// File: /workspace/github_c_makefile_star2_O2/j-hoppe[P]tu58fs/rt11.c
// Function: rt11_filesystem_calc_block_use
static int rt11_filesystem_calc_block_use(rt11_filesystem_t *_this, int test_data_size) {
	int i;
	int dir_max_seg_nr;
	int used_file_blocks;
	int available_blocks;

	if (_this->dir_entry_extra_bytes > 16)
		fatal("Extra bytes in directory %d is > 16 ... how much is allowed?", _this->dir_entry_extra_bytes);

	// 1) calc segments & blocks needed for existing files
	used_file_blocks = 0;
	for (i = 0; i < _this->file_count; i++) {
		// round file sizes up to blocks
		// prefix size and data size already sum'd up to file->block_count
		used_file_blocks += _this->file[i]->block_count;
	}
	if (test_data_size)
		used_file_blocks += NEEDED_BLOCKS(RT11_BLOCKSIZE, test_data_size);

	// total blocks available for dir and data
	// On disk supporting STd144 bad secotr info,
	// "available blocks" should not be calculated from total disk size,
	// but from usable blockcount of "rt11_radi".
	// Difficulties in case of enlarged images!
	available_blocks = _this->blockcount - _this->first_dir_blocknr; // boot, home, 2..5 used
	if (test_data_size)
		dir_max_seg_nr = rt11_dir_needed_segments(_this, _this->file_count + 1);
	else
		dir_max_seg_nr = rt11_dir_needed_segments(_this, _this->file_count);
	if (available_blocks < used_file_blocks + 2 * dir_max_seg_nr) {
		// files do not fit on volume
		if (!test_data_size)
			_this->free_blocks = 0; // can't be negative
		return error_set(ERROR_FILESYSTEM_OVERFLOW, "rt11_filesystem_calc_block_use");
	}
	if (test_data_size)
		return ERROR_OK;

	/* end of test mode */
	// now modify file system
	_this->dir_max_seg_nr = dir_max_seg_nr;
	_this->used_file_blocks = used_file_blocks;

	_this->free_blocks = available_blocks - _this->used_file_blocks - 2 * _this->dir_max_seg_nr;
	// now used_blocks,free_blocks, dir_total_seg_num valid.

	/* Plan use of remaining free_space
	 * how many files would be allocated in the remaining free space?
	 * derive from average file size, but allow 1.5 * as much
	 * Most critical test situations:
	 * All dir segments full, and only 2 block in file area left.
	 * assigned these blocks to 1 more file would need a new dir segment,
	 * which would need these 2 blocks too.
	 * If 3 blocks are left: 2 can be used for additional dir segmetn,
	 * and 1 for new file.
	 */
	if (_this->file_count == 0) {
		// if disk empty: start with only 1 segment
		_this->dir_max_seg_nr = 1;
		_this->dir_total_seg_num = 1;
	} else {
		// planning params have prefix "_"
		int avg_file_blocks; // average filesize in blocks
		int _new_file_count; // planned count of additional files
		int _used_file_blocks; // planned block requirement for all files (existing + planned)
		int _dir_total_seg_num; // planned dir segment requirement for all files (existing + planned)
		avg_file_blocks = _this->used_file_blocks / _this->file_count;
		if (avg_file_blocks < 1)
			avg_file_blocks = 1;
		// 1st estimate for possible new files.
		// Assume they have average size.
		// too big, since additional dir segments reduce free space
		_new_file_count = _this->free_blocks / avg_file_blocks + 1;
		// reduce amount of planned files, until files+dir fit on disk
		do {
			_new_file_count--;
			_used_file_blocks = _this->used_file_blocks + _new_file_count * avg_file_blocks;
			// plan for 50% more file count
			_dir_total_seg_num = rt11_dir_needed_segments(_this,
					_this->file_count + (_new_file_count * 3) / 2);
		} while (_new_file_count
				&& available_blocks < _used_file_blocks + 2 * _dir_total_seg_num);
		// solution found: save
		if (_dir_total_seg_num > 31)
			_dir_total_seg_num = 31;
		_this->dir_total_seg_num = _dir_total_seg_num;
	}
	// calculate free blocks again
	assert(available_blocks >= _this->used_file_blocks + 2 * _this->dir_total_seg_num);
	_this->free_blocks = available_blocks - _this->used_file_blocks
			- 2 * _this->dir_total_seg_num;

	return ERROR_OK;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movl %esi, %ebp
movq %rdi, %rbx
movzwl 0x68(%rdi), %esi
cmpl $0x11, %esi
jb 0xec38
leaq 0x7035(%rip), %rdi      # 0x15c66
xorl %eax, %eax
callq 0x9b87
movl 0x8c(%rbx), %edi
xorl %eax, %eax
testl %edi, %edi
movl $0x0, %ecx
cmovgl %edi, %ecx
xorl %r9d, %r9d
cmpq %rax, %rcx
je 0xec66
movq 0x90(%rbx,%rax,8), %rdx
movzwl 0x7c(%rdx), %edx
addl %edx, %r9d
incq %rax
jmp 0xec4d
testl %ebp, %ebp
je 0xecb3
addl $0x1ff, %ebp            # imm = 0x1FF
movl $0x200, %ecx            # imm = 0x200
movl %ebp, %eax
cltd
idivl %ecx
addl %eax, %r9d
movl 0x6c(%rbx), %esi
movzwl 0x34(%rbx), %eax
subl %eax, %esi
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
leal (%rdi,%rax), %ecx
addl $-0x2, %ecx
movl %eax, %edi
addl $-0x3, %edi
movl %ecx, %eax
cltd
idivl %edi
leal (%r9,%rax,2), %eax
cmpl %eax, %esi
jl 0xecf4
jmp 0xed9f
movl 0x6c(%rbx), %r8d
movzwl 0x34(%rbx), %eax
subl %eax, %r8d
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
leal (%rax,%rdi), %ecx
addl $-0x3, %ecx
movl %eax, %r10d
addl $-0x3, %r10d
movl %ecx, %eax
cltd
idivl %r10d
leal (%r9,%rax,2), %ecx
movl %r8d, %esi
subl %ecx, %esi
jge 0xed0b
andw $0x0, 0x1fd2(%rbx)
leaq 0x6fa8(%rip), %rsi      # 0x15ca3
pushq $-0x2
popq %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x982c
movw %ax, 0x66(%rbx)
movw %r9w, 0x1fd0(%rbx)
movw %si, 0x1fd2(%rbx)
testl %edi, %edi
je 0xed82
movzwl %r9w, %ecx
movl %ecx, %eax
xorl %edx, %edx
idivl %edi
cmpl $0x2, %eax
pushq $0x1
popq %r9
cmovgel %eax, %r9d
movl %esi, %eax
xorl %edx, %edx
divw %r9w
movzwl %ax, %esi
incl %esi
pushq $0x2
popq %r11
addl %r10d, %edi
decl %esi
leal (%rsi,%rsi,2), %eax
cltd
idivl %r11d
addl %edi, %eax
cltd
idivl %r10d
testl %esi, %esi
je 0xed6e
movl %esi, %edx
imull %r9d, %edx
addl %ecx, %edx
leal (%rdx,%rax,2), %edx
cmpl %edx, %r8d
jl 0xed4b
cmpl $0x1f, %eax
pushq $0x1f
popq %rdx
cmovll %eax, %edx
movw %dx, 0x64(%rbx)
movzwl %dx, %eax
addl %eax, %eax
jmp 0xed90
movl $0x10001, 0x64(%rbx)    # imm = 0x10001
movzwl %r9w, %ecx
pushq $0x2
popq %rax
addl %eax, %ecx
subl %ecx, %r8d
jl 0xeda8
movw %r8w, 0x1fd2(%rbx)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
leaq 0x6f13(%rip), %rdi      # 0x15cc2
leaq 0x697e(%rip), %rsi      # 0x15734
leaq 0x6f50(%rip), %rcx      # 0x15d0d
movl $0x1c9, %edx            # imm = 0x1C9
callq 0x3200