// File: /workspace/github_c_makefile_star2_O0/j-hoppe[P]tu58fs/image.c
// Function: image_hostfile_open
static int image_hostfile_open(image_t *_this, int allowcreate, int *filecreated) {
	int32_t fd;		// file descriptor

	*filecreated = 0;

	if (!_this->readonly) // check writability here.
		fd = open(_this->host_fpath, O_BINARY | O_RDWR, 0666);
	else
		fd = open(_this->host_fpath, O_BINARY | O_RDONLY);

	// create file if it does not exist
	if (fd < 0 && allowcreate) {
		fd = creat(_this->host_fpath, 0666);
		*filecreated = 1;
	}
	if (fd < 0)
		return error_set(ERROR_HOSTFILE, "Unit %d: image_open cannot open or create \"%s\"",
				_this->unit, _this->host_fpath);
		// get timestamps, to monitor changes
	stat(_this->host_fpath, &_this->host_fattr);

	// clear image
	memset(_this->data, 0, _this->data_size);

	if (!*filecreated) {
		// existing file
		int res;
		if ((unsigned)_this->host_fattr.st_size > _this->data_size) { // trunc ?
			if (!is_fileset(_this->host_fpath, 0, _this->data_size))
				fatal(
						"File \"%s\" is %d blocks, shall be trunc'd to %d blocks, non-zero data would be lost",
						_this->host_fpath, NEEDED_BLOCKS(_this->blocksize, _this->data_size),
						_this->forced_blockcount);
		}

		res = read(fd, _this->data, _this->data_size);

		// read file to memory
		if (res < 0)
			return error_set(ERROR_HOSTFILE, "Unit %d: image_open cannot read \"%s\"",
					_this->unit, _this->host_fpath);
		if (res < _this->host_fattr.st_size)
			return error_set(ERROR_HOSTFILE,
					"Unit %d: image_open cannot read %d bytes from \"%s\"", _this->unit,
					_this->host_fattr.st_size, _this->host_fpath);
		_this->changed = 0; // is in sync with disc file

		/* modify locally, if no empty file */
		if (_this->dec_filesystem != fsNONE && !is_memset(_this->data, 0, _this->data_size)) {
			filesystem_t *pdp_fs = filesystem_create(_this->dec_filesystem, _this->dec_device,
					_this->readonly, _this->data, _this->data_size, NULL);
			filesystem_parse(pdp_fs);
			filesystem_patch(pdp_fs); // RT-11: change DD.SYS
			filesystem_destroy(pdp_fs);
		}

	} else {
		// new file created
		// init mem. even if later file is loaded?
		switch (_this->dec_filesystem) {
		case fsNONE:
			info("Unit %d: zero'd new tape on '%s'", _this->unit, _this->host_fpath);
			break;
		case fsXXDP:
		case fsRT11: {
			filesystem_t *pdp_fs;
			// render an empty filesystem into data[]
			pdp_fs = filesystem_create(_this->dec_filesystem, _this->dec_device,
					_this->readonly, _this->data, _this->data_size, NULL);
			if (filesystem_render(pdp_fs))
				return error_set(error_code, "Creating empty file system");
			filesystem_destroy(pdp_fs);
			info("Unit %d: initialize empty %s file system on \"%s\"", _this->unit,
					filesystem_name(_this->dec_filesystem), _this->host_fpath);
		}
			break;
		}
		_this->changed = 1; // must be written
		// blocks need not be marked as "changed" because no file on image yet
	}

	// close file, TU58 works only on image
	// if "c" flag, now empty file created
	close(fd);

	return ERROR_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x3c(%rax)
jne 0x9985
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movl $0x2, %esi
movl $0x1b6, %edx            # imm = 0x1B6
movb $0x0, %al
callq 0x3490
movl %eax, -0x24(%rbp)
jmp 0x9999
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x3490
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x99c4
cmpl $0x0, -0x14(%rbp)
je 0x99c4
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movl $0x1b6, %esi            # imm = 0x1B6
callq 0x3510
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movl $0x1, (%rax)
cmpl $0x0, -0x24(%rbp)
jge 0x99f3
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rcx
movl $0xfffffffa, %edi       # imm = 0xFFFFFFFA
leaq 0x125fe(%rip), %rsi     # 0x1bfe2
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x9cd4
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x48, %rsi
callq 0x3310
movq -0x10(%rbp), %rax
movq 0x118(%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x110(%rax), %eax
movl %eax, %edx
xorl %esi, %esi
callq 0x3220
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x9bd1
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rax
movq -0x10(%rbp), %rcx
cmpl 0x110(%rcx), %eax
jbe 0x9aa9
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x110(%rax), %edx
xorl %esi, %esi
callq 0xd430
cmpl $0x0, %eax
jne 0x9aa7
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x110(%rax), %eax
movq -0x10(%rbp), %rcx
addl 0xf0(%rcx), %eax
subl $0x1, %eax
movq -0x10(%rbp), %rcx
xorl %edx, %edx
divl 0xf0(%rcx)
movl %eax, %edx
movq -0x10(%rbp), %rax
movl 0x40(%rax), %ecx
leaq 0x12571(%rip), %rdi     # 0x1c011
movb $0x0, %al
callq 0xd140
jmp 0x9aa9
movl -0x24(%rbp), %edi
movq -0x10(%rbp), %rax
movq 0x118(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x110(%rax), %eax
movl %eax, %edx
callq 0x32a0
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jge 0x9afa
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rcx
movl $0xfffffffa, %edi       # imm = 0xFFFFFFFA
leaq 0x12579(%rip), %rsi     # 0x1c064
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x9cd4
movslq -0x28(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x78(%rcx), %rax
jge 0x9b39
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %r8
movl $0xfffffffa, %edi       # imm = 0xFFFFFFFA
leaq 0x1255f(%rip), %rsi     # 0x1c089
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x9cd4
movq -0x10(%rbp), %rax
movb $0x0, 0xf5(%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x10c(%rax)
je 0x9bcc
movq -0x10(%rbp), %rax
movq 0x118(%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x110(%rax), %edx
xorl %esi, %esi
callq 0xd3d0
cmpl $0x0, %eax
jne 0x9bcc
movq -0x10(%rbp), %rax
movl 0x10c(%rax), %edi
movq -0x10(%rbp), %rax
movl 0x108(%rax), %esi
movq -0x10(%rbp), %rax
movl 0x3c(%rax), %edx
movq -0x10(%rbp), %rax
movq 0x118(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x110(%rax), %r8d
xorl %eax, %eax
movl %eax, %r9d
callq 0xec80
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0xee60
movq -0x30(%rbp), %rdi
callq 0xf380
movq -0x30(%rbp), %rdi
callq 0xed80
jmp 0x9cc5
movq -0x10(%rbp), %rax
movl 0x10c(%rax), %eax
movl %eax, -0x3c(%rbp)
testl %eax, %eax
je 0x9bf3
jmp 0x9be4
movl -0x3c(%rbp), %eax
decl %eax
subl $0x2, %eax
jb 0x9c14
jmp 0x9cba
movq -0x10(%rbp), %rax
movl (%rax), %esi
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdx
leaq 0x124b4(%rip), %rdi     # 0x1c0bc
movb $0x0, %al
callq 0xcf60
jmp 0x9cba
movq -0x10(%rbp), %rax
movl 0x10c(%rax), %edi
movq -0x10(%rbp), %rax
movl 0x108(%rax), %esi
movq -0x10(%rbp), %rax
movl 0x3c(%rax), %edx
movq -0x10(%rbp), %rax
movq 0x118(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x110(%rax), %r8d
xorl %eax, %eax
movl %eax, %r9d
callq 0xec80
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0xf310
cmpl $0x0, %eax
je 0x9c7d
leaq 0x1b8d0(%rip), %rax     # 0x25538
movl (%rax), %edi
leaq 0x1246c(%rip), %rsi     # 0x1c0dd
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x9cd4
movq -0x38(%rbp), %rdi
callq 0xed80
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl 0x10c(%rax), %edi
callq 0xec20
movl -0x40(%rbp), %esi
movq %rax, %rdx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rcx
leaq 0x12445(%rip), %rdi     # 0x1c0f8
movb $0x0, %al
callq 0xcf60
movq -0x10(%rbp), %rax
movb $0x1, 0xf5(%rax)
movl -0x24(%rbp), %edi
callq 0x3260
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)