// File: /workspace/github_c_makefile_star2_O0/lb3361[P]dosfs/ff.c
// Function: f_forward
FRESULT f_forward (
	FIL* fp, 						/* Pointer to the file object */
	UINT (*func)(const BYTE*,UINT),	/* Pointer to the streaming function */
	UINT btf,						/* Number of bytes to forward */
	UINT* bf						/* Pointer to number of bytes forwarded */
)
{
	FRESULT res;
	FATFS *fs;
	DWORD clst;
	LBA_t sect;
	FSIZE_t remain;
	UINT rcnt, csect;
	BYTE *dbuf;


	*bf = 0;	/* Clear transfer byte counter */
	res = validate(&fp->obj, &fs);		/* Check validity of the file object */
	if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
	if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED);	/* Check access mode */

	remain = fp->obj.objsize - fp->fptr;
	if (btf > remain) btf = (UINT)remain;			/* Truncate btf by remaining bytes */

	for ( ;  btf && (*func)(0, 0);					/* Repeat until all data transferred or stream goes busy */
		fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) {
		csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1));	/* Sector offset in the cluster */
		if (fp->fptr % SS(fs) == 0) {				/* On the sector boundary? */
			if (csect == 0) {						/* On the cluster boundary? */
				clst = (fp->fptr == 0) ?			/* On the top of the file? */
					fp->obj.sclust : get_fat(&fp->obj, fp->clust);
				if (clst <= 1) ABORT(fs, FR_INT_ERR);
				if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
				fp->clust = clst;					/* Update current cluster */
			}
		}
		sect = clst2sect(fs, fp->clust);			/* Get current data sector */
		if (sect == 0) ABORT(fs, FR_INT_ERR);
		sect += csect;
#if FF_FS_TINY
		if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR);	/* Move sector window to the file data */
		dbuf = fs->win;
#else
		if (fp->sect != sect) {		/* Fill sector cache with file data */
#if !FF_FS_READONLY
			if (fp->flag & FA_DIRTY) {		/* Write-back dirty sector cache */
				if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
				fp->flag &= (BYTE)~FA_DIRTY;
			}
#endif
			if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
		}
		dbuf = fp->buf;
#endif
		fp->sect = sect;
		rcnt = SS(fs) - (UINT)fp->fptr % SS(fs);	/* Number of bytes remains in the sector */
		if (rcnt > btf) rcnt = btf;					/* Clip it by btr if needed */
		rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt);	/* Forward the file data */
		if (rcnt == 0) ABORT(fs, FR_INT_ERR);
	}

	LEAVE_FF(fs, FR_OK);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl $0x0, (%rax)
movq -0x10(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x6c70
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0xb107
movq -0x10(%rbp), %rax
movzbl 0x31(%rax), %eax
movl %eax, -0x2c(%rbp)
cmpl $0x0, %eax
je 0xb112
movl -0x2c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xb3ba
movq -0x10(%rbp), %rax
movzbl 0x30(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0xb12e
movl $0x7, -0x4(%rbp)
jmp 0xb3ba
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
subq 0x38(%rcx), %rax
movq %rax, -0x50(%rbp)
movl -0x1c(%rbp), %eax
cmpq -0x50(%rbp), %rax
jbe 0xb152
movq -0x50(%rbp), %rax
movl %eax, -0x1c(%rbp)
jmp 0xb154
xorl %eax, %eax
cmpl $0x0, -0x1c(%rbp)
movb %al, -0x61(%rbp)
je 0xb171
xorl %eax, %eax
movl %eax, %edi
xorl %esi, %esi
callq *-0x18(%rbp)
cmpl $0x0, %eax
setne %al
movb %al, -0x61(%rbp)
movb -0x61(%rbp), %al
testb $0x1, %al
jne 0xb17d
jmp 0xb3b3
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
shrq $0x9, %rax
movq -0x38(%rbp), %rcx
movzwl 0xa(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
andq %rcx, %rax
movl %eax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
andq $0x1ff, %rax            # imm = 0x1FF
cmpq $0x0, %rax
jne 0xb227
cmpl $0x0, -0x58(%rbp)
jne 0xb225
movq -0x10(%rbp), %rax
cmpq $0x0, 0x38(%rax)
jne 0xb1ce
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x68(%rbp)
jmp 0xb1e1
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x40(%rax), %esi
callq 0x6560
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x3c(%rbp)
cmpl $0x1, -0x3c(%rbp)
ja 0xb201
movq -0x10(%rbp), %rax
movb $0x2, 0x31(%rax)
movl $0x2, -0x4(%rbp)
jmp 0xb3ba
cmpl $-0x1, -0x3c(%rbp)
jne 0xb21b
movq -0x10(%rbp), %rax
movb $0x1, 0x31(%rax)
movl $0x1, -0x4(%rbp)
jmp 0xb3ba
movl -0x3c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x40(%rax)
jmp 0xb227
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x40(%rax), %esi
callq 0x6870
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0xb256
movq -0x10(%rbp), %rax
movb $0x2, 0x31(%rax)
movl $0x2, -0x4(%rbp)
jmp 0xb3ba
movl -0x58(%rbp), %eax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
cmpq -0x48(%rbp), %rax
je 0xb30b
movq -0x10(%rbp), %rax
movzbl 0x30(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0xb2d0
movq -0x38(%rbp), %rax
movb 0x1(%rax), %al
movq -0x10(%rbp), %rsi
addq $0x60, %rsi
movq -0x10(%rbp), %rcx
movq 0x48(%rcx), %rdx
movl $0x1, %ecx
movzbl %al, %edi
callq 0x1a40
cmpl $0x0, %eax
je 0xb2c2
movq -0x10(%rbp), %rax
movb $0x1, 0x31(%rax)
movl $0x1, -0x4(%rbp)
jmp 0xb3ba
movq -0x10(%rbp), %rax
movzbl 0x30(%rax), %ecx
andl $0x7f, %ecx
movb %cl, 0x30(%rax)
movq -0x38(%rbp), %rax
movb 0x1(%rax), %al
movq -0x10(%rbp), %rsi
addq $0x60, %rsi
movq -0x48(%rbp), %rdx
movl $0x1, %ecx
movzbl %al, %edi
callq 0x1970
cmpl $0x0, %eax
je 0xb309
movq -0x10(%rbp), %rax
movb $0x1, 0x31(%rax)
movl $0x1, -0x4(%rbp)
jmp 0xb3ba
jmp 0xb30b
movq -0x10(%rbp), %rax
addq $0x60, %rax
movq %rax, -0x60(%rbp)
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %eax, %ecx
andl $0x1ff, %ecx            # imm = 0x1FF
movl $0x200, %eax            # imm = 0x200
subl %ecx, %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jbe 0xb34b
movl -0x1c(%rbp), %eax
movl %eax, -0x54(%rbp)
movq -0x18(%rbp), %rax
movq -0x60(%rbp), %rdi
movq -0x10(%rbp), %rcx
movq 0x38(%rcx), %rcx
andl $0x1ff, %ecx            # imm = 0x1FF
movl %ecx, %ecx
addq %rcx, %rdi
movl -0x54(%rbp), %esi
callq *%rax
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
jne 0xb385
movq -0x10(%rbp), %rax
movb $0x2, 0x31(%rax)
movl $0x2, -0x4(%rbp)
jmp 0xb3ba
jmp 0xb387
movl -0x54(%rbp), %eax
movl %eax, %ecx
movq -0x10(%rbp), %rax
addq 0x38(%rax), %rcx
movq %rcx, 0x38(%rax)
movl -0x54(%rbp), %ecx
movq -0x28(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movl -0x54(%rbp), %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
jmp 0xb154
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)