;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; FAT12.INC ;; ;; (C) 2005 Mario79, License: GPL ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; n_sector dd 0 ; temporary save for sector value flp_status dd 0 clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write path_pointer_flp dd 0 pointer_file_name_flp dd 0 save_root_flag db 0 save_flag db 0 root_read db 0 ; 0-necessary to load root, 1-not to load root flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat flp_number db 0 ; 1- Floppy A, 2-Floppy B old_track db 0 ; old value track flp_label rb 15 ; Label and ID of inserted floppy disk reserve_flp: cli cmp [flp_status],0 je reserve_flp_ok sti call change_task jmp reserve_flp reserve_flp_ok: push eax mov eax,[0x3000] shl eax,5 mov eax,[eax+0x3000+4] mov [flp_status],eax pop eax sti ret floppy_free_space: ;--------------------------------------------- ; ; returns free space in edi ; ;--------------------------------------------- push eax ebx ecx call read_flp_fat cmp [FDC_Status],0 jne fdc_status_error_2 mov eax,0x282000 xor edi,edi mov ecx,2847 ;1448000/512 rdfs1_1: mov ebx,[eax] and ebx,4095 jne rdfs2_1 add edi,512 rdfs2_1: add eax,2 loop rdfs1_1 fdc_status_error_2: pop ecx ebx eax ret floppy_fileread: ;---------------------------------------------------------------- ; ; fileread - sys floppy ; ; eax points to filename 11 chars - for root directory ; ebx first wanted block ; 1+ ; if 0 then set to 1 ; ecx number of blocks to read ; 1+ ; if 0 then set to 1 ; edx mem location to return data ; esi length of filename 12*X ; edi pointer to path /fd/1/...... - for all files in nested directories ; ; ret ebx = size or 0xffffffff file not found ; eax = 0 ok read or other = errormsg ; 10 = access denied ;-------------------------------------------------------------- mov [save_flag],0 mov [path_pointer_flp],edi cmp esi,0 ; return ramdisk root jne fr_noroot_1 cmp ebx,224/16 jbe fr_do_1 mov eax,5 mov ebx,0 mov [flp_status],0 ret fr_do_1: push ebx ecx edx call read_flp_root pop edx ecx ebx cmp [FDC_Status],0 jne fdc_status_error_1 mov edi,edx dec ebx shl ebx,9 mov esi,0x8000 add esi,ebx shl ecx,9 cld rep movsb mov eax,0 ; ok read mov ebx,0 mov [flp_status],0 ret fdc_status_error_1: mov [flp_status],0 mov eax,10 mov ebx,-1 ret fr_noroot_1: sub esp,32 call expand_filename frfloppy_1: cmp ebx,0 jne frfl5_1 mov ebx,1 frfl5_1: cmp ecx,0 jne frfl6_1 mov ecx,1 frfl6_1: dec ebx push eax push eax ebx ecx edx esi edi call read_flp_fat cmp [FDC_Status],0 jne fdc_status_error_3_1 mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор call SeekTrack mov dh,14 l.20_1: call ReadSectWithRetr cmp [FDC_Status],0 jne fdc_status_error_3_1 mov dl,16 mov edi,0xD000 inc [FDD_Sector] l.21_1: mov esi,eax ;Name of file we want mov ecx,11 cld rep cmpsb ;Found the file? je fifound_1 ;Yes add ecx,21 add edi, ecx ;Advance to next entry dec dl cmp dl,0 jne l.21_1 dec dh cmp dh,0 jne l.20_1 fdc_status_error_3: mov eax,5 ; file not found ? mov ebx,-1 add esp,32+28 mov [flp_status],0 ret fdc_status_error_3_2: cmp [FDC_Status],0 je fdc_status_error_3 fdc_status_error_3_1: add esp,32+28 jmp fdc_status_error_1 fifound_1: mov eax,[path_pointer_flp] cmp [eax+36],byte 0 je fifound_2 add edi,0xf mov eax,[edi] and eax,65535 mov ebx,[path_pointer_flp] add ebx,36 call get_cluster_of_a_path_flp jc fdc_status_error_3_2 mov ebx,[ebx-11+28] ;file size mov [esp+20],ebx mov [esp+24],ebx jmp fifound_3 fifound_2: mov ebx,[edi-11+28] ;file size mov [esp+20],ebx mov [esp+24],ebx add edi,0xf mov eax,[edi] fifound_3: and eax,65535 mov [n_sector],eax ;eax=cluster frnew_1: add eax,31 ;bootsector+2*fat+filenames cmp [esp+16],dword 0 ; wanted cluster ? jne frfl7_1 call read_chs_sector cmp [FDC_Status],0 jne fdc_status_error_5 mov edi,[esp+8] call give_back_application_data_1 add [esp+8],dword 512 dec dword [esp+12] ; last wanted cluster ? cmp [esp+12],dword 0 je frnoread_1 jmp frfl8_1 frfl7_1: dec dword [esp+16] frfl8_1: mov edi,[n_sector] shl edi,1 ;find next cluster from FAT add edi,0x282000 mov eax,[edi] and eax,4095 mov edi,eax mov [n_sector],edi cmp edi,4095 ;eof - cluster jz frnoread2_1 cmp [esp+24],dword 512 ;eof - size jb frnoread_1 sub [esp+24],dword 512 jmp frnew_1 read_chs_sector: call calculate_chs call ReadSectWithRetr ret frnoread2_1: cmp [esp+16],dword 0 ; eof without read ? je frnoread_1 mov [fdc_irq_func],fdc_null pop edi esi edx ecx add esp,4 pop ebx ; ebx <- eax : size of file add esp,36 mov eax,6 ; end of file mov [flp_status],0 ret frnoread_1: pop edi esi edx ecx add esp,4 pop ebx ; ebx <- eax : size of file add esp,36 mov eax,0 mov [flp_status],0 ret fdc_status_error_5: pop edi esi edx ecx add esp,4 pop ebx ; ebx <- eax : size of file add esp,36 jmp fdc_status_error_1 read_flp_root: pusha call check_label cmp [FDC_Status],0 jne unnecessary_root_read cmp [root_read],1 je unnecessary_root_read mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор mov edi,0x8000 call SeekTrack read_flp_root_1: call ReadSectWithRetr cmp [FDC_Status],0 jne unnecessary_root_read push edi call give_back_application_data_1 pop edi add edi,512 inc [FDD_Sector] cmp [FDD_Sector],16 jne read_flp_root_1 mov [root_read],1 unnecessary_root_read: popa ret read_flp_fat: pusha call check_label cmp [FDC_Status],0 jne unnecessary_flp_fat cmp [flp_fat],1 je unnecessary_flp_fat mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],0 ; Сторона mov [FDD_Sector],2 ; Сектор mov edi,0x8000 call SeekTrack read_flp_fat_1: call ReadSectWithRetr cmp [FDC_Status],0 jne unnecessary_flp_fat push edi call give_back_application_data_1 pop edi add edi,512 inc [FDD_Sector] cmp [FDD_Sector],19 jne read_flp_fat_1 mov [FDD_Sector],1 mov [FDD_Head],1 call ReadSectWithRetr cmp [FDC_Status],0 jne unnecessary_flp_fat call give_back_application_data_1 call calculatefatchain_flp mov [root_read],0 mov [flp_fat],1 unnecessary_flp_fat: popa ret calculatefatchain_flp: pushad mov esi,0x8000 mov edi,0x282000 fcnew_1: mov eax,dword [esi] mov ebx,dword [esi+4] mov ecx,dword [esi+8] mov edx,ecx shr edx,4 ;8 ok shr dx,4 ;7 ok xor ch,ch shld ecx,ebx,20 ;6 ok shr cx,4 ;5 ok shld ebx,eax,12 and ebx,0x0fffffff ;4 ok shr bx,4 ;3 ok shl eax,4 and eax,0x0fffffff ;2 ok shr ax,4 ;1 ok mov dword [edi],eax add edi,4 mov dword [edi],ebx add edi,4 mov dword [edi],ecx add edi,4 mov dword [edi],edx add edi,4 add esi,12 cmp edi,0x282000+2856*2 ;2849 clusters jnz fcnew_1 popad ret check_label: pushad mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],0 ; Сторона mov [FDD_Sector],1 ; Сектор call SetUserInterrupts call FDDMotorON call RecalibrateFDD cmp [FDC_Status],0 jne fdc_status_error call SeekTrack cmp [FDC_Status],0 jne fdc_status_error call ReadSectWithRetr cmp [FDC_Status],0 jne fdc_status_error mov esi,flp_label mov edi,0xD000+39 mov ecx,15 cld rep cmpsb je same_label mov [root_read],0 mov [flp_fat],0 same_label: mov esi,0xD000+39 mov edi,flp_label mov ecx,15 cld rep movsb popad ret fdc_status_error: popad ret save_flp_root: pusha call check_label cmp [FDC_Status],0 jne unnecessary_root_save cmp [root_read],0 je unnecessary_root_save mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор mov esi,0x8000 call SeekTrack save_flp_root_1: push esi call take_data_from_application_1 pop esi add esi,512 call WriteSectWithRetr cmp [FDC_Status],0 jne unnecessary_root_save inc [FDD_Sector] cmp [FDD_Sector],16 jne save_flp_root_1 unnecessary_root_save: mov [fdc_irq_func],fdc_null popa ret save_flp_fat: pusha call check_label cmp [FDC_Status],0 jne unnecessary_flp_fat_save cmp [flp_fat],0 je unnecessary_flp_fat_save call restorefatchain_flp mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],0 ; Сторона mov [FDD_Sector],2 ; Сектор mov esi,0x8000 call SeekTrack save_flp_fat_1: push esi call take_data_from_application_1 pop esi add esi,512 call WriteSectWithRetr cmp [FDC_Status],0 jne unnecessary_flp_fat_save inc [FDD_Sector] cmp [FDD_Sector],19 jne save_flp_fat_1 mov [FDD_Sector],1 mov [FDD_Head],1 call take_data_from_application_1 call WriteSectWithRetr cmp [FDC_Status],0 jne unnecessary_flp_fat_save mov [root_read],0 unnecessary_flp_fat_save: mov [fdc_irq_func],fdc_null popa ret restorefatchain_flp: ; restore fat chain pushad mov esi,0x282000 mov edi,0x8000 fcnew2_1: mov eax,dword [esi] mov ebx,dword [esi+4] shl ax,4 shl eax,4 shl bx,4 shr ebx,4 shrd eax,ebx,8 shr ebx,8 mov dword [edi],eax add edi,4 mov word [edi],bx add edi,2 add esi,8 cmp edi,0x8000+0x1200 ;4274 bytes - all used FAT jb fcnew2_1 mov esi,0x8000 ; duplicate fat chain mov edi,0x8000+0x1200 mov ecx,0x1200/4 cld rep movsd popad ret floppy_filedelete: ;-------------------------------------------- ; ; filedelete - sys floppy ; in: ; eax - filename 11 chars - for root directory ; edi pointer to path /fd/1/...... - for all files in nested directories ; ; out: ; eax - 0 = successful, 1 = file not found, 10 = access denied ; ;-------------------------------------------- mov [path_pointer_flp],edi mov [save_flag],0 mov ebp,1 ; file not found as default filedelete_newtry_1: sub esp,32 call expand_filename push eax ebx ecx edx esi edi call read_flp_fat cmp [FDC_Status],0 jne frnoreadd_1 mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор call SeekTrack mov dh,14 l.20_2: call ReadSectWithRetr cmp [FDC_Status],0 jne fdc_status_error_4 mov dl,16 mov edi,0xD000 inc [FDD_Sector] l.21_2: mov esi,eax ;Name of file we want mov ecx,11 cld rep cmpsb ;Found the file? je fifoundd_1 ;Yes add ecx,21 add edi, ecx ;Advance to next entry dec dl cmp dl,0 jne l.21_2 dec dh cmp dh,0 jne l.20_2 jmp frnoreadd_1 fdc_status_error_4: pop edi esi edx ecx ebx eax add esp,32 jmp fdc_status_error_1 fifoundd_1: mov eax,[path_pointer_flp] cmp [eax+36],byte 0 je fifoundd_2 add edi,0xf mov eax,[edi] and eax,65535 mov ebx,[path_pointer_flp] add ebx,36 call get_cluster_of_a_path_flp jc frnoreadd_1_1 mov edi,ebx add edi,11 jmp fifoundd_2_1 fifoundd_2: dec [FDD_Sector] fifoundd_2_1: mov [edi-11],byte 0xE5 ;mark filename deleted add edi,0xf mov eax,[edi] and eax,65535 mov edi,eax ;edi = cluster frnewd_1: shl edi,1 ;find next cluster from FAT add edi,0x282000 mov eax,[edi] mov [edi],word 0x0 ;clear fat chain cluster and eax,4095 mov edi,eax cmp edi,dword 4095 ;last cluster ? jz frnoreadd2_1 jmp frnewd_1 frnoreadd2_1: call WriteSectWithRetr cmp [FDC_Status],0 jne fdc_status_error_4 call save_flp_fat cmp [FDC_Status],0 jne fdc_status_error_4 ; pop edi esi edx ecx ebx eax ; add esp,32 mov ebp,0 ; file found ; jmp filedelete_newtry_1 jmp frnoreadd_1 frnoreadd_1_1: cmp [FDC_Status],0 jne fdc_status_error_4 frnoreadd_1: pop edi esi edx ecx ebx eax add esp,32 mov eax,ebp ret floppy_filesave: ;---------------------------------------------------------- ; ; filesave - sys floppy ; ; eax ; pointer to file name 11 chars - for root directory ; ebx ; buffer ; ecx ; count to write in bytes ; edx ; 0 create new , 1 append ; edi pointer to path /fd/1/...... - for all files in nested directories ; ; output : eax = 0 - ok ; 5 - file not found / directory not found ; 8 - disk full ; 10 - access denied ;----------------------------------------------------------- mov [path_pointer_flp],edi sub esp,32 call expand_filename cmp edx,0 jnz fsdel_1 pusha call floppy_filedelete cmp [FDC_Status],0 jne fdc_status_error_6 popa mov [save_flag],1 fsdel_1: call floppy_free_space cmp [FDC_Status],0 jne fdc_status_error_6 cmp ecx,edi jb rd_do_save_1 add esp,32 mov eax,8 ; not enough free space mov [flp_status],0 ret fdc_status_error_6: popa add esp,32 jmp fdc_status_error_1 rd_do_save_1: push eax ebx ecx edx esi edi call read_flp_fat cmp [FDC_Status],0 jne fdc_status_error_7 push eax mov eax,[path_pointer_flp] cmp [eax+36],byte 0 jne fifoundds_2 pop eax mov [save_root_flag],1 call read_flp_root cmp [FDC_Status],0 jne fdc_status_error_7 mov edi,0x8000 ;Point at directory mov edx,224 +1 ; find an empty spot for filename in the root dir l20ds_1: sub edx,1 cmp edx,0 jnz l21ds_1 jmp frnoreadds_1 l21ds_1: cmp [edi],byte 0xE5 jz fifoundds_1 cmp [edi],byte 0x0 jz fifoundds_1 add edi,32 ; Advance to next entry jmp l20ds_1 fifoundds_2: pop eax mov [save_root_flag],0 mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор call SeekTrack mov dh,14 l.20_3: call ReadSectWithRetr cmp [FDC_Status],0 jne fdc_status_error_7 mov dl,16 mov edi,0xD000 inc [FDD_Sector] l.21_3: mov esi,eax ;Name of file we want mov ecx,11 cld rep cmpsb ;Found the file? je fifoundds_3 ;Yes add ecx,21 add edi, ecx ;Advance to next entry dec dl cmp dl,0 jne l.21_3 dec dh cmp dh,0 jne l.20_3 fdc_status_error_8: pop edi esi edx ecx ebx eax mov eax,5 ; file not found ? mov ebx,-1 add esp,32 mov [flp_status],0 ret fifoundds_3: add edi,0xf mov eax,[edi] and eax,65535 mov ebx,[path_pointer_flp] add ebx,36 call get_cluster_of_a_path_flp jc fdc_status_error_7_1 found_directory_for_writing_flp: call analyze_directory_to_write_flp jc fdc_status_error_7_1 mov edi,ebx fifoundds_1: push edi ; move the filename to root dir mov esi,[esp+4+20] cmp [save_root_flag],0 jne fifoundds_4 mov esi,[pointer_file_name_flp] fifoundds_4: mov ecx,11 cld rep movsb pop edi mov edx,edi add edx,11+0xf ; edx <- cluster save position mov ebx,[esp+12] ; save file size mov [edi+28],ebx mov [edi+11],byte 0x20 ; attribute call get_date_for_file ; from FAT32.INC mov [edi+24],ax ; date mov [edi+18],ax ; date call get_time_for_file ; from FAT32.INC mov [edi+22],ax ; time xor ax,ax mov [edi+20],ax mov ebx,1 ; first cluster cmp [save_root_flag],0 jne frnewds_1 call frnewds_2 pusha call WriteSectWithRetr popa cmp [FDC_Status],0 jne fdc_status_error_7 jmp frnewds_3 frnewds_1: call frnewds_2 frnewds_3: pusha ; move save to floppy cluster add ebx,31 mov eax,ebx mov esi,[esp+32+16] call take_data_from_application_1 call save_chs_sector cmp [FDC_Status],0 jne fdc_status_error_7 popa mov eax,[esp+12] cmp eax,512 jb flnsa_1 sub eax,512 mov [esp+12],eax mov eax,[esp+16] add eax,512 mov [esp+16],eax jmp frnewds_1 frnewds_2: add ebx,1 mov edi,ebx ; find free cluster in FAT shl edi,1 add edi,0x282000 mov eax,[edi] and eax,4095 cmp eax,0x0 jnz frnewds_2 mov [edx],bx ; save next cluster pos. to prev cl. mov edx,edi ; next save pos abs mem add ret flnsa_1: mov [edi],word 4095 ; mark end of file - last cluster cmp [save_root_flag],1 jne flnsa_2 call save_flp_root cmp [FDC_Status],0 jne fdc_status_error_7 flnsa_2: call save_flp_fat cmp [FDC_Status],0 jne fdc_status_error_7 frnoreadds_1: pop edi esi edx ecx ebx eax add esp,32 mov eax,0 mov [flp_status],0 ret fdc_status_error_7_1: cmp [FDC_Status],0 je fdc_status_error_8 fdc_status_error_7: pop edi esi edx ecx ebx eax add esp,32 jmp fdc_status_error_1 save_chs_sector: call calculate_chs call WriteSectWithRetr ret calculate_chs: mov bl,[FDD_Track] mov [old_track],bl mov ebx,18 xor edx,edx div ebx inc edx mov [FDD_Sector],dl xor edx,edx mov ebx,2 div ebx mov [FDD_Track],al mov [FDD_Head],0 cmp edx,0 je no_head_2 inc [FDD_Head] no_head_2: mov dl,[old_track] cmp dl,[FDD_Track] je no_seek_track_1 call SeekTrack no_seek_track_1: ret get_cluster_of_a_path_flp: ;--------------------------------------------------------- ; 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 edx mov edx,ebx search_end_of_path_flp: cmp [save_flag],0 jne search_end_of_path_flp_1 cmp byte [edx],0 je found_end_of_path_flp jmp search_end_of_path_flp_2 search_end_of_path_flp_1: cmp byte [edx+12],0 je found_end_of_path_flp search_end_of_path_flp_2: inc edx ; '/' call analyze_directory_flp jc directory_not_found_flp mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field mov ax,[ebx+26] ; read the LOW 16bit cluster field and eax,0xfff ;[fatMASK] add edx,11 ; 8+3 (name+extension) jmp search_end_of_path_flp found_end_of_path_flp: inc edx mov [pointer_file_name_flp],edx pop edx clc ; no errors ret directory_not_found_flp: pop edx stc ; errors occour ret analyze_directory_flp: ;-------------------------------- ; input : EAX = first cluster of the directory ; EBX = pointer to filename ; output : IF CARRY=0 EAX = sector where th file is found ; EBX = pointer in buffer ; [buffer .. buffer+511] ; ECX,EDX,EDI,EDI not changed ; IF CARRY=1 ;-------------------------------- push ebx ;[esp+16] push ecx push edx push esi push edi adr56_flp: mov [clust_tmp_flp],eax add eax,31 pusha call read_chs_sector popa cmp [FDC_Status],0 jne not_found_file_analyze_flp mov ecx,512/32 mov ebx,0xD000 adr1_analyze_flp: mov esi,edx ;[esp+16] mov edi,ebx cld push ecx mov ecx,11 rep cmpsb pop ecx je found_file_analyze_flp add ebx,32 loop adr1_analyze_flp mov eax,[clust_tmp_flp] shl eax,1 ;find next cluster from FAT add eax,0x282000 mov eax,[eax] and eax,4095 cmp eax,0x0ff8 jb adr56_flp not_found_file_analyze_flp: pop edi pop esi pop edx pop ecx add esp,4 stc ;file not found ret found_file_analyze_flp: pop edi pop esi pop edx pop ecx add esp,4 clc ;file found ret analyze_directory_to_write_flp: ;-------------------------------- ; input : EAX = first cluster of the directory ; output : IF CARRY=0 EAX = sector where the file is found ; EBX = pointer in buffer ; [buffer .. buffer+511] ; ECX,EDX,EDI,EDI not changed ; IF CARRY=1 ;-------------------------------- push ecx push edx push esi adr561: mov [clust_tmp_flp],eax add eax,31 pusha call read_chs_sector popa cmp [FDC_Status],0 jne error_found_file_analyze1 mov ecx,512/32 mov ebx,0xD000 adr1_analyze1: cmp byte [ebx],0x00 je found_file_analyze1 cmp byte [ebx],0xe5 je found_file_analyze1 avanti: add ebx,32 loop adr1_analyze1 mov eax,[clust_tmp_flp] shl eax,1 ;find next cluster from FAT add eax,0x282000 mov eax,[eax] and eax,4095 cmp eax,0x0ff8 jb adr561 call get_free_FAT ;this block of code add a new cluster ;for the directory because the directory ;is full mov [edi],word 0x0fff mov eax,[clust_tmp_flp] shl eax,1 ;find next cluster from FAT add eax,0x282000 sub edi,0x282000 mov [eax],di pusha mov ecx,512/4 xor eax,eax mov edi,0xD000 cld rep stosd popa mov eax,edi add eax,31 pusha call save_chs_sector popa cmp [FDC_Status],0 jne error_found_file_analyze1 mov ebx,0xD000 found_file_analyze1: pop esi pop edx pop ecx clc ;file found ret error_found_file_analyze1: pop esi pop edx pop ecx stc ret get_free_FAT_flp: ;------------------------------------------ ; input : EAX = # cluster for start the searching ; output : EAX = # first cluster found free ;------------------------------------------- push ebx mov ebx,1 check_new_flp: add ebx,1 mov edi,ebx ; find free cluster in FAT shl edi,1 add edi,0x282000 mov eax,[edi] and eax,4095 cmp eax,0x0 jnz check_new_flp pop ebx ret ; \begin{diamond} fd_find_lfn: ; in: esi->name ; out: CF=1 - file not found ; else CF=0 and edi->direntry pusha sub esp, 262*2 ; reserve place for LFN mov ebp, esp push 0 ; for fat_get_name: read ASCII name call read_flp_fat cmp [FDC_Status], 0 jnz .error mov eax, 19 mov dh, 14 .main_loop: .20_1: pusha call read_chs_sector popa cmp [FDC_Status], 0 jnz .error mov edi, 0xD000 inc [FDD_Sector] push eax .21_1: call fat_get_name jc @f call fat_compare_name jz .found @@: add edi, 0x20 cmp edi, 0xD200 jb .21_1 pop eax inc eax dec dh js @f jnz .20_1 .error: add esp, 262*2+4 popa stc ret @@: ; read next sector from FAT mov eax, [(eax-31-1)*2+0x282000] and eax, 0xFFF cmp eax, 0xFF8 jae .error add eax, 31 jmp .main_loop .found: pop eax ; if LFN entry, advance to corresponding short entry cmp byte [edi+11], 0xF jnz .entryfound add edi, 0x20 cmp edi, 0xD200 jb .entryfound dec dh jz .error inc eax call read_chs_sector cmp [FDC_Status], 0 jnz .error mov edi, 0xD000 .entryfound: cmp byte [esi], 0 jz .done test byte [edi+11], 10h ; is a directory? jz .error movzx eax, word [edi+26] add eax, 31 mov dh, 0 jmp .main_loop .done: add esp, 262*2+4+4 push edi popad ret ;---------------------------------------------------------------- ; ; fs_FloppyRead - LFN variant for reading floppy ; ; esi points to filename ; ebx pointer to 64-bit number = first wanted byte, 0+ ; may be ebx=0 - start from first byte ; ecx number of bytes to read, 0+ ; edx mem location to return data ; ; ret ebx = bytes read or 0xffffffff file not found ; eax = 0 ok read or other = errormsg ; ;-------------------------------------------------------------- fs_FloppyRead: call read_flp_fat cmp byte [esi], 0 jnz @f or ebx, -1 mov eax, 10 ; access denied ret @@: push edi call fd_find_lfn jnc .found pop edi or ebx, -1 mov eax, 5 ; file not found ret .found: test ebx, ebx jz .l1 cmp dword [ebx+4], 0 jz @f xor ebx, ebx .reteof: mov eax, 6 ; EOF pop edi ret @@: mov ebx, [ebx] .l1: push ecx edx push 0 mov eax, [edi+28] sub eax, ebx jb .eof cmp eax, ecx jae @f mov ecx, eax mov byte [esp], 6 ; EOF @@: movzx edi, word [edi+26] .new: jecxz .done test edi, edi jz .eof cmp edi, 0xFF8 jae .eof lea eax, [edi+31] pusha call read_chs_sector popa cmp [FDC_Status], 0 jnz .err sub ebx, 512 jae .skip lea eax, [0xD000+ebx+512] neg ebx push ecx cmp ecx, ebx jbe @f mov ecx, ebx @@: mov ebx, edx call memmove add edx, ecx sub [esp], ecx pop ecx xor ebx, ebx .skip: movzx edi, word [edi*2+0x282000] jmp .new .done: mov ebx, edx pop eax edx ecx edi sub ebx, edx ret .eof: mov ebx, edx pop eax edx ecx jmp .reteof .err: mov ebx, edx pop eax edx ecx edi sub ebx, edx mov al, 5 ; may be other error code? ret ;---------------------------------------------------------------- ; ; fs_FloppyReadFolder - LFN variant for reading floppy folders ; ; esi points to filename ; ebx pointer to structure: 32-bit number = first wanted block, 0+ ; & flags (bitfields) ; flags: bit 0: 0=ANSI names, 1=UNICODE names ; ecx number of blocks to read, 0+ ; edx mem location to return data ; ; ret ebx = blocks read or 0xffffffff folder not found ; eax = 0 ok read or other = errormsg ; ;-------------------------------------------------------------- fs_FloppyReadFolder: call read_flp_fat push edi cmp byte [esi], 0 jz .root call fd_find_lfn jnc .found pop edi or ebx, -1 mov eax, ERROR_FILE_NOT_FOUND ret .found: test byte [edi+11], 0x10 ; do not allow read files jnz .found_dir pop edi or ebx, -1 mov eax, ERROR_ACCESS_DENIED ret .found_dir: movzx eax, word [edi+26] add eax, 31 push 0 jmp .doit .root: mov eax, 19 push 14 .doit: push ecx ebp sub esp, 262*2 ; reserve space for LFN mov ebp, esp push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names mov ebx, [ebx] ; init header push eax ecx mov edi, edx mov ecx, 32/4 xor eax, eax rep stosd pop ecx eax mov byte [edx], 1 ; version mov esi, edi ; esi points to BDFE .main_loop: pusha call read_chs_sector popa cmp [FDC_Status], 0 jnz .error mov edi, 0xD000 push eax .l1: call fat_get_name jc .l2 cmp byte [edi+11], 0xF jnz .do_bdfe add edi, 0x20 cmp edi, 0xD200 jb .do_bdfe pop eax inc eax dec byte [esp+262*2+12] jz .done jns @f ; read next sector from FAT mov eax, [(eax-31-1)*2+0x282000] and eax, 0xFFF cmp eax, 0xFF8 jae .done add eax, 31 mov byte [esp+262*2+12], 0 @@: pusha call read_chs_sector popa cmp [FDC_Status], 0 jnz .error mov edi, 0xD000 push eax .do_bdfe: inc dword [edx+8] ; new file found dec ebx jns .l2 dec ecx js .l2 inc dword [edx+4] ; new file block copied call fat_entry_to_bdfe .l2: add edi, 0x20 cmp edi, 0xD200 jb .l1 pop eax inc eax dec byte [esp+262*2+12] jz .done jns @f ; read next sector from FAT mov eax, [(eax-31-1)*2+0x282000] and eax, 0xFFF cmp eax, 0xFF8 jae .done add eax, 31 mov byte [esp+262*2+12], 0 @@: jmp .main_loop .error: add esp, 262*2+4 pop ebp ecx edi edi or ebx, -1 mov eax, ERROR_FILE_NOT_FOUND ret .done: add esp, 262*2+4 pop ebp mov ebx, [edx+4] xor eax, eax dec ecx js @f mov al, ERROR_END_OF_FILE @@: pop ecx edi edi ret ; \end{diamond}