📄 fat32.inc
字号:
inc ecx
cmp edx,512-4
jb check_new
inc ecx
inc eax
call hd_read_new
xor edx,edx
jmp check_new
found:
mov eax,ecx
pop edx
pop ecx
pop ebx
ret
;EXPERIMENTAL !!!!!!!!!!!!!
get_cluster_of_a_path:
;---------------------------------------------------------
; input: EBX = pointer to a path string
; (example: the path "/files/data/document" become
; "files......data.......document...0"
; '.' = space char
; '0' = char(0) (ASCII=0) !!! )
; output: if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
push ebx
push edx
mov eax,[ROOT_CLUSTER]
mov edx,ebx
search_end_of_path:
cmp byte [edx],0
je found_end_of_path
inc edx ; '/'
mov ebx,edx
call analyze_directory
jc directory_not_found
mov ax,[ebx+20] ;read the HIGH 16bit cluster field
shl eax,16
mov ax,[ebx+26] ;read the LOW 16bit cluster field
add edx,11 ;8+3 (name+extension)
jmp search_end_of_path
found_end_of_path:
pop edx
pop ebx
clc ;no errors
ret
directory_not_found:
pop edx
pop ebx
stc ;errors occour
ret
bcd2bin:
;----------------------------------
; input : AL=BCD number (eg. 0x11)
; output : AH=0
; AL=decimal number (eg. 11)
;----------------------------------
push cx
mov cl,al
shr cl,4
mov ch,cl
shl cl,3
add cl,ch
add cl,ch
and al,0xf
add al,cl
mov ah,0
pop cx
ret
get_data_for_file:
;-----------------------------------------------------
; Get data from CMOS and pack day,month,year in AX
; DATE bits 0..4 : day of month 0..31
; 5..8 : month of year 1..12
; 9..15 : count of years from 1980
;-----------------------------------------------------
push dx
xor dx,dx
mov al,0x7 ;day
out 0x70,al
in al,0x71
call bcd2bin
or dx,ax
mov al,0x8 ;month
out 0x70,al
in al,0x71
call bcd2bin
shl ax,5
or dx,ax
mov al,0x9 ;year
out 0x70,al
in al,0x71
call bcd2bin
add ax,20 ;because CMOS return only the
;two last digit (eg. 2000 -> 00 , 2001 -> 01) and we
shl ax,9 ;need the difference with
;1980 (eg. 2001-1980)
or dx,ax
xchg ax,dx ;the result must be in AX
pop dx
ret
;-----------------------------------------------------
; Get time from CMOS and pack hour,minute,second in AX
; TIME bits 0..4 : second (the low bit is lost)
; 5..10 : minute 0..59
; 11..15 : hour 0..23
;-----------------------------------------------------
get_time_for_file:
push dx
xor dx,dx
mov al,0x0 ;second
out 0x70,al
in al,0x71
call bcd2bin
shr ax,1
or dx,ax
mov al,0x2 ;minute
out 0x70,al
in al,0x71
call bcd2bin
shl ax,5
or dx,ax
mov al,0x4 ;hour
out 0x70,al
in al,0x71
call bcd2bin
shl ax,11
or dx,ax
xchg ax,dx ;the result must be in AX
pop dx
ret
file_write:
;--------------------------------------------------------------------------
; INPUT :user-reg register-in-this meaning symbol-in-this-routine
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) file size PAR2
; ESI EDX (PAR3) pointer to path PAR3
;--------------------------------------------------------------------------
; ret ; we've noticed some directory overwrite with large files
; if you're ok with that , comment ret
cmp [valid_fat],byte 1
jz fat_ok_for_writing
ret
fat_ok_for_writing:
cli
cmp [hd1_status],0
je fatokl1
sti
call change_task
jmp fat_ok_for_writing
fatokl1:
mov [hd1_status],1
sti
sub esp,32
call expand_filename
pusha
mov ecx,edx ;try to delete the file first
call file_delete
popa
pushad
mov [0xfe10],dword 0
PAR0 equ [esp+28] ;EAX
PAR1 equ [esp+24] ;ECX
PAR2 equ [esp+16] ;EBX
PAR3 equ [esp+20] ;EDX
mov ebx,PAR3
call get_cluster_of_a_path
jnc found_directory_for_writing
exit_writing_with_error:
popa
stc
add esp,32
mov [hd1_status],0
ret
found_directory_for_writing:
call analyze_directory_to_write
found1:
push eax
mov eax,2
call get_free_FAT
mov [cluster],eax
pop eax
push ebx
mov ebx,buffer
call hd_read_new
pop ebx
mov esi,PAR0 ;file name
mov edi,ebx
mov ecx,11
cld
rep movsb
mov ecx,PAR2
mov [ebx+28],ecx ;file size
mov ecx,[cluster]
mov [ebx+26],cx ;16 bits low of cluster
shr ecx,16
mov [ebx+20],cx ;16 bits high of cluster
mov byte [ebx+11],0x20 ;attrib
push eax
call get_time_for_file
mov [ebx+22],ax
call get_data_for_file
mov [ebx+24],ax
pop eax
mov ebx,buffer ;save the directory name,length,cluster
call hd_write_new
imul esi,[SECTOR_PER_CLUSTER],512
hd_new_block_write:
mov eax,[cluster] ; eax = block
mov ebx,PAR1 ; ebx = buffer
call set_data_cluster
mov ecx,esi ; ecx = size to write in bytes
cmp ecx,PAR2
jbe adr3
mov ecx,PAR2
adr3:
add PAR1,ecx
sub PAR2,ecx ; sub wrote bytes in stack
cmp PAR2,dword 0
je file_saved_OK
mov eax,[cluster]
inc eax
call get_free_FAT
mov [cluster1],eax ; next free in FAT
mov eax,[cluster]
mov edx,[cluster1]
call set_FAT
mov eax,[cluster1]
mov [cluster],eax
jmp hd_new_block_write ; adr2
file_saved_OK:
mov eax,[cluster]
mov edx,0x0fffffff
call set_FAT
popad
clc
add esp,32
mov [hd1_status],0
ret
file_read:
;--------------------------------------------------------------------------
; INPUT : user-register register-in-this meaning symbol-in-this
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) file size PAR2
; ESI EDX (PAR3) pointer to path PAR3
;--------------------------------------------------------------------------
cmp [valid_fat],byte 1
jz fat_ok_for_reading
ret
fat_ok_for_reading:
pushad
PAR0 equ [esp+28] ;EAX
PAR1 equ [esp+24] ;ECX
PAR2 equ [esp+16] ;EBX
PAR3 equ [esp+20] ;EDX
mov ebx,PAR3
call get_cluster_of_a_path
jc file_to_read_not_found
mov ebx,PAR0
call analyze_directory
jc file_to_read_not_found
found1r:
mov ax,[ebx+20]
shl eax,16
mov ax,[ebx+26]
imul esi,[SECTOR_PER_CLUSTER],512
mov ebx,PAR1
mov ecx,esi
cmp PAR2,esi
jae adr3r
mov ecx,PAR2
adr3r:
call get_data_cluster
adr2r:
add PAR1,ecx
sub PAR2,ecx
jz file_read_OK
call get_FAT
mov ebx,PAR1
mov ecx,esi
cmp PAR2,esi
jae adr4r
mov ecx,PAR2
adr4r:
call get_data_cluster
jmp adr2r
file_read_OK:
popad
clc
ret
file_to_read_not_found:
popad
stc
ret
f_del db 0x0
file_delete:
;--------------------------------------------------------------------------
;EXPERIMENTAL !!!!!
; INPUT : user-reg register-in-this meaning symbol-in-this
; EAX EDI system call to delete /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to path PAR1
;--------------------------------------------------------------------------
cmp [valid_fat],byte 1
jz fat_ok_for_deleting
ret
fat_ok_for_deleting:
pushad
mov [f_del],1 ; delete on
mov [0xfe10],dword 0 ; clear cache
PAR0 equ [esp+28] ;EAX
PAR1 equ [esp+24] ;ECX
mov ebx,PAR1
call get_cluster_of_a_path
jc file_to_delete_not_found
mov ebx,PAR0
call analyze_directory
jc file_to_delete_not_found
found_delete:
mov byte [ebx],0xe5
mov edx,ebx
mov ebx,buffer
call hd_write_new
mov ebx,edx
mov ax,[ebx+20]
shl eax,16
mov ax,[ebx+26]
xor edx,edx
clean_new_chain:
mov ebx,eax
call get_FAT
mov ecx,eax
mov eax,ebx
call set_FAT
mov eax,ecx
cmp eax,0x0f000000
jge delete_OK
jmp clean_new_chain
delete_OK:
popad
clc
mov [f_del],0
ret
file_to_delete_not_found:
popad
mov [f_del],0
stc
ret
;**************************************************************************
hd_read_new:
; eax = block
; ebx = pointer to memory
call wait_for_hd_idle
push edi ; [esp+12] +13 +14 +15
push eax ; [esp+8] +9 +10 +11
push ecx ; [esp+4] +5 +6 +7
push edx ; [esp] +1 +2 +3
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
mov al,1
out dx,al
inc edx
mov al,[esp+8]
out dx,al
inc edx
mov al,[esp+9]
out dx,al
inc edx
mov al,[esp+10]
out dx,al
inc edx
mov al,[esp+11]
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al
inc edx
mov al,20h
out dx,al
sti
hdwait_read:
in al,dx
and al,128
jnz hdwait_read
cli
mov edi,ebx
mov ecx,256
mov edx,[hdbase]
cld
rep insw
sti
pop edx
pop ecx
pop eax
pop edi
ret
;****************************************************************
hd_write_new:
; eax = block
; ebx = pointer to memory
cmp eax,[PARTITION_START]
jb danger
cmp eax,[PARTITION_END]
ja danger
call wait_for_hd_idle
push esi ; [esp+12] +13 +14 +15
push eax ; [esp+8] +9 +10 +11
push ecx ; [esp+4] +5 +6 +7
push edx ; [esp] +1 +2 +3
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
mov al,1
out dx,al
inc edx
mov al,[esp+8]
out dx,al
inc edx
mov al,[esp+9]
out dx,al
inc edx
mov al,[esp+10]
out dx,al
inc edx
mov al,[esp+11]
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al
inc edx
mov al,31h
out dx,al
mov esi,ebx
mov ecx,256
mov edx,[hdbase]
cld
rep outsw ;port[dx] <- word [esi]
sti
add edx,7
hdwait_write:
in al,dx
and al,128
jnz hdwait_write
pop edx
pop ecx
pop eax
pop esi
danger:
ret
wait_for_hd_idle:
push eax
push edx
mov edx,[hdbase]
add edx,0x7
wfhil1:
in al,dx
test al,128
jnz wfhil1
pop edx
pop eax
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -