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