// File: /workspace/github_c_makefile_star2_O1/excess-c64[P]lib1541img/src/lib/1541img/cbmdosfs.c
// Function: vfsChanged
static void vfsChanged(void *receiver, int id, const void *sender,
	const void *args)
{
    (void)id;
    (void)sender;

    CbmdosFs *self = receiver;
    if (self->status & CFS_BROKEN) return;
    const CbmdosVfsEventArgs *ea = args;
    switch (ea->what)
    {
	DirEntry tmpEntry;

	case CVE_DOSVERCHANGED:
	case CVE_NAMECHANGED:
	case CVE_IDCHANGED:
	    updateBam(self);
	    break;

	case CVE_FILEADDED:
	    if (ea->filepos > self->dir.size)
	    {
		logmsg(L_ERROR, "CbmdosFs: inconsistent state, file added at "
			"invalid position.");
		self->status |= CFS_BROKEN;
		break;
	    }
	    if (self->dir.size == self->dir.capa)
	    {
		self->dir.capa += DIRCHUNK;
		self->dir.entries = xrealloc(self->dir.entries,
			self->dir.capa * sizeof *self->dir.entries);
	    }
	    if (ea->filepos < self->dir.size)
	    {
		memmove(self->dir.entries + ea->filepos + 1,
			self->dir.entries + ea->filepos,
			(self->dir.size - ea->filepos)
			* sizeof *self->dir.entries);
	    }
	    ++self->dir.size;
            memset(self->dir.entries + ea->filepos, 0,
                    sizeof *self->dir.entries);
	    if (updateDir(self) < 0)
	    {
		self->status |= CFS_DIRFULL;
		updateBam(self);
		break;
	    }
	    if (updateFile(self, ea->filepos) < 0)
	    {
		self->status |= CFS_DISKFULL;
	    }
	    updateDir(self);
	    updateBam(self);
	    break;

	case CVE_FILEDELETED:
	    if (ea->filepos >= self->dir.size)
	    {
		logmsg(L_ERROR, "CbmdosFs: inconsistent state, non-existent "
			"file removed.");
		self->status |= CFS_BROKEN;
		break;
	    }
	    scratchFile(self, ea->filepos);
	    --self->dir.size;
	    if (ea->filepos < self->dir.size)
	    {
		memmove(self->dir.entries + ea->filepos,
			self->dir.entries + ea->filepos + 1,
			(self->dir.size - ea->filepos)
			* sizeof *self->dir.entries);
	    }
	    if (self->status & CFS_DISKFULL)
	    {
		self->status &= ~CFS_DISKFULL;
		for (unsigned pos = 0; pos < self->dir.size; ++pos)
		{
		    if (updateFile(self, pos) < 0)
		    {
			self->status |= CFS_DISKFULL;
		    }
		}
	    }
	    updateDir(self);
	    updateBam(self);
	    break;

	case CVE_FILEMOVED:
	    if (ea->filepos >= self->dir.size
		    || ea->targetpos >= self->dir.size)
	    {
		logmsg(L_ERROR, "CbmdosFs: inconsistent state, file moved to "
			"or from invalid position.");
		self->status |= CFS_BROKEN;
		break;
	    }
	    memcpy(&tmpEntry, self->dir.entries + ea->filepos,
		    sizeof tmpEntry);
	    if (ea->targetpos > ea->filepos)
	    {
		memmove(self->dir.entries + ea->filepos,
			self->dir.entries + ea->filepos + 1,
			(ea->targetpos - ea->filepos)
			* sizeof *self->dir.entries);
	    }
	    else
	    {
		memmove(self->dir.entries + ea->targetpos + 1,
			self->dir.entries + ea->targetpos,
			(ea->filepos - ea->targetpos)
			* sizeof *self->dir.entries);
	    }
	    memcpy(self->dir.entries + ea->targetpos, &tmpEntry,
		    sizeof *self->dir.entries);
	    updateDir(self);
	    updateBam(self);
	    break;

	case CVE_FILECHANGED:
	    if (ea->fileEventArgs->what == CFE_DATACHANGED
                    || ea->fileEventArgs->what == CFE_TYPECHANGED
                    || ea->fileEventArgs->what == CFE_RECORDLENGTHCHANGED
		    || ea->fileEventArgs->what == CFE_FORCEDBLOCKSCHANGED
		    || ea->fileEventArgs->what == CFE_OPTOVERRIDESCHANGED)
	    {
		if (updateFile(self, ea->filepos) < 0)
		{
		    self->status |= CFS_DISKFULL;
		}
		if (self->status & CFS_DISKFULL)
		{
		    self->status &= ~CFS_DISKFULL;
		    for (unsigned pos = 0; pos < self->dir.size; ++pos)
		    {
			if (updateFile(self, pos) < 0)
			{
			    self->status |= CFS_DISKFULL;
			}
		    }
		}
	    }
	    updateDir(self);
	    updateBam(self);
	    break;
    }
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x10, %rsp
testb $0x8, 0x20(%rdi)
jne 0x9626
movq %rcx, %r14
movl (%rcx), %eax
cmpq $0x6, %rax
ja 0x9626
movq %rdi, %rbx
leaq 0x4c94(%rip), %rcx      # 0xe0a8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x18(%rbx), %ecx
cmpl %ecx, 0x10(%r14)
jbe 0x9582
leaq 0x4fdf(%rip), %rsi      # 0xe410
jmp 0x9618
movl 0x10(%r14), %eax
movl 0x18(%rbx), %edx
cmpl %edx, %eax
jae 0x9576
movl 0x14(%r14), %ecx
cmpl %edx, %ecx
jae 0x9576
movq 0x10(%rbx), %rdx
leaq (%rax,%rax,2), %rsi
movzwl 0x4(%rdx,%rsi,2), %edi
movw %di, 0xc(%rsp)
movl (%rdx,%rsi,2), %edi
movl %edi, 0x8(%rsp)
cmpl %eax, %ecx
jbe 0x9635
leaq (%rdx,%rsi,2), %rdi
leaq 0x6(%rdi), %rsi
subl %eax, %ecx
addq %rcx, %rcx
leaq (%rcx,%rcx,2), %rdx
jmp 0x964e
movq 0x8(%r14), %rax
movl (%rax), %eax
cmpl $0x7, %eax
ja 0x9670
movl $0xe5, %ecx
btl %eax, %ecx
jae 0x9670
movl 0x10(%r14), %esi
movq %rbx, %rdi
callq 0x9a70
testl %eax, %eax
jns 0x94b9
orb $0x2, 0x20(%rbx)
movl 0x20(%rbx), %eax
testb $0x2, %al
je 0x9670
andl $-0x3, %eax
movl %eax, 0x20(%rbx)
cmpl $0x0, 0x18(%rbx)
je 0x9670
xorl %ebp, %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x9a70
testl %eax, %eax
jns 0x94e8
orb $0x2, 0x20(%rbx)
incl %ebp
cmpl 0x18(%rbx), %ebp
jb 0x94d6
jmp 0x9670
movl 0x10(%r14), %esi
cmpl 0x18(%rbx), %esi
jae 0x9611
movq %rbx, %rdi
callq 0xa3fd
movl 0x18(%rbx), %eax
decl %eax
movl %eax, 0x18(%rbx)
movl 0x10(%r14), %ecx
cmpl %ecx, %eax
jbe 0x953b
movq 0x10(%rbx), %rdx
leaq (%rcx,%rcx,2), %rsi
leaq (%rdx,%rsi,2), %rdi
leaq (%rdx,%rsi,2), %rsi
addq $0x6, %rsi
subl %ecx, %eax
addq %rax, %rax
leaq (%rax,%rax,2), %rdx
callq 0x4620
movl 0x20(%rbx), %eax
testb $0x2, %al
je 0x9670
andl $-0x3, %eax
movl %eax, 0x20(%rbx)
cmpl $0x0, 0x18(%rbx)
je 0x9670
xorl %ebp, %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x9a70
testl %eax, %eax
jns 0x956a
orb $0x2, 0x20(%rbx)
incl %ebp
cmpl 0x18(%rbx), %ebp
jb 0x9558
jmp 0x9670
leaq 0x4f0a(%rip), %rsi      # 0xe487
jmp 0x9618
movl 0x1c(%rbx), %eax
cmpl %eax, %ecx
jne 0x95a5
addl $0x90, %eax
movl %eax, 0x1c(%rbx)
movq 0x10(%rbx), %rdi
addq %rax, %rax
leaq (%rax,%rax,2), %rsi
callq 0x487c
movq %rax, 0x10(%rbx)
movl 0x10(%r14), %ecx
movl 0x18(%rbx), %eax
cmpl %ecx, %eax
jbe 0x95d2
movq 0x10(%rbx), %rdx
leaq (%rcx,%rcx,2), %rdi
leaq (%rdx,%rdi,2), %rsi
leaq (%rdx,%rdi,2), %rdi
addq $0x6, %rdi
subl %ecx, %eax
addq %rax, %rax
leaq (%rax,%rax,2), %rdx
callq 0x4620
incl 0x18(%rbx)
movq 0x10(%rbx), %rax
movl 0x10(%r14), %ecx
leaq (%rcx,%rcx,2), %rcx
movw $0x0, 0x4(%rax,%rcx,2)
movl $0x0, (%rax,%rcx,2)
movq %rbx, %rdi
callq 0x8f87
testl %eax, %eax
js 0x962f
movl 0x10(%r14), %esi
movq %rbx, %rdi
callq 0x9a70
testl %eax, %eax
jns 0x9670
orb $0x2, 0x20(%rbx)
jmp 0x9670
leaq 0x4e36(%rip), %rsi      # 0xe44e
movl $0x1, %edi
callq 0x491c
orb $0x8, 0x20(%rbx)
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq
orb $0x4, 0x20(%rbx)
jmp 0x9678
leaq (%rcx,%rcx,2), %rdi
leaq (%rdx,%rdi,2), %rsi
leaq (%rdx,%rdi,2), %rdi
addq $0x6, %rdi
subl %ecx, %eax
addq %rax, %rax
leaq (%rax,%rax,2), %rdx
callq 0x4620
movq 0x10(%rbx), %rax
movl 0x14(%r14), %ecx
leaq (%rcx,%rcx,2), %rcx
movzwl 0xc(%rsp), %edx
movw %dx, 0x4(%rax,%rcx,2)
movl 0x8(%rsp), %edx
movl %edx, (%rax,%rcx,2)
movq %rbx, %rdi
callq 0x8f87
movq %rbx, %rdi
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
jmp 0x9280