Fat.inc
[ Return to Browse Source Page ]
; FAT16 Procedures for PizziOS
; Started 26 Aug 2000
; fat16_arrangename_dots:
; lea edi,[edi+1]
; mov al,[edi]
; mov cl,1
; mov ch,10
; cmp al,'.'
; jnz fat16_arrangename_1dot
; lea edi,[edi+1]
; inc cl
; dec ch
; fat16_arrangename_1dot:
; mov al,[edi]
; test al,al
; jz fat16_arrangename_dots_ok
; stc
; jmp fat16_arrangename_error
; fat16_arrangename_dots_ok:
; mov al,'.'
; fat16_arrangename_dots_l1:
; dec cl
; mov [esi],al
; lea esi,[esi+1]
; jnz fat16_arrangename_dots_l1
; mov al,020h
; fat16_arrangename_dots_l2:
; dec ch
; mov [esi],al
; lea esi,[esi+1]
; jnz fat16_arrangename_dots_l2
; jmp fat16_arrangename_b5
fat16_arrangename:
push edi
push eax
push ebx
push ecx
mov ebx,offset fat16_filename
; mov al,[edi]
; cmp al,'.'
; jz fat16_arrangename_dots
mov cl,8
fat16_arrangename_l1:
mov al,[edi]
lea edi,[edi+1]
test al,al
jz fat16_arrangename_b1
cmp al,'.'
jz fat16_arrangename_b2
mov [ebx],al
lea ebx,[ebx+1]
dec cl
jz fat16_arrangename_b3
jmp fat16_arrangename_l1
fat16_arrangename_b2:
mov al,020h
fat16_arrangename_l2:
mov [ebx],al
lea ebx,[ebx+1]
dec cl
jnz fat16_arrangename_l2
fat16_arrangename_b3_ret:
mov cl,3
fat16_arrangename_l3:
mov al,[edi]
lea edi,[edi+1]
test al,al
jz fat16_arrangename_b4
mov [ebx],al
lea ebx,[ebx+1]
dec cl
jz fat16_arrangename_b5
jmp fat16_arrangename_l3
fat16_arrangename_b4:
mov al,020h
fat16_arrangename_l4:
mov [ebx],al
lea ebx,[ebx+1]
dec cl
jnz fat16_arrangename_l4
fat16_arrangename_b5:
clc
fat16_arrangename_error:
pop ecx
pop ebx
pop eax
pop edi
ret
fat16_arrangename_b1:
add cl,3
jmp fat16_arrangename_b4
fat16_arrangename_b3:
mov al,[edi]
lea edi,[edi+1]
test al,al
jz fat16_arrangename_b1
cmp al,'.'
jz fat16_arrangename_b3_ret
stc
jmp fat16_arrangename_error
fat16_cd:
; esi = partition table
; eax = directory
mov edi,eax
call toupper
call fat16_arrangename
jc fat16_cd_err_1
mov ebx,ds:[current_directory]
xor eax,eax
mov al,[esi+2] ; spc
test ebx,ebx
jnz fat16_cd_notroot
mov eax,[esi+16]
fat16_cd_notroot:
push ebx ; cluster #
push eax ; sectors left
call fat16_xlate
push ebx ; sector #
; [esp] = s#, [esp+4] = sectors left, [esp+8] = c#
IFDEF debugfs
mov eax,[esp]
call print_hex_32
mov eax,ecx
call print_hex_32
call pause
call do_crlf
ENDIF
fat16_cd_sectorloop:
IFDEF debugfs
mov eax,[esp]
call print_hex_32
mov eax,[esp+4]
call print_hex_32
mov eax,[esp+8]
call print_hex_32
call pause
ENDIF
mov ebx,[esp]
mov edi,offset hd_buffer
call read_sector_p2
jc fat16_cd_err_2
IFDEF debugfs
call dump_sector
call clearscreen
ENDIF
mov edx,ds:[fat16_filename+8]
mov ebp,ds:[fat16_filename]
mov ebx,ds:[fat16_filename+4]
and edx,0ffffffh
mov ch,(512/32)
fat16_cd_entryloop:
mov eax,[edi]
cmp eax,ebp
jnz fat16_cd_entryloop_next
mov eax,[edi+4]
cmp eax,ebx
jnz fat16_cd_entryloop_next
mov eax,[edi+8]
test eax,010000000h
jz fat16_cd_entryloop_next
and eax,0ffffffh
cmp eax,edx
jnz fat16_cd_entryloop_next
xor eax,eax
mov ax,[edi + 26]
mov ds:[current_directory],eax
jmp fat16_cd_success
fat16_cd_entryloop_next:
lea edi,[edi+32]
dec ch
jnz fat16_cd_entryloop
IFDEF debugfs
call pause
ENDIF
call fat16_nextsector
jnc fat16_cd_sectorloop
fat16_cd_err_2:
lea esp,[esp+12]
fat16_cd_err_1:
popad
ret
fat16_cd_success:
mov esi,offset current_directory_str
fat16_cd_success_l1:
mov al,[esi]
lea esi,[esi+1]
test al,al
jnz fat16_cd_success_l1
mov al,'/'
mov [esi-1],al
mov [esi],ebp
mov [esi+4],ebx
fat16_cd_success_l2:
mov al,[esi]
lea esi,[esi+1]
test al,al
jz fat_16_cd_success_l2_break
cmp al,020h
jnz fat16_cd_success_l2
fat_16_cd_success_l2_break:
lea esi,[esi-1]
cmp edx,0202020h
jz fat16_cd_success_extdone
mov [esi],edx
mov edx,0202020h
jmp fat16_cd_success_l2
fat16_cd_success_extdone:
xor al,al
mov [esi],al
lea esp,[esp+12]
popad
ret
fat16_tmp_dir:
; esi = partition table
mov ebx,ds:[current_directory]
xor eax,eax
mov al,[esi+2] ; spc
test ebx,ebx
jnz fat16_tmp_dir_notroot
mov eax,[esi+16]
fat16_tmp_dir_notroot:
push ebx ; cluster #
push eax ; sectors left
call fat16_xlate
push ebx ; sector #
; [esp] = s#, [esp+4] = sectors left, [esp+8] = c#
IFDEF debugfs
mov eax,[esp]
call print_hex_32
mov eax,ecx
call print_hex_32
call pause
call do_crlf
ENDIF
fat16_tmp_dir_sectorloop:
IFDEF debugfs
mov eax,[esp]
call print_hex_32
mov eax,[esp+4]
call print_hex_32
mov eax,[esp+8]
call print_hex_32
call pause
ENDIF
mov ebx,[esp]
mov edi,offset hd_buffer
call read_sector_p2
jc fat16_tmp_dir_exit
IFDEF debugfs
call dump_sector
call clearscreen
ENDIF
mov ch,(512/32)
fat16_tmp_dir_entryloop:
mov eax,[edi]
test al,al
jz fat16_tmp_dir_entryloop_next
cmp al,0e5h ; file deleted marker
jz fat16_tmp_dir_entryloop_next
cmp al,02eh ; directory location/parent info
jz fat16_tmp_dir_entryloop_next
mov ebx,[edi+4]
mov edx,[edi+8]
mov dword ptr ds:[file_str],eax
and edx,0ffffffh
mov dword ptr ds:[file_str+4],ebx
mov al,[edi+11]
mov dword ptr ds:[file_str_ext],edx
cmp al,0fh ; LFN entry - ignore
jz fat16_tmp_dir_entryloop_next
test al,01000b
jnz fat16_tmp_dir_entryloop_next
push esi
mov esi,offset pre_file_str
test al,10000b
jz fat16_tmp_dir_not_dir
mov esi,offset pre_dir_str
fat16_tmp_dir_not_dir:
call print
mov esi,offset file_str
call print
mov esi,offset file_str_ext_p
call print
call do_crlf
pop esi
fat16_tmp_dir_entryloop_next:
lea edi,[edi+32]
dec ch
jnz fat16_tmp_dir_entryloop
IFDEF debugfs
call pause
ENDIF
call fat16_nextsector
jnc fat16_tmp_dir_sectorloop
fat16_tmp_dir_exit:
call do_crlf
lea esp,[esp+12]
popad
ret
fat16_nextsector:
; [esp+4] = s#, [esp+8] = sectors left, [esp+12] = c#
mov eax,[esp+8]
mov ebx,[esp+4]
dec eax
jz fat16_nextsector_cluster
inc ebx
mov [esp+8],eax
mov [esp+4],ebx
clc
ret
fat16_nextsector_cluster:
mov ebx,[esp+12]
test ebx,ebx
jz fat16_nextsector_err
call fat16_getnextcluster
jnc fat16_nextsector_havecluster
fat16_nextsector_err:
stc
ret
fat16_nextsector_havecluster:
mov [esp+12],ebx
call fat16_xlate
xor eax,eax
mov al,[esi+2]
mov [esp+4],ebx
mov [esp+8],eax
clc
ret
fat16_xlate:
push eax
push ecx
test ebx,ebx
mov cl,[esi + 3]
mov eax,[esi + 28]
jz fat16_xlate_root
shl ebx,cl
lea ebx,[ebx+eax]
pop ecx
pop eax
ret
fat16_xlate_root:
xor ebx,ebx
mov bl,[esi+2] ; spc
mov ecx,[esi+16] ; s in root dir
shl ebx,1 ; spc*2
sub eax,ecx ; magic - sroot
lea ebx,[ebx+eax] ; magic - sroot + spc*2 = cluster2 - sroot
pop ecx
pop eax
ret
fat16_getnextcluster:
push eax
push ecx
push edi
mov eax,ebx
shr ebx,8
mov ecx,[esi+20]
and eax,0ffh
cmp ebx,ecx
mov ecx,[esi+24]
lea eax,[eax*2 + offset hd_buffer]
jnb fat16_getnextcluster_fail ; domain error
add ebx,ecx
mov edi,offset hd_buffer
call read_sector_p2
xor ebx,ebx
mov bx,[eax]
mov eax,ebx
or eax,0fh
cmp eax,0ffffh
jz fat16_getnextcluster_fail ; prob last cluster
test ebx,ebx
jz fat16_getnextcluster_fail ; actual error in file system
;success
clc
pop edi
pop ecx
pop eax
ret
fat16_getnextcluster_fail:
stc
pop edi
pop ecx
pop eax
ret
fat16_setup:
; esi = partition table
; eax = partition number
; *preserve these*
; bl = partition type, discardable
; returns to different location on error
push eax
xor ebx,ebx
mov edi,offset hd_buffer
call read_sector_p
jc fat16_setup_err ; can't read first sector
mov dx,[edi+01feh]
mov ebx,[edi+020h]
mov ecx,[esi+12]
cmp dx,0aa55h ; slow is ok here
jnz fat16_setup_err ; not a valid first sector
mov dx,[edi+0bh]
cmp ebx,ecx
ja fat16_setup_err ; partition doesn't fit
mov bl,[edi+0dh]
xor cl,cl
cmp dx,512
jnz fat16_setup_err ; !512 bytes / sector
test bl,1
mov [esi+2],bl
jnz fat16_setup_overspc1
fat16_setup_spc1:
shr bl,1
inc cl
test bl,1
jz fat16_setup_spc1
fat16_setup_overspc1:
test bl,0FEh
jnz fat16_setup_err ; not an even power of 2. go away.
mov [esi+3],cl
xor ebx,ebx
mov bx,[edi+011h]
shr ebx,4 ; ebx = (ebx * 32) / 512 = (ebx << 5) >> 9 = ebx >> 4
mov [esi+16],ebx
xor eax,eax
mov ax,[edi+016h] ; spf
xor ecx,ecx
mov cl,[edi+10h] ; #f
mov [esi + 20],eax
mul ecx
mov [esi + 4],cl
mov cx,[edi+0Eh] ; #reserved
lea eax,[eax+ecx] ; #f*spf + #res
IFDEF debugfs
call print_hex_32
ENDIF
mov [esi+24],ecx
mov ecx,[esi+16] ; s in root dir
xor ebx,ebx
mov bl,[esi+2] ; spc
lea eax,[eax+ecx] ; #f*spf + #res + rootdirs
shl ebx,1 ; spc * 2
sub eax,ebx ; #f*spf + #res + rootdirs - (spc * 2)
mov [esi+28],eax ; magic_number
IFDEF debugfs
call print_hex_32
sub eax,[esi+16]
call print_hex_32
mov eax,[esi+16]
call print_hex_32
xor eax,eax
mov al,[esi+2]
call print_hex_32
ENDIF
pop eax
jmp fs_setup_partition_next
fat16_setup_err:
pop eax
jmp fs_setup_invalid_partition
Download this file.
[ Return to Browse Source Page ]
Copyright 2000, Ed Pizzi