// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl $0x18, %edi
callq 0x2220
movq %rax, %rdi
callq 0x136a0
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rdi
leaq 0x5458(%rip), %rsi      # 0x15c34
callq 0x2260
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x1080b
movq -0x20(%rbp), %rdi
callq 0x10d30
movq $0x0, -0x8(%rbp)
jmp 0x10d17
movl $0x30, %edi
callq 0x2220
movq %rax, %rdi
callq 0x136a0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movl $0x1, %esi
movl $0x30, %edx
callq 0x20a0
cmpq $0x30, %rax
jae 0x10878
movq 0x87b0(%rip), %rax      # 0x18ff8
movq (%rax), %rdi
leaq 0x53e5(%rip), %rsi      # 0x15c37
movb $0x0, %al
callq 0x21c0
movq -0x20(%rbp), %rdi
callq 0x10d30
movq -0x28(%rbp), %rdi
callq 0x2040
movq $0x0, -0x8(%rbp)
jmp 0x10d17
movq -0x20(%rbp), %rax
movl $0x0, 0x14(%rax)
cmpl $0x0, -0x14(%rbp)
je 0x108bc
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
andl $0xff, %eax
movq -0x28(%rbp), %rcx
movsbl 0x1(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
cmpl $0x200, %eax            # imm = 0x200
jne 0x108bc
movq -0x20(%rbp), %rax
movl $0x1, 0x14(%rax)
jmp 0x10912
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
andl $0xff, %eax
movq -0x28(%rbp), %rcx
movsbl 0x1(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
cmpl $0x201, %eax            # imm = 0x201
je 0x10910
movq 0x870f(%rip), %rax      # 0x18ff8
movq (%rax), %rdi
leaq 0x5363(%rip), %rsi      # 0x15c56
movb $0x0, %al
callq 0x21c0
movq -0x20(%rbp), %rdi
callq 0x10d30
movq $0x0, -0x8(%rbp)
jmp 0x10d17
jmp 0x10912
movq -0x28(%rbp), %rax
movsbl 0x1a(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movsbl 0x1e(%rax), %eax
andl $0xff, %eax
movq -0x28(%rbp), %rcx
movsbl 0x1f(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movsbl 0x1c(%rax), %eax
andl $0xff, %eax
movq -0x28(%rbp), %rcx
movsbl 0x1d(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
subl $0x1, %eax
movl %eax, -0x34(%rbp)
cmpl $0x8, -0x2c(%rbp)
jae 0x1099d
movq -0x20(%rbp), %rdi
callq 0x10d30
movq 0x867c(%rip), %rax      # 0x18ff8
movq (%rax), %rdi
movl -0x2c(%rbp), %edx
leaq 0x52f2(%rip), %rsi      # 0x15c7b
movb $0x0, %al
callq 0x21c0
movq $0x0, -0x8(%rbp)
jmp 0x10d17
movq -0x28(%rbp), %rdi
callq 0x2040
movl -0x30(%rbp), %eax
imull -0x2c(%rbp), %eax
movl %eax, %eax
movl %eax, %edi
callq 0x2220
movq %rax, %rdi
callq 0x136a0
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rdi
movl -0x34(%rbp), %eax
shll $0x9, %eax
movl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2240
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
movl -0x30(%rbp), %eax
movl %eax, %edx
movq -0x20(%rbp), %rax
movq (%rax), %rcx
callq 0x20a0
movl -0x30(%rbp), %ecx
cmpq %rcx, %rax
jae 0x10a1b
movq -0x20(%rbp), %rdi
callq 0x10d30
movq -0x28(%rbp), %rdi
callq 0x2040
movq $0x0, -0x8(%rbp)
jmp 0x10d17
movl $0x0, -0x38(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0x10b74
movq -0x28(%rbp), %rax
movl -0x38(%rbp), %ecx
imull -0x2c(%rbp), %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movsbl (%rax), %eax
andl $0xff, %eax
movq -0x48(%rbp), %rcx
movsbl 0x1(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x10b62
movq -0x48(%rbp), %rax
movsbl 0x2(%rax), %eax
andl $0xff, %eax
movq -0x48(%rbp), %rcx
movsbl 0x3(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x10b62
jmp 0x10a9f
movl -0x3c(%rbp), %ecx
addl $-0x1, %ecx
movl %ecx, -0x3c(%rbp)
xorl %eax, %eax
cmpl -0x38(%rbp), %ecx
movb %al, -0x69(%rbp)
jle 0x10b23
movq -0x28(%rbp), %rax
movl -0x3c(%rbp), %ecx
imull -0x2c(%rbp), %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movsbl (%rax), %ecx
andl $0xff, %ecx
movq -0x50(%rbp), %rax
movsbl 0x1(%rax), %eax
andl $0xff, %eax
shll $0x8, %eax
addl %eax, %ecx
xorl %eax, %eax
cmpl $0xffff, %ecx           # imm = 0xFFFF
movb %al, -0x6a(%rbp)
jne 0x10b1d
movq -0x50(%rbp), %rax
movsbl 0x2(%rax), %eax
andl $0xff, %eax
movq -0x50(%rbp), %rcx
movsbl 0x3(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
sete %al
movb %al, -0x6a(%rbp)
movb -0x6a(%rbp), %al
movb %al, -0x69(%rbp)
movb -0x69(%rbp), %al
testb $0x1, %al
jne 0x10b2c
jmp 0x10b31
jmp 0x10a9f
movl -0x3c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jg 0x10b3b
jmp 0x10b74
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
movl -0x2c(%rbp), %eax
movl %eax, %edx
callq 0x2200
movq -0x50(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %edx
movl $0xff, %esi
callq 0x2120
jmp 0x10b64
jmp 0x10b64
jmp 0x10b66
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x10a28
movl -0x38(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rax
movslq 0x10(%rax), %rax
imulq $0x18, %rax, %rdi
callq 0x2220
movq %rax, %rdi
callq 0x136a0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x20(%rbp), %rax
movslq 0x10(%rax), %rax
imulq $0x18, %rax, %rdx
xorl %esi, %esi
callq 0x2120
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x10d06
movq -0x28(%rbp), %rax
movl -0x3c(%rbp), %ecx
imull -0x2c(%rbp), %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movsbl (%rax), %edi
andl $0xff, %edi
movq -0x68(%rbp), %rax
movsbl 0x1(%rax), %eax
andl $0xff, %eax
shll $0x8, %eax
addl %eax, %edi
leaq -0x60(%rbp), %rsi
callq 0x13ba0
movq -0x68(%rbp), %rax
movsbl 0x2(%rax), %edi
andl $0xff, %edi
movq -0x68(%rbp), %rax
movsbl 0x3(%rax), %eax
andl $0xff, %eax
shll $0x8, %eax
addl %eax, %edi
leaq -0x60(%rbp), %rsi
addq $0x3, %rsi
callq 0x13ba0
movb $0x0, -0x5a(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x10de0
leaq -0x60(%rbp), %rdi
callq 0x22d0
movq %rax, %rdi
callq 0x136a0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x3c(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movq -0x68(%rbp), %rax
movsbl 0x4(%rax), %eax
andl $0xff, %eax
movq -0x68(%rbp), %rcx
movsbl 0x5(%rcx), %ecx
andl $0xff, %ecx
shll $0x8, %ecx
addl %ecx, %eax
andl $0x7fff, %eax           # imm = 0x7FFF
subl $0x1, %eax
shll $0x9, %eax
movq -0x68(%rbp), %rcx
movsbl 0x6(%rcx), %ecx
andl $0xff, %ecx
movq -0x68(%rbp), %rdx
movsbl 0x7(%rdx), %edx
andl $0xff, %edx
shll $0x8, %edx
addl %edx, %ecx
andl $0x1ff, %ecx            # imm = 0x1FF
addl %ecx, %eax
movslq %eax, %rcx
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x3c(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl $0xffffffff, 0x10(%rax) # imm = 0xFFFFFFFF
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x10bc4
movq -0x28(%rbp), %rdi
callq 0x2040
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)