// File: /workspace/github_c_makefile_star2_O0/j-hoppe[P]tu58fs/rt11.c
// Function: parse_directory
static int parse_directory(rt11_filesystem_t *_this) {
	uint16_t *ds; // ptr to start of directory segment
	uint32_t ds_nr = 0; // runs from 1
	uint32_t ds_next_nr = 0;
	uint32_t w;
	uint16_t de_data_blocknr; // start blocknumber for file data

	uint16_t *de; // directory entry in current directory segment
	uint16_t de_nr; // directory entry_nr, runs from 0
	uint16_t de_len; // total size of directory entry in words
	// by this segment begins.

	/*** iterate directory segments ***/
	_this->used_file_blocks = 0;
	_this->free_blocks = 0;

	ds_nr = 1;
	do {
		ds = DIR_SEGMENT(_this, ds_nr);
		// read 5 word directory segment header
		w = IMAGE_GET_WORD(ds + 0);
		if (ds_nr == 1)
			_this->dir_total_seg_num = w;
		else if (w != _this->dir_total_seg_num)
			return error_set(ERROR_FILESYSTEM_FORMAT,
					"parse_directory(): ds_header_total_seg_num in entry %d different from entry 1\n",
					ds_nr);
		if (ds_nr == 1)
			_this->dir_max_seg_nr = IMAGE_GET_WORD(ds + 2);
		ds_next_nr = IMAGE_GET_WORD(ds + 1); // nr of next segment
		if (ds_next_nr > _this->dir_max_seg_nr)
			return error_set(ERROR_FILESYSTEM_FORMAT,
					"parse_directory(): next segment nr %d > maximum %d\n", ds_next_nr,
					_this->dir_max_seg_nr);
		de_data_blocknr = IMAGE_GET_WORD(ds + 4);
		if (ds_nr == 1) {
			_this->dir_entry_extra_bytes = IMAGE_GET_WORD(ds + 3);
			_this->file_space_blocknr = de_data_blocknr; // 1st dir entry
		}
		//

		/*** iterate directory entries in segment ***/
		de_len = 7 + _this->dir_entry_extra_bytes / 2;
		de_nr = 0;
		de = ds + 5; // 1st entry 5 words after segment start
		while (!(IMAGE_GET_WORD(de) & RT11_DIR_EEOS)) { // end of segment?
			uint16_t de_status = IMAGE_GET_WORD(de);
			if (de_status & RT11_FILE_EMPTY) { // skip empty entries
				w = IMAGE_GET_WORD(de + 4);
				_this->free_blocks += w;
			} else if (de_status & RT11_FILE_EPERM) { // only permanent files
				// new file! read dir entry
				rt11_file_t *f = rt11_file_create();
				f->status = de_status;
				// filnam: 6 chars
				w = IMAGE_GET_WORD(de + 1);
				strcat(f->filnam, rad50_decode(w));
				w = IMAGE_GET_WORD(de + 2);
				strcat(f->filnam, rad50_decode(w));
				// extension: 3 chars
				w = IMAGE_GET_WORD(de + 3);
				strcpy(f->ext, rad50_decode(w));
				// blocks in data stream
				f->block_nr = de_data_blocknr; // startblock on disk
				f->block_count = IMAGE_GET_WORD(de + 4);
				_this->used_file_blocks += f->block_count;
				// fprintf(stderr, "parse %s.%s, %d blocks @ %d\n", f->filnam, f->ext,	f->block_count, f->block_nr);
				// ignore job/channel
				// creation date
				w = IMAGE_GET_WORD(de + 6);
				// 5 bit year, 2 bit "age". Year since 1972
				// date "0" is possible, then no display in DIR output
				if (w) {
					f->date.tm_year = 72 + (w & 0x1f) + 32 * ((w >> 14) & 3);
					f->date.tm_mday = (w >> 5) & 0x1f;
					f->date.tm_mon = ((w >> 10) & 0x0f) - 1;
				} else { // oldest: 1-jan-72
					f->date.tm_year = 72;
					f->date.tm_mday = 1;
					f->date.tm_mon = 0;
				}
				// "readonly", if either EREAD or EPROT)
				f->readonly = 0;
				if (f->status & (RT11_FILE_EREAD))
					f->readonly = 1;
				if (f->status & (RT11_FILE_EPROT))
					f->readonly = 1;

				// Extract extra bytes in directory entry as stream ...
				if (_this->dir_entry_extra_bytes) {
					assert(f->dir_ext == NULL);
					f->dir_ext = stream_create();
					stream_parse(_this, f->dir_ext,
					/*start block*/IMAGE_PTR2BLOCKNR(_this, de + 7),
					/* byte_offset*/IMAGE_PTR2BLOCKOFFSET(_this, de + 7),
							_this->dir_entry_extra_bytes);
					strcpy(f->dir_ext->name, RT11_STREAMNAME_DIREXT);
					// generate only a stream if any bytes set <> 00
					if (is_memset(f->dir_ext->data, 0, f->dir_ext->data_size)) {
						stream_destroy(f->dir_ext);
						f->dir_ext = NULL;
					}
				}

				if (_this->file_count >= RT11_MAX_FILES_PER_IMAGE)
					return error_set(ERROR_FILESYSTEM_FORMAT,
							"parse_directory(): more than %d files!\n",
							RT11_MAX_FILES_PER_IMAGE);
				_this->file[_this->file_count++] = f; //save
			}

			// advance file start block in data area, also for empty entries
			de_data_blocknr += IMAGE_GET_WORD(de + 4);

			// next dir entry
			de_nr++;
			de += de_len;
			if (de - ds > 2 * RT11_BLOCKSIZE) // 1 segment = 2 blocks
				return error_set(ERROR_FILESYSTEM_FORMAT,
						"parse_directory(): list of entries exceeds %d bytes\n",
						2 * RT11_BLOCKSIZE);
		}

		// next segment
		ds_nr = ds_next_nr;
	} while (ds_nr > 0);
	return ERROR_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl $0x0, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movw $0x0, 0x1fd0(%rax)
movq -0x10(%rbp), %rax
movw $0x0, 0x1fd2(%rax)
movl $0x1, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movzwl 0x34(%rcx), %ecx
shll $0x9, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movl -0x1c(%rbp), %ecx
subl $0x1, %ecx
shll %ecx
shll $0x9, %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
movzwl %ax, %eax
movq -0x18(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
cmpl $0x1, -0x1c(%rbp)
jne 0x13f0a
movl -0x24(%rbp), %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x64(%rax)
jmp 0x13f39
movl -0x24(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x64(%rcx), %ecx
cmpl %ecx, %eax
je 0x13f37
movl -0x1c(%rbp), %edx
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq 0x9985(%rip), %rsi      # 0x1d8ad
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x144f5
jmp 0x13f39
cmpl $0x1, -0x1c(%rbp)
jne 0x13f65
movq -0x18(%rbp), %rax
movzbl 0x4(%rax), %eax
movzwl %ax, %eax
movq -0x18(%rbp), %rcx
movzbl 0x5(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x66(%rax)
movq -0x18(%rbp), %rax
movzbl 0x2(%rax), %eax
movzwl %ax, %eax
movq -0x18(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x66(%rcx), %ecx
cmpl %ecx, %eax
jbe 0x13fb8
movl -0x20(%rbp), %edx
movq -0x10(%rbp), %rax
movzwl 0x66(%rax), %ecx
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq 0x9953(%rip), %rsi      # 0x1d8fc
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x144f5
movq -0x18(%rbp), %rax
movzbl 0x8(%rax), %eax
movzwl %ax, %eax
movq -0x18(%rbp), %rcx
movzbl 0x9(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movw %ax, -0x26(%rbp)
cmpl $0x1, -0x1c(%rbp)
jne 0x14012
movq -0x18(%rbp), %rax
movzbl 0x6(%rax), %eax
movzwl %ax, %eax
movq -0x18(%rbp), %rcx
movzbl 0x7(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x68(%rax)
movw -0x26(%rbp), %cx
movq -0x10(%rbp), %rax
movw %cx, 0x1fd4(%rax)
movq -0x10(%rbp), %rax
movzwl 0x68(%rax), %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl $0x7, %eax
movw %ax, -0x34(%rbp)
movw $0x0, -0x32(%rbp)
movq -0x18(%rbp), %rax
addq $0xa, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1406b
jmp 0x144de
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movw %ax, -0x36(%rbp)
movzwl -0x36(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x140d1
movq -0x30(%rbp), %rax
movzbl 0x8(%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x9(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %edx
movq -0x10(%rbp), %rax
movzwl 0x1fd2(%rax), %ecx
addl %edx, %ecx
movw %cx, 0x1fd2(%rax)
jmp 0x14460
movzwl -0x36(%rbp), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
je 0x1445e
callq 0x13640
movq %rax, -0x40(%rbp)
movw -0x36(%rbp), %cx
movq -0x40(%rbp), %rax
movw %cx, (%rax)
movq -0x30(%rbp), %rax
movzbl 0x2(%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x58(%rbp)
movl -0x24(%rbp), %eax
movzwl %ax, %edi
callq 0xd980
movq -0x58(%rbp), %rdi
movq %rax, %rsi
callq 0x3500
movq -0x30(%rbp), %rax
movzbl 0x4(%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x5(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x50(%rbp)
movl -0x24(%rbp), %eax
movzwl %ax, %edi
callq 0xd980
movq -0x50(%rbp), %rdi
movq %rax, %rsi
callq 0x3500
movq -0x30(%rbp), %rax
movzbl 0x6(%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x7(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rax
addq $0x52, %rax
movq %rax, -0x48(%rbp)
movl -0x24(%rbp), %eax
movzwl %ax, %edi
callq 0xd980
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0x30c0
movw -0x26(%rbp), %cx
movq -0x40(%rbp), %rax
movw %cx, 0x7a(%rax)
movq -0x30(%rbp), %rax
movzbl 0x8(%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0x9(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movw %ax, %cx
movq -0x40(%rbp), %rax
movw %cx, 0x7c(%rax)
movq -0x40(%rbp), %rax
movzwl 0x7c(%rax), %edx
movq -0x10(%rbp), %rax
movzwl 0x1fd0(%rax), %ecx
addl %edx, %ecx
movw %cx, 0x1fd0(%rax)
movq -0x30(%rbp), %rax
movzbl 0xc(%rax), %eax
movzwl %ax, %eax
movq -0x30(%rbp), %rcx
movzbl 0xd(%rcx), %ecx
movzwl %cx, %ecx
shll $0x8, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x14278
movl -0x24(%rbp), %ecx
andl $0x1f, %ecx
addl $0x48, %ecx
movl -0x24(%rbp), %eax
shrl $0xe, %eax
andl $0x3, %eax
shll $0x5, %eax
addl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0xac(%rax)
movl -0x24(%rbp), %ecx
shrl $0x5, %ecx
andl $0x1f, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0xa4(%rax)
movl -0x24(%rbp), %ecx
shrl $0xa, %ecx
andl $0xf, %ecx
subl $0x1, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0xa8(%rax)
jmp 0x142a2
movq -0x40(%rbp), %rax
movl $0x48, 0xac(%rax)
movq -0x40(%rbp), %rax
movl $0x1, 0xa4(%rax)
movq -0x40(%rbp), %rax
movl $0x0, 0xa8(%rax)
movq -0x40(%rbp), %rax
movl $0x0, 0xd0(%rax)
movq -0x40(%rbp), %rax
movzwl (%rax), %eax
andl $0x4000, %eax           # imm = 0x4000
cmpl $0x0, %eax
je 0x142cf
movq -0x40(%rbp), %rax
movl $0x1, 0xd0(%rax)
movq -0x40(%rbp), %rax
movzwl (%rax), %eax
andl $0x8000, %eax           # imm = 0x8000
cmpl $0x0, %eax
je 0x142ee
movq -0x40(%rbp), %rax
movl $0x1, 0xd0(%rax)
movq -0x10(%rbp), %rax
cmpw $0x0, 0x68(%rax)
je 0x14406
movq -0x40(%rbp), %rax
cmpq $0x0, 0x90(%rax)
jne 0x1430d
jmp 0x1432c
leaq 0x961c(%rip), %rdi      # 0x1d930
leaq 0x931d(%rip), %rsi      # 0x1d638
movl $0x26d, %edx            # imm = 0x26D
leaq 0x961c(%rip), %rcx      # 0x1d943
callq 0x3200
callq 0x17040
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x90(%rax)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x90(%rax), %rsi
movq -0x30(%rbp), %rax
addq $0xe, %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
movl $0x200, %ecx            # imm = 0x200
cqto
idivq %rcx
movw %ax, -0x5a(%rbp)
movq -0x30(%rbp), %rax
addq $0xe, %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
movl $0x200, %ecx            # imm = 0x200
cqto
idivq %rcx
movw -0x5a(%rbp), %ax
movl %edx, %ecx
movq -0x10(%rbp), %rdx
movzwl 0x68(%rdx), %r8d
movzwl %ax, %edx
callq 0x13be0
movq -0x40(%rbp), %rax
movq 0x90(%rax), %rdi
addq $0x14, %rdi
leaq 0x85a6(%rip), %rsi      # 0x1c95d
callq 0x30c0
movq -0x40(%rbp), %rax
movq 0x90(%rax), %rax
movq 0x8(%rax), %rdi
movq -0x40(%rbp), %rax
movq 0x90(%rax), %rax
movl 0x10(%rax), %edx
xorl %esi, %esi
callq 0xd3d0
cmpl $0x0, %eax
je 0x14404
movq -0x40(%rbp), %rax
movq 0x90(%rax), %rdi
callq 0x16700
movq -0x40(%rbp), %rax
movq $0x0, 0x90(%rax)
jmp 0x14406
movq -0x10(%rbp), %rax
cmpl $0x3e8, 0x8c(%rax)      # imm = 0x3E8
jl 0x14436
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq 0x954a(%rip), %rsi      # 0x1d96c
movl $0x3e8, %edx            # imm = 0x3E8
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x144f5
movq -0x40(%rbp), %rdx
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rsi
movl 0x8c(%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, 0x8c(%rsi)
movslq %ecx, %rcx
movq %rdx, 0x90(%rax,%rcx,8)
jmp 0x14460
movq -0x30(%rbp), %rax
movzbl 0x8(%rax), %eax
movzwl %ax, %ecx
movq -0x30(%rbp), %rax
movzbl 0x9(%rax), %eax
movzwl %ax, %eax
shll $0x8, %eax
orl %eax, %ecx
movzwl -0x26(%rbp), %eax
addl %ecx, %eax
movw %ax, -0x26(%rbp)
movw -0x32(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x32(%rbp)
movzwl -0x34(%rbp), %ecx
movq -0x30(%rbp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
sarq %rax
cmpq $0x400, %rax            # imm = 0x400
jle 0x144d9
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq 0x94cc(%rip), %rsi      # 0x1d994
movl $0x400, %edx            # imm = 0x400
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x144f5
jmp 0x1403b
movl -0x20(%rbp), %eax
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
ja 0x13eab
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nop