// File: /workspace/github_c_makefile_star2_O1/excess-c64[P]lib1541img/src/lib/1541img/cbmdosfs.c
// Function: CbmdosFs_fromImage
SOEXPORT CbmdosFs *CbmdosFs_fromImage(D64 *d64, CbmdosFsOptions options)
{
    if (validateOptions(options) < 0) return 0;
    switch (D64_type(d64))
    {
	case D64_STANDARD:
	    if (options.flags & (CFF_40TRACK | CFF_42TRACK))
	    {
		logmsg(L_ERROR, "CbmdosFs_fromImage: trying to read a 40- or "
			"42-tracks filesystem from an image that only has "
			"35 tracks.");
		return 0;
	    }
	    break;
	case D64_40TRACK:
	    if (options.flags & CFF_42TRACK)
	    {
		logmsg(L_ERROR, "CbmdosFs_fromImage: trying to read a "
			"42-tracks filesystem from an image that only has "
			"40 tracks.");
		return 0;
	    }
	    if (!(options.flags & CFF_40TRACK))
	    {
		logmsg(L_WARNING, "CbmdosFs_fromImage: trying to read a "
			"35-tracks filesystem from an image that has 40 "
			"tracks, this will fail if the filesystem spans "
			"all 40 tracks.");
	    }
	    break;
	case D64_42TRACK:
	    if (!(options.flags & CFF_42TRACK))
	    {
		logmsg(L_WARNING, "CbmdosFs_fromImage: trying to read a 35- "
			"or 40-tracks filesystem from an image that has 42 "
			"tracks, this will fail if the filesystem spans "
			"all 42 tracks.");
	    }
	    break;
    }

    CbmdosFs *self = xmalloc(sizeof *self);
    memset(self, 0, sizeof *self);
    self->d64 = d64;
    self->dir.capa = DIRCHUNK;
    self->dir.entries = xmalloc(DIRCHUNK * sizeof *self->dir.entries);
    self->vfs = CbmdosVfs_create();
    self->options = options;
    int rc = readCbmdosVfsInternal(self->vfs, self->d64,
	    &self->options, self->bam, &self->dir);
    switch (rc)
    {
	case -1:
	    self->d64 = 0;
	    CbmdosFs_destroy(self);
	    return 0;
	case -2:
	    self->status |= CFS_INVALIDBAM;
	    break;
    }
    if (self->options.flags & CFF_RECOVER)
    {
	self->options.flags &= ~CFF_RECOVER;
	self->status |= CFS_BROKEN;
    }
    Event_register(CbmdosVfs_changedEvent(self->vfs), self, vfsChanged);
    return self;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %r14
movq %rdi, %r15
movq %rsi, %rdi
callq 0x8f15
testl %eax, %eax
js 0x97cd
movq %r15, %rdi
callq 0x4430
cmpl $0x2, %eax
je 0x96e8
cmpl $0x1, %eax
je 0x96cf
testl %eax, %eax
jne 0x96ff
testb $0xc, %r14b
je 0x96ff
leaq 0x4a02(%rip), %rsi      # 0xe0cc
jmp 0x97c3
testb $0x8, %r14b
jne 0x97bc
testb $0x4, %r14b
jne 0x96ff
leaq 0x4aaf(%rip), %rsi      # 0xe195
jmp 0x96f5
testb $0x8, %r14b
jne 0x96ff
leaq 0x4b32(%rip), %rsi      # 0xe227
movl $0x2, %edi
callq 0x491c
movq %r14, %r13
shrq $0x20, %r13
movl $0x3a0, %edi            # imm = 0x3A0
callq 0x485c
movq %rax, %rbx
movl $0x3a0, %edx            # imm = 0x3A0
movq %rax, %rdi
xorl %esi, %esi
callq 0x4320
movq %r15, (%rbx)
leaq 0x10(%rbx), %r12
movl $0x90, 0x1c(%rbx)
movl $0x360, %edi            # imm = 0x360
callq 0x485c
movq %rax, 0x10(%rbx)
callq 0x4520
movq %rax, 0x8(%rbx)
leaq 0x24(%rbx), %r15
movl %r14d, 0x24(%rbx)
movl %r13d, 0x28(%rbx)
movq (%rbx), %rsi
movq %rbx, %rcx
addq $0x2c, %rcx
movq %rax, %rdi
movq %r15, %rdx
movq %r12, %r8
callq 0x7244
cmpl $-0x2, %eax
je 0x9786
cmpl $-0x1, %eax
jne 0x978a
movq $0x0, (%rbx)
movq %rbx, %rdi
callq 0x4460
jmp 0x97cd
orb $0x1, 0x20(%rbx)
movl (%r15), %eax
btl $0x8, %eax
jae 0x979f
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, 0x24(%rbx)
orb $0x8, 0x20(%rbx)
movq 0x8(%rbx), %rdi
callq 0x41e0
leaq -0x3c6(%rip), %rdx      # 0x93e9
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4550
jmp 0x97cf
leaq 0x4971(%rip), %rsi      # 0xe134
movl $0x1, %edi
callq 0x491c
xorl %ebx, %ebx
movq %rbx, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq