// File: /workspace/github_c_makefile_star2_O2/j-hoppe[P]tu58fs/rt11.c
// Function: render_directory_entry
static int render_directory_entry(rt11_filesystem_t *_this, rt11_file_t *f, int ds_nr,
		int de_nr) {
	uint16_t *ds = DIR_SEGMENT(_this, ds_nr); // ptr to dir segment in image
	uint16_t *de; // ptr to dir entry in image
	int dir_entry_word_count = 7 + (_this->dir_entry_extra_bytes / 2);
	uint16_t w;
	char buff[80];
	if (de_nr == 0) {
		// 1st entry in segment: write 5 word header
		IMAGE_PUT_WORD(ds + 0, _this->dir_total_seg_num);
		if (ds_nr == _this->dir_max_seg_nr)
			IMAGE_PUT_WORD(ds + 1, 0); // last segment
		else
			IMAGE_PUT_WORD(ds + 1, ds_nr + 1); // link to next segment
		IMAGE_PUT_WORD(ds + 2, _this->dir_max_seg_nr);
		IMAGE_PUT_WORD(ds + 3, _this->dir_entry_extra_bytes);
		if (f)
			IMAGE_PUT_WORD(ds + 4, f->block_nr); // start of first file on disk
		else
			// end marker at first entry
			IMAGE_PUT_WORD(ds + 4, _this->file_space_blocknr);
	}
	// write dir_entry
	de = ds + 5 + de_nr * dir_entry_word_count;
	//fprintf(stderr, "ds_nr=%d, de_nr=%d, ds in img=0x%lx, de in img =0x%lx\n", ds_nr, de_nr,
	//		(uint8_t*) ds - *_this->image_data_ptr, (uint8_t*) de - *_this->image_data_ptr);
	if (f == NULL) {
		// write start of free chain: space after last file
		IMAGE_PUT_WORD(de + 0, RT11_FILE_EMPTY);
		// after INIT free space has the name " EMPTY.FIL"
		IMAGE_PUT_WORD(de + 1, rad50_encode(" EM"));
		IMAGE_PUT_WORD(de + 2, rad50_encode("PTY"));
		IMAGE_PUT_WORD(de + 3, rad50_encode("FIL"));
		IMAGE_PUT_WORD(de + 4, _this->free_blocks); // block count
		IMAGE_PUT_WORD(de + 5, 0); // job/channel
		IMAGE_PUT_WORD(de + 6, 0); // INIT sets a creation date ... don't need to!
	} else {
		// regular file
		// status
		w = RT11_FILE_EPERM;
		if (f->readonly)
			w |= RT11_FILE_EREAD | RT11_FILE_EPROT;
		if (f->prefix)
			w |= RT11_FILE_EPRE;
		IMAGE_PUT_WORD(de + 0, w);

		// filename chars 0..2
		strncpy(buff, f->filnam, 3);
		buff[3] = 0;
		IMAGE_PUT_WORD(de + 1, rad50_encode(buff));

		// filename chars 3..5
		if (strlen(f->filnam) < 4)
			buff[0] = 0;
		else
			strncpy(buff, f->filnam + 3, 3);
		buff[3] = 0;
		IMAGE_PUT_WORD(de + 2, rad50_encode(buff));
		// ext
		IMAGE_PUT_WORD(de + 3, rad50_encode(f->ext));
		// total file len
		IMAGE_PUT_WORD(de + 4, f->block_count);
		// clr job/channel
		IMAGE_PUT_WORD(de + 5, 0);
		//date. do not set "age", as it is not evaluated by DEC software.
		// year already in range 1972..1999
		w = f->date.tm_year - 72;
		w |= f->date.tm_mday << 5;
		w |= (f->date.tm_mon + 1) << 10;
		IMAGE_PUT_WORD(de + 6, w);
		if (f->dir_ext) {
			// write bytes from "dir extension" stream into directory entry
			if (f->dir_ext->data_size > _this->dir_entry_extra_bytes)
				return error_set(ERROR_FILESYSTEM_OVERFLOW,
						"render_directory(): file %s dir_ext size %d > extra bytes in dir %d\n",
						f->filnam, f->dir_ext->data_size, _this->dir_entry_extra_bytes);
			memcpy(de + 7, f->dir_ext->data, f->dir_ext->data_size);
		}
	}
	// write end-of-segment marker behind dir_entry.
	IMAGE_PUT_WORD(de + dir_entry_word_count, RT11_DIR_EEOS);
	// this is overwritten by next entry; and remains if last entry in segment
	return ERROR_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movzwl 0x34(%rdi), %esi
shll $0x9, %esi
addq (%rdi), %rsi
movl %edx, %eax
shll $0xa, %eax
addl $0xfffffc00, %eax       # imm = 0xFFFFFC00
cltq
addq %rsi, %rax
movzwl 0x68(%rdi), %r13d
shrl %r13d
testl %ecx, %ecx
je 0xf803
leal 0x7(%r13), %edx
imull %ecx, %edx
movslq %edx, %rcx
leaq (%rax,%rcx,2), %rbp
addq $0xa, %rbp
testq %r14, %r14
jne 0xf862
jmp 0xf9b9
movb 0x64(%rbx), %cl
movb %cl, (%rax)
movb 0x65(%rbx), %cl
movb %cl, 0x1(%rax)
movzwl 0x66(%rbx), %ecx
leal 0x1(%rdx), %esi
movl %esi, %edi
shrl $0x8, %edi
xorl %r8d, %r8d
cmpl %edx, %ecx
cmovel %r8d, %esi
cmovel %r8d, %edi
movb %sil, 0x2(%rax)
movb %dil, 0x3(%rax)
movb 0x66(%rbx), %cl
movb %cl, 0x4(%rax)
movb 0x67(%rbx), %cl
movb %cl, 0x5(%rax)
movb 0x68(%rbx), %cl
movb %cl, 0x6(%rax)
movb 0x69(%rbx), %cl
movb %cl, 0x7(%rax)
leaq 0xa(%rax), %rbp
testq %r14, %r14
je 0xf9a7
movb 0x7a(%r14), %cl
movb %cl, 0x8(%rax)
movb 0x7b(%r14), %cl
movb %cl, 0x9(%rax)
xorl %eax, %eax
cmpl $0x0, 0xd0(%r14)
sete %al
shll $0xe, %eax
xorl %ecx, %ecx
cmpq $0x0, 0x88(%r14)
setne %cl
shll $0x4, %ecx
addl %ecx, %eax
addl $0xffffc400, %eax       # imm = 0xFFFFC400
movw %ax, (%rbp)
leaq 0x2(%r14), %r15
movq %rsp, %r12
pushq $0x3
popq %rdx
movq %r12, %rdi
movq %r15, %rsi
callq 0x30a0
movb $0x0, 0x3(%r12)
movq %r12, %rdi
callq 0xa1d5
movb %al, 0x2(%rbp)
movq %r12, %rdi
callq 0xa1d5
movb %ah, 0x3(%rbp)
movq %r15, %rdi
callq 0x3190
cmpq $0x3, %rax
ja 0xf8d2
movb $0x0, (%rsp)
jmp 0xf8e1
leaq 0x5(%r14), %rsi
movq %rsp, %rdi
pushq $0x3
popq %rdx
callq 0x30a0
movq %rsp, %r12
movb $0x0, 0x3(%r12)
movq %r12, %rdi
callq 0xa1d5
movb %al, 0x4(%rbp)
movq %r12, %rdi
callq 0xa1d5
movb %ah, 0x5(%rbp)
leaq 0x52(%r14), %r12
movq %r12, %rdi
callq 0xa1d5
movb %al, 0x6(%rbp)
movq %r12, %rdi
callq 0xa1d5
movb %ah, 0x7(%rbp)
movb 0x7c(%r14), %al
movb %al, 0x8(%rbp)
movb 0x7d(%r14), %al
movb %al, 0x9(%rbp)
andw $0x0, 0xa(%rbp)
movl $0xffb8, %ecx           # imm = 0xFFB8
addl 0xac(%r14), %ecx
movl 0xa4(%r14), %edx
movl 0xa8(%r14), %eax
shll $0x5, %edx
orl %ecx, %edx
shll $0xa, %eax
addl $0x400, %eax            # imm = 0x400
orl %edx, %eax
movb %dl, 0xc(%rbp)
movb %ah, 0xd(%rbp)
movq 0x90(%r14), %rax
testq %rax, %rax
je 0xfa2c
movl 0x10(%rax), %ecx
movzwl 0x68(%rbx), %r8d
cmpl %r8d, %ecx
jbe 0xf992
leaq 0x6257(%rip), %rsi      # 0x15bd7
pushq $-0x2
popq %rdi
movq %r15, %rdx
xorl %eax, %eax
callq 0x982c
jmp 0xfa34
leaq 0xe(%rbp), %rdi
movq 0x8(%rax), %rsi
movq %rcx, %rdx
callq 0x3340
jmp 0xfa2c
movb 0x1fd4(%rbx), %cl
movb %cl, 0x8(%rax)
movb 0x1fd5(%rbx), %cl
movb %cl, 0x9(%rax)
movw $0x200, (%rbp)          # imm = 0x200
leaq 0x6205(%rip), %r14      # 0x15bcb
movq %r14, %rdi
callq 0xa1d5
movb %al, 0x2(%rbp)
movq %r14, %rdi
callq 0xa1d5
movb %ah, 0x3(%rbp)
leaq 0x61ec(%rip), %r14      # 0x15bcf
movq %r14, %rdi
callq 0xa1d5
movb %al, 0x4(%rbp)
movq %r14, %rdi
callq 0xa1d5
movb %ah, 0x5(%rbp)
leaq 0x61d3(%rip), %r14      # 0x15bd3
movq %r14, %rdi
callq 0xa1d5
movb %al, 0x6(%rbp)
movq %r14, %rdi
callq 0xa1d5
movb %ah, 0x7(%rbp)
movb 0x1fd2(%rbx), %al
movb %al, 0x8(%rbp)
movb 0x1fd3(%rbx), %al
movb %al, 0x9(%rbp)
andl $0x0, 0xa(%rbp)
movw $0x800, 0xe(%rbp,%r13,2) # imm = 0x800
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq