// File: /workspace/github_c_makefile_star2_O3/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 0x9b99
testl %eax, %eax
js 0xa41e
movq %r15, %rdi
callq 0x5430
cmpl $0x2, %eax
je 0xa338
cmpl $0x1, %eax
je 0xa31f
testl %eax, %eax
jne 0xa34f
testb $0xc, %r14b
je 0xa34f
leaq 0x4db2(%rip), %rsi      # 0xf0cc
jmp 0xa414
testb $0x8, %r14b
jne 0xa40d
testb $0x4, %r14b
jne 0xa34f
leaq 0x4e5f(%rip), %rsi      # 0xf195
jmp 0xa345
testb $0x8, %r14b
jne 0xa34f
leaq 0x4ee2(%rip), %rsi      # 0xf227
movl $0x2, %edi
callq 0x591c
movq %r14, %r13
shrq $0x20, %r13
movl $0x3a0, %edi            # imm = 0x3A0
callq 0x585c
movq %rax, %rbx
leaq 0x8(%rax), %rdi
movl $0x398, %edx            # imm = 0x398
xorl %esi, %esi
callq 0x5320
movq %r15, (%rbx)
leaq 0x10(%rbx), %r12
movl $0x90, 0x1c(%rbx)
movl $0x360, %edi            # imm = 0x360
callq 0x585c
movq %rax, 0x10(%rbx)
callq 0x5520
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 0x80f0
cmpl $-0x2, %eax
je 0xa3d7
cmpl $-0x1, %eax
jne 0xa3db
movq $0x0, (%rbx)
movq %rbx, %rdi
callq 0x5460
jmp 0xa41e
orb $0x1, 0x20(%rbx)
movl (%r15), %eax
btl $0x8, %eax
jae 0xa3f0
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, 0x24(%rbx)
orb $0x8, 0x20(%rbx)
movq 0x8(%rbx), %rdi
callq 0x51e0
leaq -0x3d5(%rip), %rdx      # 0xa02b
movq %rax, %rdi
movq %rbx, %rsi
callq 0x5550
jmp 0xa420
leaq 0x4d20(%rip), %rsi      # 0xf134
movl $0x1, %edi
callq 0x591c
xorl %ebx, %ebx
movq %rbx, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq