; File structure. This holds the information for each currently open file.
;
struc open_file_t
-file_left resd 1 ; Number of sectors left (0 = free)
+file_bytesleft resd 1 ; Number of bytes left (0 = free)
file_sector resd 1 ; Next linear sector to read
file_in_sec resd 1 ; Sector where inode lives
file_in_off resw 1
mov ax,[ThisInode+i_mode]
mov [bx+file_mode],ax
mov eax,[ThisInode+i_size]
- push eax
- add eax,SECTOR_SIZE-1
- shr eax,SECTOR_SHIFT
- mov [bx+file_left],eax
- pop eax
+ mov [bx+file_bytesleft],eax
mov si,bx
and eax,eax ; ZF clear unless zero-length file
pop gs
close_file:
and si,si
jz .closed
- mov dword [si],0 ; First dword == file_left
+ mov dword [si],0 ; First dword == file_bytesleft
.closed: ret
;
; CX -> Sector count (0FFFFh = until end of file)
; Must not exceed the ES segment
; Returns CF=1 on EOF (not necessarily error)
+; On return ECX = number of bytes read
; All arguments are advanced to reflect data read.
;
getfssec:
push edi
movzx ecx,cx
- cmp ecx,[si] ; Number of sectors left
+ push ecx ; Sectors requested read
+ mov eax,[si+file_bytesleft]
+ add eax,SECTOR_SIZE-1
+ shr eax,SECTOR_SHIFT
+ cmp ecx,eax ; Number of sectors left
jbe .lenok
- mov cx,[si]
+ mov cx,ax
.lenok:
.getfragment:
mov eax,[si+file_sector] ; Current start index
add bx,bp ; Adjust buffer pointer
pop bp
add [si+file_sector],ebp ; Next sector index
- sub [si],ebp ; Sectors consumed
jcxz .done
jnz .getfragment
; Fall through
.done:
- cmp dword [si],1 ; Did we run out of file?
+ pop ecx ; Sectors requested read
+ shl ecx,SECTOR_SHIFT
+ cmp ecx,[si+file_bytesleft]
+ jb .noteof
+ mov ecx,[si+file_bytesleft]
+.noteof: sub [si+file_bytesleft],ecx
+ ; Did we run out of file?
+ cmp dword [si+file_bytesleft],1
; CF set if [SI] < 1, i.e. == 0
pop edi
pop edx
;
struc open_file_t
file_sector resd 1 ; Sector pointer (0 = structure free)
+file_bytesleft resd 1 ; Number of bytes left
file_left resd 1 ; Number of sectors left
+ resd 1 ; Unused
endstruc
%ifndef DEPEND
jnz .badfile ; If not a file, it's a bad thing
; SI and EAX are already set
+ mov [si+file_bytesleft],eax
and eax,eax ; EAX != 0
jz .badfile
ret ; Done!
; CX -> Sector count (0FFFFh = until end of file)
; Must not exceed the ES segment
; Returns CF=1 on EOF (not necessarily error)
+; ECX returns number of bytes read.
; All arguments are advanced to reflect data read.
;
getfssec:
push edx
movzx edx,cx
- cmp edx,[si+4]
+ push edx ; Zero-extended CX
+ cmp edx,[si+file_left]
jbe .sizeok
- mov edx,[si+4]
+ mov edx,[si+file_left]
mov cx,dx
.sizeok:
- sub [si+4],edx
- mov edx,[si]
+ sub [si+file_left],edx
+ mov edx,[si+file_sector]
call getfssec_edx
- mov [si],edx
+ mov [si+file_sector],edx
+ pop ecx ; Sectors requested read
+ pushf ; Save CF from getfssec_edx
+ shl ecx,SECTOR_SHIFT
+ cmp ecx,[si+file_bytesleft]
+ jna .noteof
+ mov ecx,[si+file_bytesleft]
+.noteof: sub ecx,[si+file_bytesleft]
+ popf
pop edx
ret