Subversion Repositories Kolibri OS

Rev

Rev 381 | Blame | Last modification | View Log | Download | RSS feed

  1. $Revision: 425 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                                      ;;
  4. ;; FAT12.INC                                                            ;;
  5. ;; (C) 2005 Mario79, License: GPL                                       ;;
  6. ;;                                                                      ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. n_sector    dd 0  ; temporary save for sector value
  10. flp_status  dd 0
  11. clust_tmp_flp dd 0  ; used by analyze_directory and analyze_directory_to_write
  12. path_pointer_flp dd 0
  13. pointer_file_name_flp dd 0
  14. save_root_flag db 0
  15. save_flag   db 0
  16. root_read   db 0  ; 0-necessary to load root, 1-not to load root
  17. flp_fat     db 0  ; 0-necessary to load fat, 1-not to load fat
  18. flp_number  db 0  ; 1- Floppy A, 2-Floppy B
  19. old_track   db 0  ; old value track
  20. flp_label   rb 15 ; Label and ID of inserted floppy disk
  21.  
  22. reserve_flp:
  23.  
  24.     cli
  25.     cmp   [flp_status],0
  26.     je    reserve_flp_ok
  27.  
  28.     sti
  29.     call  change_task
  30.     jmp   reserve_flp
  31.  
  32.   reserve_flp_ok:
  33.  
  34.     push  eax
  35.     mov   eax,[CURRENT_TASK]
  36.     shl   eax,5
  37.     mov   eax,[eax+CURRENT_TASK+TASKDATA.pid]
  38.     mov   [flp_status],eax
  39.     pop   eax
  40.     sti
  41.     ret
  42.  
  43. floppy_free_space:
  44. ;---------------------------------------------
  45. ;
  46. ; returns free space in edi
  47. ;
  48. ;---------------------------------------------
  49.     push   eax ebx ecx
  50.     call   read_flp_fat
  51.     cmp    [FDC_Status],0
  52.     jne    fdc_status_error_2
  53.     mov    eax,0x282004
  54.     xor    edi,edi
  55.     mov    ecx,2847   ;1448000/512
  56. rdfs1_1:
  57.     mov    ebx,[eax]
  58.     and    ebx,4095
  59.     jne    rdfs2_1
  60.     add    edi,512
  61. rdfs2_1:
  62.     add    eax,2
  63.     loop   rdfs1_1
  64. fdc_status_error_2:
  65.     pop    ecx ebx eax
  66.     ret
  67.  
  68.  
  69.  
  70.  
  71. floppy_fileread:
  72. ;----------------------------------------------------------------
  73. ;
  74. ;  fileread - sys floppy
  75. ;
  76. ;  eax  points to filename 11 chars  - for root directory
  77. ;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
  78. ;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
  79. ;  edx  mem location to return data
  80. ;  esi  length of filename 12*X
  81. ;  edi  pointer to path   /fd/1/......  - for all files in nested directories
  82. ;
  83. ;  ret ebx = size or 0xffffffff file not found
  84. ;      eax = 0 ok read or other = errormsg
  85. ;            10 = access denied
  86. ;--------------------------------------------------------------
  87.  
  88.     mov    [save_flag],0
  89.     mov    [path_pointer_flp],edi
  90.     cmp    esi,0           ; return ramdisk root
  91.     jne    fr_noroot_1
  92.     cmp    ebx,224/16
  93.     jbe    fr_do_1
  94.     mov    eax,5
  95.     mov    ebx,0
  96.     mov   [flp_status],0
  97.     ret
  98.  
  99. fr_do_1:
  100.     push ebx ecx edx
  101.     call  read_flp_root
  102.     pop edx ecx ebx
  103.     cmp    [FDC_Status],0
  104.     jne    fdc_status_error_1
  105.     mov    edi,edx
  106.     dec    ebx
  107.     shl    ebx,9
  108.     mov    esi,FLOPPY_BUFF
  109.     add    esi,ebx
  110.     shl    ecx,9
  111.     cld
  112.     rep    movsb
  113.     mov    eax,0 ; ok read
  114.     mov    ebx,0
  115.     mov   [flp_status],0
  116.     ret
  117. fdc_status_error_1:
  118.     mov   [flp_status],0
  119.     mov    eax,10
  120.     mov    ebx,-1
  121.     ret
  122.  
  123. fr_noroot_1:
  124.     sub    esp,32
  125.     call   expand_filename
  126. frfloppy_1:
  127.     cmp    ebx,0
  128.     jne    frfl5_1
  129.     mov    ebx,1
  130. frfl5_1:
  131.     cmp    ecx,0
  132.     jne    frfl6_1
  133.     mov    ecx,1
  134. frfl6_1:
  135.     dec    ebx
  136.     push   eax
  137.     push   eax ebx ecx edx esi edi
  138.     call   read_flp_fat
  139.     cmp    [FDC_Status],0
  140.     jne    fdc_status_error_3_1
  141.     mov    [FDD_Track],0      ; Öèëèíäð
  142.     mov    [FDD_Head],1      ; Ñòîðîíà
  143.     mov    [FDD_Sector],2      ; Ñåêòîð
  144.     call    SeekTrack
  145.     mov     dh,14
  146. l.20_1:
  147.     call    ReadSectWithRetr
  148.     cmp    [FDC_Status],0
  149.     jne    fdc_status_error_3_1
  150.     mov     dl,16
  151.     mov     edi,FDD_BUFF
  152.     inc     [FDD_Sector]
  153. l.21_1:
  154.     mov    esi,eax            ;Name of file we want
  155.     mov    ecx,11
  156.     cld
  157.     rep    cmpsb            ;Found the file?
  158.     je     fifound_1          ;Yes
  159.     add    ecx,21
  160.     add    edi, ecx         ;Advance to next entry
  161.     dec    dl
  162.     cmp    dl,0
  163.     jne    l.21_1
  164.     dec    dh
  165.     cmp    dh,0
  166.     jne    l.20_1
  167. fdc_status_error_3:
  168.     mov    eax,5            ; file not found ?
  169.     mov    ebx,-1
  170.     add    esp,32+28
  171.     mov   [flp_status],0
  172.     ret
  173. fdc_status_error_3_2:
  174.     cmp    [FDC_Status],0
  175.     je    fdc_status_error_3
  176. fdc_status_error_3_1:
  177.     add    esp,32+28
  178.     jmp    fdc_status_error_1
  179.  
  180. fifound_1:
  181.     mov    eax,[path_pointer_flp]
  182.     cmp    [eax+36],byte 0
  183.     je     fifound_2
  184.     add    edi,0xf
  185.     mov    eax,[edi]
  186.     and    eax,65535
  187.     mov    ebx,[path_pointer_flp]
  188.     add    ebx,36
  189.     call   get_cluster_of_a_path_flp
  190.     jc     fdc_status_error_3_2
  191.     mov    ebx,[ebx-11+28]        ;file size
  192.     mov    [esp+20],ebx
  193.     mov    [esp+24],ebx
  194.     jmp     fifound_3
  195. fifound_2:
  196.     mov    ebx,[edi-11+28]        ;file size
  197.     mov    [esp+20],ebx
  198.     mov    [esp+24],ebx
  199.     add    edi,0xf
  200.     mov    eax,[edi]
  201. fifound_3:
  202.     and    eax,65535
  203.     mov    [n_sector],eax            ;eax=cluster
  204. frnew_1:
  205.     add    eax,31            ;bootsector+2*fat+filenames
  206.     cmp    [esp+16],dword 0     ; wanted cluster ?
  207.     jne    frfl7_1
  208.     call   read_chs_sector
  209.     cmp    [FDC_Status],0
  210.     jne    fdc_status_error_5
  211.     mov    edi,[esp+8]
  212.     call    give_back_application_data_1
  213.     add    [esp+8],dword 512
  214.     dec    dword [esp+12]        ; last wanted cluster ?
  215.     cmp    [esp+12],dword 0
  216.     je     frnoread_1
  217.     jmp    frfl8_1
  218. frfl7_1:
  219.     dec    dword [esp+16]
  220. frfl8_1:
  221.     mov    edi,[n_sector]
  222.     shl    edi,1            ;find next cluster from FAT
  223.     add    edi,FLOPPY_FAT
  224.     mov    eax,[edi]
  225.     and    eax,4095
  226.     mov    edi,eax
  227.     mov    [n_sector],edi
  228.     cmp    edi,4095         ;eof  - cluster
  229.     jz     frnoread2_1
  230.     cmp    [esp+24],dword 512    ;eof  - size
  231.     jb     frnoread_1
  232.     sub    [esp+24],dword 512
  233.     jmp    frnew_1
  234.  
  235. read_chs_sector:
  236.     call    calculate_chs
  237.     call    ReadSectWithRetr
  238.     ret
  239.  
  240. frnoread2_1:
  241.     cmp    [esp+16],dword 0     ; eof without read ?
  242.     je     frnoread_1
  243.     mov    [fdc_irq_func],fdc_null
  244.     pop    edi esi edx ecx
  245.     add    esp,4
  246.     pop    ebx     ; ebx <- eax : size of file
  247.     add    esp,36
  248.     mov    eax,6   ; end of file
  249.     mov    [flp_status],0
  250.     ret
  251.  
  252. frnoread_1:
  253.     pop    edi esi edx ecx
  254.     add    esp,4
  255.     pop    ebx     ; ebx <- eax : size of file
  256.     add    esp,36
  257.     mov    eax,0
  258.     mov    [flp_status],0
  259.     ret
  260.  
  261. fdc_status_error_5:
  262.     pop    edi esi edx ecx
  263.     add    esp,4
  264.     pop    ebx     ; ebx <- eax : size of file
  265.     add    esp,36
  266.     jmp    fdc_status_error_1
  267.  
  268. read_flp_root:
  269.     pusha
  270.     call  check_label
  271.     cmp    [FDC_Status],0
  272.     jne    unnecessary_root_read
  273.     cmp   [root_read],1
  274.     je    unnecessary_root_read
  275.     mov    [FDD_Track],0      ; Öèëèíäð
  276.     mov    [FDD_Head],1      ; Ñòîðîíà
  277.     mov    [FDD_Sector],2      ; Ñåêòîð
  278.     mov    edi,FLOPPY_BUFF
  279.     call   SeekTrack
  280. read_flp_root_1:
  281.     call   ReadSectWithRetr
  282.     cmp    [FDC_Status],0
  283.     jne    unnecessary_root_read
  284.     push   edi
  285.     call   give_back_application_data_1
  286.     pop    edi
  287.     add    edi,512
  288.     inc    [FDD_Sector]
  289.     cmp    [FDD_Sector],16
  290.     jne    read_flp_root_1
  291.     mov    [root_read],1
  292. unnecessary_root_read:
  293.     popa
  294.     ret
  295.  
  296.  
  297. read_flp_fat:
  298.     pusha
  299.     call  check_label
  300.     cmp    [FDC_Status],0
  301.     jne    unnecessary_flp_fat
  302.     cmp   [flp_fat],1
  303.     je    unnecessary_flp_fat
  304.     mov    [FDD_Track],0      ; Öèëèíäð
  305.     mov    [FDD_Head],0      ; Ñòîðîíà
  306.     mov    [FDD_Sector],2      ; Ñåêòîð
  307.     mov    edi,FLOPPY_BUFF
  308.     call   SeekTrack
  309. read_flp_fat_1:
  310.     call   ReadSectWithRetr
  311.     cmp    [FDC_Status],0
  312.     jne    unnecessary_flp_fat
  313.     push   edi
  314.     call   give_back_application_data_1
  315.     pop    edi
  316.     add    edi,512
  317.     inc    [FDD_Sector]
  318.     cmp    [FDD_Sector],19
  319.     jne    read_flp_fat_1
  320.     mov    [FDD_Sector],1
  321.     mov    [FDD_Head],1
  322.     call   ReadSectWithRetr
  323.     cmp    [FDC_Status],0
  324.     jne    unnecessary_flp_fat
  325.     call   give_back_application_data_1
  326.     call   calculatefatchain_flp
  327.     mov    [root_read],0
  328.     mov    [flp_fat],1
  329. unnecessary_flp_fat:
  330.     popa
  331.     ret
  332.  
  333. calculatefatchain_flp:
  334.    pushad
  335.  
  336.    mov  esi,FLOPPY_BUFF
  337.    mov  edi,FLOPPY_FAT
  338.  
  339.  fcnew_1:
  340.    mov  eax,dword [esi]
  341.    mov  ebx,dword [esi+4]
  342.    mov  ecx,dword [esi+8]
  343.    mov  edx,ecx
  344.    shr  edx,4   ;8 ok
  345.    shr  dx,4    ;7 ok
  346.    xor  ch,ch
  347.    shld ecx,ebx,20 ;6 ok
  348.    shr  cx,4     ;5 ok
  349.    shld ebx,eax,12
  350.    and  ebx,0x0fffffff  ;4 ok
  351.    shr  bx,4    ;3 ok
  352.    shl  eax,4
  353.    and  eax,0x0fffffff  ;2 ok
  354.    shr  ax,4  ;1 ok
  355.    mov dword [edi],eax
  356.    add  edi,4
  357.    mov dword [edi],ebx
  358.    add  edi,4
  359.    mov dword [edi],ecx
  360.    add  edi,4
  361.    mov dword [edi],edx
  362.    add  edi,4
  363.    add  esi,12
  364.  
  365.    cmp  edi,FLOPPY_FAT+2856*2   ;2849 clusters
  366.    jnz  fcnew_1
  367.  
  368.    popad
  369.    ret
  370.  
  371. check_label:
  372.     pushad
  373.     mov    [FDD_Track],0      ; Öèëèíäð
  374.     mov    [FDD_Head],0      ; Ñòîðîíà
  375.     mov    [FDD_Sector],1      ; Ñåêòîð
  376.     call   SetUserInterrupts
  377.     call   FDDMotorON
  378.     call   RecalibrateFDD
  379.     cmp    [FDC_Status],0
  380.     jne    fdc_status_error
  381.     call   SeekTrack
  382.     cmp    [FDC_Status],0
  383.     jne    fdc_status_error
  384.     call   ReadSectWithRetr
  385.     cmp    [FDC_Status],0
  386.     jne    fdc_status_error
  387.     mov    esi,flp_label
  388.     mov    edi,FDD_BUFF+39
  389.     mov    ecx,15
  390.     cld
  391.     rep    cmpsb
  392.     je     same_label
  393.     mov    [root_read],0
  394.     mov    [flp_fat],0
  395. same_label:
  396.     mov    esi,FDD_BUFF+39
  397.     mov    edi,flp_label
  398.     mov    ecx,15
  399.     cld
  400.     rep    movsb
  401.     popad
  402.     ret
  403. fdc_status_error:
  404.     popad
  405.     ret
  406.  
  407. save_flp_root:
  408.     pusha
  409.     call  check_label
  410.     cmp    [FDC_Status],0
  411.     jne    unnecessary_root_save
  412.     cmp   [root_read],0
  413.     je    unnecessary_root_save
  414.     mov    [FDD_Track],0      ; Öèëèíäð
  415.     mov    [FDD_Head],1      ; Ñòîðîíà
  416.     mov    [FDD_Sector],2      ; Ñåêòîð
  417.     mov    esi,FLOPPY_BUFF
  418.     call   SeekTrack
  419. save_flp_root_1:
  420.     push   esi
  421.     call   take_data_from_application_1
  422.     pop    esi
  423.     add    esi,512
  424.     call   WriteSectWithRetr
  425.     cmp    [FDC_Status],0
  426.     jne    unnecessary_root_save
  427.     inc    [FDD_Sector]
  428.     cmp    [FDD_Sector],16
  429.     jne    save_flp_root_1
  430. unnecessary_root_save:
  431.     mov    [fdc_irq_func],fdc_null
  432.     popa
  433.     ret
  434.  
  435. save_flp_fat:
  436.     pusha
  437.     call  check_label
  438.     cmp    [FDC_Status],0
  439.     jne    unnecessary_flp_fat_save
  440.     cmp   [flp_fat],0
  441.     je    unnecessary_flp_fat_save
  442.     call   restorefatchain_flp
  443.     mov    [FDD_Track],0      ; Öèëèíäð
  444.     mov    [FDD_Head],0      ; Ñòîðîíà
  445.     mov    [FDD_Sector],2      ; Ñåêòîð
  446.     mov    esi,FLOPPY_BUFF
  447.     call   SeekTrack
  448. save_flp_fat_1:
  449.     push   esi
  450.     call   take_data_from_application_1
  451.     pop    esi
  452.     add    esi,512
  453.     call   WriteSectWithRetr
  454.     cmp    [FDC_Status],0
  455.     jne    unnecessary_flp_fat_save
  456.     inc    [FDD_Sector]
  457.     cmp    [FDD_Sector],19
  458.     jne    save_flp_fat_1
  459.     mov    [FDD_Sector],1
  460.     mov    [FDD_Head],1
  461.     call   take_data_from_application_1
  462.     call   WriteSectWithRetr
  463.     cmp    [FDC_Status],0
  464.     jne    unnecessary_flp_fat_save
  465.     mov    [root_read],0
  466. unnecessary_flp_fat_save:
  467.     mov    [fdc_irq_func],fdc_null
  468.     popa
  469.     ret
  470.  
  471.  
  472. restorefatchain_flp:   ; restore fat chain
  473.    pushad
  474.  
  475.    mov  esi,FLOPPY_FAT
  476.    mov  edi,FLOPPY_BUFF
  477.  
  478.   fcnew2_1:
  479.    mov  eax,dword [esi]
  480.    mov  ebx,dword [esi+4]
  481.    shl  ax,4
  482.    shl  eax,4
  483.    shl  bx,4
  484.    shr  ebx,4
  485.    shrd eax,ebx,8
  486.    shr  ebx,8
  487.    mov dword [edi],eax
  488.    add  edi,4
  489.    mov word [edi],bx
  490.    add  edi,2
  491.    add  esi,8
  492.  
  493.    cmp  edi,FLOPPY_BUFF+0x1200     ;4274 bytes - all used FAT
  494.    jb   fcnew2_1
  495.  
  496.    mov  esi,FLOPPY_BUFF           ; duplicate fat chain
  497.    mov  edi,FLOPPY_BUFF+0x1200
  498.    mov  ecx,0x1200/4
  499.    cld
  500.    rep  movsd
  501.  
  502.    popad
  503.    ret
  504.  
  505.  
  506. floppy_filedelete:
  507. ;--------------------------------------------
  508. ;
  509. ; filedelete - sys floppy
  510. ; in:
  511. ; eax - filename 11 chars - for root directory
  512. ; edi  pointer to path   /fd/1/...... - for all files in nested directories
  513. ;
  514. ; out:
  515. ; eax - 0 = successful, 1 = file not found, 10 = access denied
  516. ;
  517. ;--------------------------------------------
  518.     mov    [path_pointer_flp],edi
  519.     mov    [save_flag],0
  520.     mov    ebp,1  ; file not found as default
  521. filedelete_newtry_1:
  522.     sub    esp,32
  523.     call   expand_filename
  524.     push   eax ebx ecx edx esi edi
  525.     call   read_flp_fat
  526.     cmp    [FDC_Status],0
  527.     jne    frnoreadd_1
  528.     mov    [FDD_Track],0      ; Öèëèíäð
  529.     mov    [FDD_Head],1      ; Ñòîðîíà
  530.     mov    [FDD_Sector],2      ; Ñåêòîð
  531.     call    SeekTrack
  532.     mov     dh,14
  533. l.20_2:
  534.     call    ReadSectWithRetr
  535.     cmp    [FDC_Status],0
  536.     jne    fdc_status_error_4
  537.     mov     dl,16
  538.     mov     edi,FDD_BUFF
  539.     inc     [FDD_Sector]
  540. l.21_2:
  541.     mov    esi,eax            ;Name of file we want
  542.     mov    ecx,11
  543.     cld
  544.     rep    cmpsb            ;Found the file?
  545.     je     fifoundd_1          ;Yes
  546.     add    ecx,21
  547.     add    edi, ecx         ;Advance to next entry
  548.     dec    dl
  549.     jne    l.21_2
  550.     dec    dh
  551.     jne    l.20_2
  552.     jmp    frnoreadd_1
  553.  
  554. fdc_status_error_4:
  555.     pop    edi esi edx ecx ebx eax
  556.     add    esp,32
  557.     jmp    fdc_status_error_1
  558.  
  559. fifoundd_1:
  560.     mov    eax,[path_pointer_flp]
  561.     cmp    [eax+36],byte 0
  562.     je    fifoundd_2
  563.     movzx  eax, word [edi+0xf]
  564.     mov    ebx,[path_pointer_flp]
  565.     add    ebx,36
  566.     call   get_cluster_of_a_path_flp
  567.     jc     frnoreadd_1_1
  568.     mov    edi,ebx
  569.     add    edi,11
  570.     jmp    fifoundd_2_1
  571. fifoundd_2:
  572.     dec    [FDD_Sector]
  573. fifoundd_2_1:
  574.     mov    [edi-11],byte 0xE5    ;mark filename deleted
  575.         movzx   edi, word [edi+0xf] ;edi = cluster
  576. frnewd_1:
  577.     shl    edi,1            ;find next cluster from FAT
  578.     add    edi,FLOPPY_FAT
  579.     mov    eax,[edi]
  580.     mov    [edi],word 0x0        ;clear fat chain cluster
  581.     and    eax,4095
  582.     mov    edi,eax
  583.     cmp    edi,dword 4095        ;last cluster ?
  584.     jz     frnoreadd2_1
  585.     jmp    frnewd_1
  586.  
  587. frnoreadd2_1:
  588.     call   WriteSectWithRetr
  589.     cmp    [FDC_Status],0
  590.     jne    fdc_status_error_4
  591.     call   save_flp_fat
  592.     cmp    [FDC_Status],0
  593.     jne    fdc_status_error_4
  594. ;    pop    edi esi edx ecx ebx eax
  595. ;    add    esp,32
  596.     mov    ebp,0       ; file found
  597. ;    jmp    filedelete_newtry_1
  598.     jmp    frnoreadd_1
  599.  
  600. frnoreadd_1_1:
  601.     cmp    [FDC_Status],0
  602.     jne    fdc_status_error_4
  603. frnoreadd_1:
  604.     pop    edi esi edx ecx ebx eax
  605.     add    esp,32
  606.     mov    eax,ebp
  607.     ret
  608.  
  609. floppy_filesave:
  610. ;----------------------------------------------------------
  611. ;
  612. ; filesave - sys floppy
  613. ;
  614. ; eax      ; pointer to file name 11 chars - for root directory
  615. ; ebx      ; buffer
  616. ; ecx      ; count to write in bytes
  617. ; edx      ; 0 create new , 1 append
  618. ; edi  pointer to path   /fd/1/......  - for all files in nested directories
  619. ;
  620. ; output : eax = 0 - ok
  621. ;                5 - file not found / directory not found
  622. ;                8 - disk full
  623. ;               10 - access denied
  624. ;-----------------------------------------------------------
  625.     mov    [path_pointer_flp],edi
  626.     sub  esp,32
  627.     call expand_filename
  628.     cmp  edx,0
  629.     jnz  fsdel_1
  630.     pusha
  631.     call floppy_filedelete
  632.     cmp    [FDC_Status],0
  633.     jne    fdc_status_error_6
  634.     popa
  635.     mov    [save_flag],1
  636. fsdel_1:
  637.     call   floppy_free_space
  638.     cmp    [FDC_Status],0
  639.     jne    fdc_status_error_6
  640.     cmp    ecx,edi
  641.     jb     rd_do_save_1
  642.     add    esp,32
  643.     mov    eax,8    ; not enough free space
  644.     mov   [flp_status],0
  645.     ret
  646.  
  647. fdc_status_error_6:
  648.     popa
  649.     add    esp,32
  650.     jmp    fdc_status_error_1
  651.  
  652. rd_do_save_1:
  653.     push   eax ebx ecx edx esi edi
  654.     call   read_flp_fat
  655.     cmp    [FDC_Status],0
  656.     jne    fdc_status_error_7
  657.     push   eax
  658.     mov    eax,[path_pointer_flp]
  659.     cmp    [eax+36],byte 0
  660.     jne    fifoundds_2
  661.     pop    eax
  662.     mov    [save_root_flag],1
  663.     call   read_flp_root
  664.     cmp    [FDC_Status],0
  665.     jne    fdc_status_error_7
  666.     mov    edi,FLOPPY_BUFF   ;Point at directory
  667.     mov    edx,224 +1
  668.     ; find an empty spot for filename in the root dir
  669. l20ds_1:
  670.     sub    edx,1
  671.     jz     frnoreadds_1
  672. l21ds_1:
  673.     cmp    [edi],byte 0xE5
  674.     jz     fifoundds_1
  675.     cmp    [edi],byte 0x0
  676.     jz     fifoundds_1
  677.     add    edi,32            ; Advance to next entry
  678.     jmp    l20ds_1
  679.  
  680. fifoundds_2:
  681.     pop    eax
  682.     mov    [save_root_flag],0
  683.     mov    [FDD_Track],0      ; Öèëèíäð
  684.     mov    [FDD_Head],1       ; Ñòîðîíà
  685.     mov    [FDD_Sector],2      ; Ñåêòîð
  686.     call   SeekTrack
  687.     mov    dh,14
  688. l.20_3:
  689.     call    ReadSectWithRetr
  690.     cmp    [FDC_Status],0
  691.     jne    fdc_status_error_7
  692.     mov    dl,16
  693.     mov    edi,FDD_BUFF
  694.     inc     [FDD_Sector]
  695. l.21_3:
  696.     mov    esi,eax            ;Name of file we want
  697.     mov    ecx,11
  698.     cld
  699.     rep    cmpsb            ;Found the file?
  700.     je     fifoundds_3          ;Yes
  701.     add    ecx,21
  702.     add    edi, ecx         ;Advance to next entry
  703.     dec    dl
  704.     jne    l.21_3
  705.     dec    dh
  706.     jne    l.20_3
  707. fdc_status_error_8:
  708.     pop     edi esi edx ecx ebx eax
  709.     mov    eax,5            ; file not found ?
  710.     mov    ebx,-1
  711.     add    esp,32
  712.     mov    [flp_status],0
  713.     ret
  714.  
  715. fifoundds_3:
  716.     add    edi,0xf
  717.     mov    eax,[edi]
  718.     and    eax,65535
  719.     mov    ebx,[path_pointer_flp]
  720.     add    ebx,36
  721.     call   get_cluster_of_a_path_flp
  722.     jc     fdc_status_error_7_1
  723. found_directory_for_writing_flp:
  724.     call   analyze_directory_to_write_flp
  725.     jc     fdc_status_error_7_1
  726.     mov    edi,ebx
  727. fifoundds_1:
  728.     push   edi            ; move the filename to root dir
  729.     mov    esi,[esp+4+20]
  730.     cmp    [save_root_flag],0
  731.     jne    fifoundds_4
  732.     mov    esi,[pointer_file_name_flp]
  733. fifoundds_4:
  734.     mov    ecx,11
  735.     cld
  736.     rep    movsb
  737.     pop    edi
  738.     mov    edx,edi
  739.     add    edx,11+0xf        ; edx <- cluster save position
  740.     mov    ebx,[esp+12]        ; save file size
  741.     mov    [edi+28],ebx
  742.     mov    [edi+11],byte 0x20    ; attribute
  743.     call   get_date_for_file     ; from FAT32.INC
  744.     mov    [edi+24],ax      ; date
  745.     mov    [edi+18],ax      ; date
  746.     call   get_time_for_file     ; from FAT32.INC
  747.     mov    [edi+22],ax      ; time
  748.     xor    ax,ax
  749.     mov    [edi+20],ax
  750.     mov    ebx,1            ; first cluster
  751.     cmp    [save_root_flag],0
  752.     jne    frnewds_1
  753.     call   frnewds_2
  754.     pusha
  755.     call   WriteSectWithRetr
  756.     popa
  757.     cmp    [FDC_Status],0
  758.     jne    fdc_status_error_7
  759.     jmp    frnewds_3
  760.  
  761. frnewds_1:
  762.     call   frnewds_2
  763. frnewds_3:
  764.     pusha                ; move save to floppy cluster
  765.     add    ebx,31
  766.     mov    eax,ebx
  767.     mov    esi,[esp+32+16]
  768.     call   take_data_from_application_1
  769.     call   save_chs_sector
  770.     cmp    [FDC_Status],0
  771.     jne    fdc_status_error_7
  772.     popa
  773.     mov    eax,[esp+12]
  774.     cmp    eax,512
  775.     jb     flnsa_1
  776.     sub    eax,512
  777.     mov    [esp+12],eax
  778.     mov    eax,[esp+16]
  779.     add    eax,512
  780.     mov    [esp+16],eax
  781.     jmp    frnewds_1
  782.  
  783. frnewds_2:
  784.     add    ebx,1
  785.     mov    edi,ebx            ; find free cluster in FAT
  786.     shl    edi,1
  787.     add    edi,FLOPPY_FAT
  788.     mov    eax,[edi]
  789.     and    eax,4095
  790.     jnz    frnewds_2
  791.     mov    [edx],bx         ; save next cluster pos. to prev cl.
  792.     mov    edx,edi            ; next save pos abs mem add
  793.     ret
  794.  
  795. flnsa_1:
  796.     mov    [edi],word 4095        ; mark end of file - last cluster
  797.     cmp    [save_root_flag],1
  798.     jne    flnsa_2
  799.     call   save_flp_root
  800.     cmp    [FDC_Status],0
  801.     jne    fdc_status_error_7
  802. flnsa_2:
  803.     call   save_flp_fat
  804.     cmp    [FDC_Status],0
  805.     jne    fdc_status_error_7
  806. frnoreadds_1:
  807.     pop    edi esi edx ecx ebx eax
  808.     add    esp,32
  809.     mov    eax,0
  810.     mov   [flp_status],0
  811.     ret
  812.  
  813. fdc_status_error_7_1:
  814.     cmp    [FDC_Status],0
  815.     je    fdc_status_error_8
  816. fdc_status_error_7:
  817.     pop    edi esi edx ecx ebx eax
  818.     add    esp,32
  819.     jmp    fdc_status_error_1
  820.  
  821. save_chs_sector:
  822.     call    calculate_chs
  823.     call    WriteSectWithRetr
  824.     ret
  825.  
  826. calculate_chs:
  827.     mov    bl,[FDD_Track]
  828.     mov    [old_track],bl
  829.     mov    ebx,18
  830.     xor    edx,edx
  831.     div    ebx
  832.     inc    edx
  833.     mov    [FDD_Sector],dl
  834.     xor    edx,edx
  835.     mov    ebx,2
  836.     div    ebx
  837.     mov    [FDD_Track],al
  838.     mov    [FDD_Head],0
  839.     cmp    edx,0
  840.     je     no_head_2
  841.     inc    [FDD_Head]
  842. no_head_2:
  843.     mov     dl,[old_track]
  844.     cmp     dl,[FDD_Track]
  845.     je      no_seek_track_1
  846.     call    SeekTrack
  847. no_seek_track_1:
  848.     ret
  849.  
  850.  
  851. get_cluster_of_a_path_flp:
  852. ;---------------------------------------------------------
  853. ; input  : EBX = pointer to a path string
  854. ;          (example: the path "/files/data/document" become
  855. ;                             "files......data.......document...0"
  856. ;          '.' = space char
  857. ;          '0' = char(0) (ASCII=0) !!! )
  858. ; output : if (CARRY=1) -> ERROR in the PATH
  859. ;          if (CARRY=0) -> EAX=cluster
  860. ;---------------------------------------------------------
  861.  
  862.     push  edx
  863.     mov   edx,ebx
  864.  
  865. search_end_of_path_flp:
  866.     cmp   [save_flag],0
  867.     jne   search_end_of_path_flp_1
  868.     cmp   byte [edx],0
  869.     je    found_end_of_path_flp
  870.     jmp   search_end_of_path_flp_2
  871. search_end_of_path_flp_1:
  872.     cmp   byte [edx+12],0
  873.     je    found_end_of_path_flp
  874. search_end_of_path_flp_2:
  875.     inc   edx ; '/'
  876.     call  analyze_directory_flp
  877.     jc    directory_not_found_flp
  878.  
  879.     mov   eax,[ebx+20-2]        ; read the HIGH 16bit cluster field
  880.     mov   ax,[ebx+26]           ; read the LOW 16bit cluster field
  881.     and   eax,0xfff           ;[fatMASK]
  882.     add   edx,11                ; 8+3 (name+extension)
  883.     jmp   search_end_of_path_flp
  884.  
  885. found_end_of_path_flp:
  886.     inc   edx
  887.     mov   [pointer_file_name_flp],edx
  888.     pop   edx
  889.     clc                         ; no errors
  890.     ret
  891.  
  892. directory_not_found_flp:
  893.     pop   edx
  894.     stc                         ; errors occour
  895.     ret
  896.  
  897. analyze_directory_flp:
  898. ;--------------------------------
  899. ; input  : EAX = first cluster of the directory
  900. ;          EBX = pointer to filename
  901. ; output : IF CARRY=0 EAX = sector where th file is found
  902. ;                     EBX = pointer in buffer
  903. ;                     [buffer .. buffer+511]
  904. ;                     ECX,EDX,EDI,EDI not changed
  905. ;          IF CARRY=1
  906. ;--------------------------------
  907.    push ebx ;[esp+16]
  908.    push ecx
  909.    push edx
  910.    push esi
  911.    push edi
  912.  
  913.  
  914. adr56_flp:
  915.    mov [clust_tmp_flp],eax
  916.    add    eax,31
  917.    pusha
  918.    call   read_chs_sector
  919.    popa
  920.    cmp    [FDC_Status],0
  921.    jne    not_found_file_analyze_flp
  922.  
  923.    mov ecx,512/32
  924.    mov ebx,FDD_BUFF
  925.  
  926. adr1_analyze_flp:
  927.    mov esi,edx   ;[esp+16]
  928.    mov edi,ebx
  929.    cld
  930.    push ecx
  931.    mov ecx,11
  932.    rep cmpsb
  933.    pop ecx
  934.    je found_file_analyze_flp
  935.  
  936.    add ebx,32
  937.    loop adr1_analyze_flp
  938.  
  939.     mov eax,[clust_tmp_flp]
  940.     shl    eax,1            ;find next cluster from FAT
  941.     add    eax,FLOPPY_FAT
  942.     mov    eax,[eax]
  943.     and    eax,4095
  944.     cmp eax,0x0ff8
  945.     jb  adr56_flp
  946. not_found_file_analyze_flp:
  947.    pop edi
  948.    pop esi
  949.    pop edx
  950.    pop ecx
  951.    add esp,4
  952.    stc        ;file not found
  953.    ret
  954.  
  955. found_file_analyze_flp:
  956.    pop edi
  957.    pop esi
  958.    pop edx
  959.    pop ecx
  960.    add esp,4
  961.    clc        ;file found
  962.    ret
  963.  
  964.  
  965. analyze_directory_to_write_flp:
  966. ;--------------------------------
  967. ; input  : EAX = first cluster of the directory
  968. ; output : IF CARRY=0 EAX = sector where the file is found
  969. ;                     EBX = pointer in buffer
  970. ;                     [buffer .. buffer+511]
  971. ;                     ECX,EDX,EDI,EDI not changed
  972. ;          IF CARRY=1
  973. ;--------------------------------
  974.  
  975.    push ecx
  976.    push edx
  977.    push esi
  978.  
  979. adr561:
  980.    mov [clust_tmp_flp],eax
  981.    add    eax,31
  982.    pusha
  983.    call   read_chs_sector
  984.    popa
  985.    cmp    [FDC_Status],0
  986.    jne    error_found_file_analyze1
  987.  
  988.    mov ecx,512/32
  989.    mov ebx,FDD_BUFF
  990.  
  991. adr1_analyze1:
  992.    cmp byte [ebx],0x00
  993.    je  found_file_analyze1
  994.    cmp byte [ebx],0xe5
  995.    je  found_file_analyze1
  996.  
  997. avanti:
  998.    add ebx,32
  999.    loop adr1_analyze1
  1000.  
  1001.    mov eax,[clust_tmp_flp]
  1002.    shl    eax,1            ;find next cluster from FAT
  1003.    add    eax,FLOPPY_FAT
  1004.    mov    eax,[eax]
  1005.    and    eax,4095
  1006.    cmp eax,0x0ff8
  1007.    jb  adr561
  1008.  
  1009.    call get_free_FAT               ;this block of code add a new cluster
  1010.                                    ;for the directory because the directory
  1011.                                    ;is full
  1012.  
  1013.    mov [edi],word 0x0fff
  1014.  
  1015.    mov eax,[clust_tmp_flp]
  1016.    shl    eax,1            ;find next cluster from FAT
  1017.    add    eax,FLOPPY_FAT
  1018.    sub    edi,FLOPPY_FAT
  1019.    mov    [eax],di
  1020.  
  1021.    pusha
  1022.    mov ecx,512/4
  1023.    xor eax,eax
  1024.    mov edi,FDD_BUFF
  1025.    cld
  1026.    rep stosd
  1027.    popa
  1028.  
  1029.    mov    eax,edi
  1030.    add    eax,31
  1031.    pusha
  1032.    call   save_chs_sector
  1033.    popa
  1034.    cmp    [FDC_Status],0
  1035.    jne    error_found_file_analyze1
  1036.    mov    ebx,FDD_BUFF
  1037.  
  1038. found_file_analyze1:
  1039.  
  1040.    pop esi
  1041.    pop edx
  1042.    pop ecx
  1043.    clc        ;file found
  1044.    ret
  1045.  
  1046. error_found_file_analyze1:
  1047.    pop esi
  1048.    pop edx
  1049.    pop ecx
  1050.    stc
  1051.    ret
  1052.  
  1053. get_free_FAT_flp:
  1054. ;------------------------------------------
  1055. ; input  :  EAX = # cluster for start the searching
  1056. ; output :  EAX = # first cluster found free
  1057. ;-------------------------------------------
  1058.    push ebx
  1059.  
  1060.     mov    ebx,1
  1061. check_new_flp:
  1062.     add    ebx,1
  1063.     mov    edi,ebx            ; find free cluster in FAT
  1064.     shl    edi,1
  1065.     add    edi,FLOPPY_FAT
  1066.     mov    eax,[edi]
  1067.     and    eax,4095
  1068.     cmp    eax,0x0
  1069.     jnz    check_new_flp
  1070.  
  1071.    pop ebx
  1072.    ret
  1073.  
  1074. ; \begin{diamond}
  1075. fat_find_lfn:
  1076. ; in: esi->name
  1077. ;     [esp+4] = next
  1078. ;     [esp+8] = first
  1079. ;     [esp+C]... - possibly parameters for first and next
  1080. ; out: CF=1 - file not found
  1081. ;      else CF=0, esi->next name component, edi->direntry
  1082.         pusha
  1083.         lea     eax, [esp+0Ch+20h]
  1084.         call    dword [eax-4]
  1085.         jc      .reterr
  1086.         sub     esp, 262*2      ; reserve place for LFN
  1087.         mov     ebp, esp
  1088.         push    0               ; for fat_get_name: read ASCII name
  1089. .l1:
  1090.         call    fat_get_name
  1091.         jc      .l2
  1092.         call    fat_compare_name
  1093.         jz      .found
  1094. .l2:
  1095.         lea     eax, [esp+0Ch+20h+262*2+4]
  1096.         call    dword [eax-8]
  1097.         jnc     .l1
  1098.         add     esp, 262*2+4
  1099. .reterr:
  1100.         stc
  1101.         popa
  1102.         ret
  1103. .found:
  1104.         add     esp, 262*2+4
  1105. ; if this is LFN entry, advance to true entry
  1106.         cmp     byte [edi+11], 0xF
  1107.         jnz     @f
  1108.         lea     eax, [esp+0Ch+20h]
  1109.         call    dword [eax-8]
  1110.         jc      .reterr
  1111. @@:
  1112.         add     esp, 8          ; CF=0
  1113.         push    esi
  1114.         push    edi
  1115.         popa
  1116.         ret
  1117.  
  1118. uglobal
  1119. ; this is for delete support
  1120. fd_prev_sector          dd      ?
  1121. fd_prev_prev_sector     dd      ?
  1122. endg
  1123.  
  1124. flp_root_next:
  1125.         cmp     edi, 0xD200-0x20
  1126.         jae     @f
  1127.         add     edi, 0x20
  1128.         ret     ; CF=0
  1129. @@:
  1130. ; read next sector
  1131.         inc     dword [eax]
  1132.         cmp     dword [eax], 14
  1133.         jae     flp_root_first.readerr
  1134.         push    [fd_prev_sector]
  1135.         pop     [fd_prev_prev_sector]
  1136.         push    eax
  1137.         mov     eax, [eax]
  1138.         add     eax, 19-1
  1139.         mov     [fd_prev_sector], eax
  1140.         pop     eax
  1141. flp_root_first:
  1142.         mov     eax, [eax]
  1143.         pusha
  1144.         add     eax, 19
  1145.         call    read_chs_sector
  1146.         popa
  1147.         cmp     [FDC_Status], 0
  1148.         jnz     .readerr
  1149.         mov     edi, FDD_BUFF
  1150.         ret     ; CF=0
  1151. .readerr:
  1152.         stc
  1153.         ret
  1154.  
  1155. flp_rootmem_first:
  1156.         mov     edi, FLOPPY_BUFF
  1157.         clc
  1158.         ret
  1159. flp_rootmem_next:
  1160.         add     edi, 0x20
  1161.         cmp     edi, FLOPPY_BUFF+14*0x200
  1162.         cmc
  1163. flp_rootmem_next_write:
  1164. flp_rootmem_begin_write:
  1165. flp_rootmem_end_write:
  1166.         ret
  1167. flp_rootmem_extend_dir:
  1168.         stc
  1169.         ret
  1170.  
  1171. flp_notroot_next:
  1172.         cmp     edi, 0xD200-0x20
  1173.         jae     flp_notroot_next_sector
  1174.         add     edi, 0x20
  1175.         ret     ; CF=0
  1176. flp_notroot_next_sector:
  1177.         push    ecx
  1178.         mov     ecx, [eax]
  1179.         push    [fd_prev_sector]
  1180.         pop     [fd_prev_prev_sector]
  1181.         add     ecx, 31
  1182.         mov     [fd_prev_sector], ecx
  1183.         mov     ecx, [(ecx-31)*2+FLOPPY_FAT]
  1184.         and     ecx, 0xFFF
  1185.         cmp     ecx, 2849
  1186.         jae     flp_notroot_first.err2
  1187.         mov     [eax], ecx
  1188.         pop     ecx
  1189. flp_notroot_first:
  1190.         mov     eax, [eax]
  1191.         cmp     eax, 2
  1192.         jb      .err
  1193.         cmp     eax, 2849
  1194.         jae     .err
  1195.         pusha
  1196.         add     eax, 31
  1197.         call    read_chs_sector
  1198.         popa
  1199.         mov     edi, FDD_BUFF
  1200.         cmp     [FDC_Status], 0
  1201.         jnz     .err
  1202.         ret     ; CF=0
  1203. .err2:
  1204.         pop     ecx
  1205. .err:
  1206.         stc
  1207.         ret
  1208. flp_notroot_begin_write:
  1209.         pusha
  1210.         mov     eax, [eax]
  1211.         add     eax, 31
  1212.         call    read_chs_sector
  1213.         popa
  1214.         ret
  1215. flp_notroot_end_write:
  1216.         pusha
  1217.         mov     eax, [eax]
  1218.         add     eax, 31
  1219.         call    save_chs_sector
  1220.         popa
  1221.         ret
  1222. flp_notroot_next_write:
  1223.         cmp     edi, 0xD200
  1224.         jae     @f
  1225.         ret
  1226. @@:
  1227.         call    flp_notroot_end_write
  1228.         jmp     flp_notroot_next_sector
  1229. flp_notroot_extend_dir:
  1230. ; find free cluster in FAT
  1231.         pusha
  1232.         xor     eax, eax
  1233.         mov     edi, FLOPPY_FAT
  1234.         mov     ecx, 2849
  1235.         repnz   scasw
  1236.         jnz     .notfound
  1237.         mov     word [edi-2], 0xFFF     ; mark as last cluster
  1238.         sub     edi, FLOPPY_FAT
  1239.         shr     edi, 1
  1240.         dec     edi
  1241.         mov     eax, [esp+28]
  1242.         mov     ecx, [eax]
  1243.         mov     [FLOPPY_FAT+ecx*2], di
  1244.         mov     [eax], edi
  1245.         xor     eax, eax
  1246.         mov     edi, FDD_BUFF
  1247.         mov     ecx, 128
  1248.         rep     stosd
  1249.         popa
  1250.         call    flp_notroot_end_write
  1251.         mov     edi, FDD_BUFF
  1252.         clc
  1253.         ret
  1254. .notfound:
  1255.         popa
  1256.         stc
  1257.         ret
  1258.  
  1259. fd_find_lfn:
  1260. ; in: esi->name
  1261. ; out: CF=1 - file not found
  1262. ;      else CF=0 and edi->direntry, eax=directory cluster (0 for root)
  1263.         push    esi edi
  1264.         push    0
  1265.         push    flp_root_first
  1266.         push    flp_root_next
  1267. .loop:
  1268.         call    fat_find_lfn
  1269.         jc      .notfound
  1270.         cmp     byte [esi], 0
  1271.         jz      .found
  1272.         test    byte [edi+11], 10h
  1273.         jz      .notfound
  1274.         movzx   eax, word [edi+26]      ; cluster
  1275.         mov     [esp+8], eax
  1276.         mov     dword [esp+4], flp_notroot_first
  1277.         mov     dword [esp], flp_notroot_next
  1278.         jmp     .loop
  1279. .notfound:
  1280.         add     esp, 12
  1281.         pop     edi esi
  1282.         stc
  1283.         ret
  1284. .found:
  1285.         mov     eax, [esp+8]
  1286.         add     eax, 31
  1287.         cmp     dword [esp], flp_root_next
  1288.         jnz     @f
  1289.         add     eax, -31+19
  1290. @@:
  1291.         add     esp, 16         ; CF=0
  1292.         pop     esi
  1293.         ret
  1294.  
  1295. ;----------------------------------------------------------------
  1296. ;
  1297. ;  fs_FloppyRead - LFN variant for reading floppy
  1298. ;
  1299. ;  esi  points to filename
  1300. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  1301. ;       may be ebx=0 - start from first byte
  1302. ;  ecx  number of bytes to read, 0+
  1303. ;  edx  mem location to return data
  1304. ;
  1305. ;  ret ebx = bytes read or 0xffffffff file not found
  1306. ;      eax = 0 ok read or other = errormsg
  1307. ;
  1308. ;--------------------------------------------------------------
  1309. fs_FloppyRead:
  1310.         call    read_flp_fat
  1311.         cmp     byte [esi], 0
  1312.         jnz     @f
  1313.         or      ebx, -1
  1314.         mov     eax, 10         ; access denied
  1315.         ret
  1316. @@:
  1317.         push    edi
  1318.         call    fd_find_lfn
  1319.         jnc     .found
  1320.         pop     edi
  1321.         or      ebx, -1
  1322.         mov     eax, 5          ; file not found
  1323.         ret
  1324. .found:
  1325.         test    ebx, ebx
  1326.         jz      .l1
  1327.         cmp     dword [ebx+4], 0
  1328.         jz      @f
  1329.         xor     ebx, ebx
  1330. .reteof:
  1331.         mov     eax, 6          ; EOF
  1332.         pop     edi
  1333.         ret
  1334. @@:
  1335.         mov     ebx, [ebx]
  1336. .l1:
  1337.         push    ecx edx
  1338.         push    0
  1339.         mov     eax, [edi+28]
  1340.         sub     eax, ebx
  1341.         jb      .eof
  1342.         cmp     eax, ecx
  1343.         jae     @f
  1344.         mov     ecx, eax
  1345.         mov     byte [esp], 6           ; EOF
  1346. @@:
  1347.         movzx   edi, word [edi+26]
  1348. .new:
  1349.         jecxz   .done
  1350.         test    edi, edi
  1351.         jz      .eof
  1352.         cmp     edi, 0xFF8
  1353.         jae     .eof
  1354.         sub     ebx, 512
  1355.         jae     .skip
  1356.         lea     eax, [edi+31]
  1357.         pusha
  1358.         call    read_chs_sector
  1359.         popa
  1360.         cmp     [FDC_Status], 0
  1361.         jnz     .err
  1362.         lea     eax, [FDD_BUFF+ebx+512]
  1363.         neg     ebx
  1364.         push    ecx
  1365.         cmp     ecx, ebx
  1366.         jbe     @f
  1367.         mov     ecx, ebx
  1368. @@:
  1369.         mov     ebx, edx
  1370.         call    memmove
  1371.         add     edx, ecx
  1372.         sub     [esp], ecx
  1373.         pop     ecx
  1374.         xor     ebx, ebx
  1375. .skip:
  1376.         movzx   edi, word [edi*2+FLOPPY_FAT]
  1377.         jmp     .new
  1378. .done:
  1379.         mov     ebx, edx
  1380.         pop     eax edx ecx edi
  1381.         sub     ebx, edx
  1382.         ret
  1383. .eof:
  1384.         mov     ebx, edx
  1385.         pop     eax edx ecx
  1386.         jmp     .reteof
  1387. .err:
  1388.         mov     ebx, edx
  1389.         pop     eax edx ecx edi
  1390.         sub     ebx, edx
  1391.         mov     al, 11
  1392.         ret
  1393.  
  1394. ;----------------------------------------------------------------
  1395. ;
  1396. ;  fs_FloppyReadFolder - LFN variant for reading floppy folders
  1397. ;
  1398. ;  esi  points to filename
  1399. ;  ebx  pointer to structure: 32-bit number = first wanted block, 0+
  1400. ;                           & flags (bitfields)
  1401. ; flags: bit 0: 0=ANSI names, 1=UNICODE names
  1402. ;  ecx  number of blocks to read, 0+
  1403. ;  edx  mem location to return data
  1404. ;
  1405. ;  ret ebx = blocks read or 0xffffffff folder not found
  1406. ;      eax = 0 ok read or other = errormsg
  1407. ;
  1408. ;--------------------------------------------------------------
  1409. fs_FloppyReadFolder:
  1410.         call    read_flp_fat
  1411.         push    edi
  1412.         cmp     byte [esi], 0
  1413.         jz      .root
  1414.         call    fd_find_lfn
  1415.         jnc     .found
  1416.         pop     edi
  1417.         or      ebx, -1
  1418.         mov     eax, ERROR_FILE_NOT_FOUND
  1419.         ret
  1420. .found:
  1421.         test    byte [edi+11], 0x10     ; do not allow read files
  1422.         jnz     .found_dir
  1423.         pop     edi
  1424.         or      ebx, -1
  1425.         mov     eax, ERROR_ACCESS_DENIED
  1426.         ret
  1427. .found_dir:
  1428.         movzx   eax, word [edi+26]
  1429.         add     eax, 31
  1430.         push    0
  1431.         jmp     .doit
  1432. .root:
  1433.         mov     eax, 19
  1434.         push    14
  1435. .doit:
  1436.         push    ecx ebp
  1437.         sub     esp, 262*2      ; reserve space for LFN
  1438.         mov     ebp, esp
  1439.         push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE names
  1440.         mov     ebx, [ebx]
  1441. ; init header
  1442.         push    eax ecx
  1443.         mov     edi, edx
  1444.         mov     ecx, 32/4
  1445.         xor     eax, eax
  1446.         rep     stosd
  1447.         pop     ecx eax
  1448.         mov     byte [edx], 1   ; version
  1449.         mov     esi, edi        ; esi points to BDFE
  1450. .main_loop:
  1451.         pusha
  1452.         call    read_chs_sector
  1453.         popa
  1454.         cmp     [FDC_Status], 0
  1455.         jnz     .error
  1456.         mov     edi, FDD_BUFF
  1457.         push    eax
  1458. .l1:
  1459.         call    fat_get_name
  1460.         jc      .l2
  1461.         cmp     byte [edi+11], 0xF
  1462.         jnz     .do_bdfe
  1463.         add     edi, 0x20
  1464.         cmp     edi, 0xD200
  1465.         jb      .do_bdfe
  1466.         pop     eax
  1467.         inc     eax
  1468.         dec     byte [esp+262*2+12]
  1469.         jz      .done
  1470.         jns     @f
  1471. ; read next sector from FAT
  1472.         mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
  1473.         and     eax, 0xFFF
  1474.         cmp     eax, 0xFF8
  1475.         jae     .done
  1476.         add     eax, 31
  1477.         mov     byte [esp+262*2+12], 0
  1478. @@:
  1479.         pusha
  1480.         call    read_chs_sector
  1481.         popa
  1482.         cmp     [FDC_Status], 0
  1483.         jnz     .error
  1484.         mov     edi, FDD_BUFF
  1485.         push    eax
  1486. .do_bdfe:
  1487.         inc     dword [edx+8]   ; new file found
  1488.         dec     ebx
  1489.         jns     .l2
  1490.         dec     ecx
  1491.         js      .l2
  1492.         inc     dword [edx+4]   ; new file block copied
  1493.         call    fat_entry_to_bdfe
  1494. .l2:
  1495.         add     edi, 0x20
  1496.         cmp     edi, 0xD200
  1497.         jb      .l1
  1498.         pop     eax
  1499.         inc     eax
  1500.         dec     byte [esp+262*2+12]
  1501.         jz      .done
  1502.         jns     @f
  1503. ; read next sector from FAT
  1504.         mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
  1505.         and     eax, 0xFFF
  1506.         cmp     eax, 0xFF8
  1507.         jae     .done
  1508.         add     eax, 31
  1509.         mov     byte [esp+262*2+12], 0
  1510. @@:
  1511.         jmp     .main_loop
  1512. .error:
  1513.         add     esp, 262*2+4
  1514.         pop     ebp ecx edi edi
  1515.         or      ebx, -1
  1516.         mov     eax, ERROR_FILE_NOT_FOUND
  1517.         ret
  1518. .done:
  1519.         add     esp, 262*2+4
  1520.         pop     ebp
  1521.         mov     ebx, [edx+4]
  1522.         xor     eax, eax
  1523.         dec     ecx
  1524.         js      @f
  1525.         mov     al, ERROR_END_OF_FILE
  1526. @@:
  1527.         pop     ecx edi edi
  1528.         ret
  1529.  
  1530. ;----------------------------------------------------------------
  1531. ;
  1532. ;  fs_FloppyRewrite - LFN variant for writing sys floppy
  1533. ;
  1534. ;  esi  points to filename
  1535. ;  ebx  ignored (reserved)
  1536. ;  ecx  number of bytes to write, 0+
  1537. ;  edx  mem location to data
  1538. ;
  1539. ;  ret ebx = number of written bytes
  1540. ;      eax = 0 ok read or other = errormsg
  1541. ;
  1542. ;--------------------------------------------------------------
  1543. @@:
  1544.         mov     eax, ERROR_ACCESS_DENIED
  1545.         xor     ebx, ebx
  1546.         ret
  1547. fsfrfe2:
  1548.         popad
  1549. fsfrfe:
  1550.         mov     eax, 11
  1551.         xor     ebx, ebx
  1552.         ret
  1553.  
  1554. fs_FloppyCreateFolder:
  1555.         mov     al, 1
  1556.         jmp     fs_FloppyRewrite.common
  1557.  
  1558. fs_FloppyRewrite:
  1559.         xor     eax, eax
  1560. .common:
  1561.         cmp     byte [esi], 0
  1562.         jz      @b
  1563.         call    read_flp_fat
  1564.         cmp     [FDC_Status], 0
  1565.         jnz     fsfrfe
  1566.         pushad
  1567.         xor     ebp, ebp
  1568.         push    esi
  1569. @@:
  1570.         lodsb
  1571.         test    al, al
  1572.         jz      @f
  1573.         cmp     al, '/'
  1574.         jnz     @b
  1575.         lea     ebp, [esi-1]
  1576.         jmp     @b
  1577. @@:
  1578.         pop     esi
  1579.         test    ebp, ebp
  1580.         jnz     .noroot
  1581.         call    read_flp_root
  1582.         cmp     [FDC_Status], 0
  1583.         jnz     fsfrfe2
  1584.         push    flp_rootmem_extend_dir
  1585.         push    flp_rootmem_end_write
  1586.         push    flp_rootmem_next_write
  1587.         push    flp_rootmem_begin_write
  1588.         xor     ebp, ebp
  1589.         push    ebp
  1590.         push    flp_rootmem_first
  1591.         push    flp_rootmem_next
  1592.         jmp     .common1
  1593. .noroot:
  1594.         mov     eax, ERROR_ACCESS_DENIED
  1595.         cmp     byte [ebp+1], 0
  1596.         jz      .ret1
  1597. ; check existence
  1598.         mov     byte [ebp], 0
  1599.         call    fd_find_lfn
  1600.         mov     byte [ebp], '/'
  1601.         lea     esi, [ebp+1]
  1602.         jnc     @f
  1603.         mov     eax, ERROR_FILE_NOT_FOUND
  1604. .ret1:
  1605.         mov     [esp+28], eax
  1606.         popad
  1607.         xor     ebx, ebx
  1608.         ret
  1609. @@:
  1610.         test    byte [edi+11], 0x10     ; must be directory
  1611.         mov     eax, ERROR_ACCESS_DENIED
  1612.         jz      .ret1
  1613.         movzx   ebp, word [edi+26]      ; ebp=cluster
  1614.         mov     eax, ERROR_FAT_TABLE
  1615.         cmp     ebp, 2
  1616.         jb      .ret1
  1617.         cmp     ebp, 2849
  1618.         jae     .ret1
  1619.         push    flp_notroot_extend_dir
  1620.         push    flp_notroot_end_write
  1621.         push    flp_notroot_next_write
  1622.         push    flp_notroot_begin_write
  1623.         push    ebp
  1624.         push    flp_notroot_first
  1625.         push    flp_notroot_next
  1626. .common1:
  1627.         call    fat_find_lfn
  1628.         jc      .notfound
  1629. ; found
  1630.         test    byte [edi+11], 10h
  1631.         jz      .exists_file
  1632. ; found directory; if we are creating directory, return OK,
  1633. ;                  if we are creating file, say "access denied"
  1634.         add     esp, 28
  1635.         popad
  1636.         test    al, al
  1637.         mov     eax, ERROR_ACCESS_DENIED
  1638.         jz      @f
  1639.         mov     al, 0
  1640. @@:
  1641.         xor     ebx, ebx
  1642.         ret
  1643. .exists_file:
  1644. ; found file; if we are creating directory, return "access denied",
  1645. ;             if we are creating file, delete existing file and continue
  1646.         cmp     byte [esp+28+28], 0
  1647.         jz      @f
  1648.         add     esp, 28
  1649.         popad
  1650.         mov     eax, ERROR_ACCESS_DENIED
  1651.         xor     ebx, ebx
  1652.         ret
  1653. @@:
  1654. ; delete FAT chain
  1655.         push    edi
  1656.         xor     eax, eax
  1657.         mov     dword [edi+28], eax     ; zero size
  1658.         xchg    ax, word [edi+26]       ; start cluster
  1659.         test    eax, eax
  1660.         jz      .done1
  1661. @@:
  1662.         cmp     eax, 0xFF8
  1663.         jae     .done1
  1664.         lea     edi, [FLOPPY_FAT + eax*2] ; position in FAT
  1665.         xor     eax, eax
  1666.         xchg    ax, [edi]
  1667.         jmp     @b
  1668. .done1:
  1669.         pop     edi
  1670.         call    get_time_for_file
  1671.         mov     [edi+22], ax
  1672.         call    get_date_for_file
  1673.         mov     [edi+24], ax
  1674.         mov     [edi+18], ax
  1675.         or      byte [edi+11], 20h      ; set 'archive' attribute
  1676.         jmp     .doit
  1677. .notfound:
  1678. ; file is not found; generate short name
  1679.         call    fat_name_is_legal
  1680.         jc      @f
  1681.         add     esp, 28
  1682.         popad
  1683.         mov     eax, ERROR_FILE_NOT_FOUND
  1684.         xor     ebx, ebx
  1685.         ret
  1686. @@:
  1687.         sub     esp, 12
  1688.         mov     edi, esp
  1689.         call    fat_gen_short_name
  1690. .test_short_name_loop:
  1691.         push    esi edi ecx
  1692.         mov     esi, edi
  1693.         lea     eax, [esp+12+12+8]
  1694.         mov     [eax], ebp
  1695.         call    dword [eax-4]
  1696.         jc      .found
  1697. .test_short_name_entry:
  1698.         cmp     byte [edi+11], 0xF
  1699.         jz      .test_short_name_cont
  1700.         mov     ecx, 11
  1701.         push    esi edi
  1702.         repz    cmpsb
  1703.         pop     edi esi
  1704.         jz      .short_name_found
  1705. .test_short_name_cont:
  1706.         lea     eax, [esp+12+12+8]
  1707.         call    dword [eax-8]
  1708.         jnc     .test_short_name_entry
  1709.         jmp     .found
  1710. .short_name_found:
  1711.         pop     ecx edi esi
  1712.         call    fat_next_short_name
  1713.         jnc     .test_short_name_loop
  1714. .disk_full:
  1715.         add     esp, 12+28
  1716.         popa
  1717.         mov     eax, ERROR_DISK_FULL
  1718.         xor     ebx, ebx
  1719.         ret
  1720. .found:
  1721.         pop     ecx edi esi
  1722. ; now find space in directory
  1723. ; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
  1724.         mov     al, '~'
  1725.         push    ecx edi
  1726.         mov     ecx, 8
  1727.         repnz   scasb
  1728.         push    1
  1729.         pop     eax     ; 1 entry
  1730.         jnz     .notilde
  1731. ; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
  1732.         xor     eax, eax
  1733. @@:
  1734.         cmp     byte [esi], 0
  1735.         jz      @f
  1736.         inc     esi
  1737.         inc     eax
  1738.         jmp     @b
  1739. @@:
  1740.         sub     esi, eax
  1741.         add     eax, 12+13
  1742.         mov     ecx, 13
  1743.         push    edx
  1744.         cdq
  1745.         div     ecx
  1746.         pop     edx
  1747. .notilde:
  1748.         push    -1
  1749.         push    -1
  1750. ; find <eax> successive entries in directory
  1751.         xor     ecx, ecx
  1752.         push    eax
  1753.         lea     eax, [esp+12+8+12+8]
  1754.         mov     [eax], ebp
  1755.         call    dword [eax-4]
  1756.         pop     eax
  1757.         jnc     .scan_dir
  1758. .fsfrfe3:
  1759.         add     esp, 8+8+12+28
  1760.         popad
  1761.         mov     eax, 11
  1762.         xor     ebx, ebx
  1763.         ret
  1764. .scan_dir:
  1765.         cmp     byte [edi], 0
  1766.         jz      .free
  1767.         cmp     byte [edi], 0xE5
  1768.         jz      .free
  1769.         xor     ecx, ecx
  1770. .scan_cont:
  1771.         push    eax
  1772.         lea     eax, [esp+12+8+12+8]
  1773.         call    dword [eax-8]
  1774.         pop     eax
  1775.         jnc     .scan_dir
  1776.         cmp     [FDC_Status], 0
  1777.         jnz     .fsfrfe3
  1778.         push    eax
  1779.         lea     eax, [esp+12+8+12+8]
  1780.         call    dword [eax+16]          ; extend directory
  1781.         pop     eax
  1782.         jnc     .scan_dir
  1783.         add     esp, 8+8+12+28
  1784.         popad
  1785.         mov     eax, ERROR_DISK_FULL
  1786.         xor     ebx, ebx
  1787.         ret
  1788. .free:
  1789.         test    ecx, ecx
  1790.         jnz     @f
  1791.         mov     [esp], edi
  1792.         mov     ecx, [esp+8+8+12+8]
  1793.         mov     [esp+4], ecx
  1794.         xor     ecx, ecx
  1795. @@:
  1796.         inc     ecx
  1797.         cmp     ecx, eax
  1798.         jb      .scan_cont
  1799. ; found!
  1800. ; calculate name checksum
  1801.         push    esi ecx
  1802.         mov     esi, [esp+8+8]
  1803.         mov     ecx, 11
  1804.         xor     eax, eax
  1805. @@:
  1806.         ror     al, 1
  1807.         add     al, [esi]
  1808.         inc     esi
  1809.         loop    @b
  1810.         pop     ecx esi
  1811.         pop     edi
  1812.         pop     dword [esp+8+12+8]
  1813. ; edi points to first entry in free chunk
  1814.         dec     ecx
  1815.         jz      .nolfn
  1816.         push    esi
  1817.         push    eax
  1818.         lea     eax, [esp+8+8+12+8]
  1819.         call    dword [eax+4]         ; begin write
  1820.         mov     al, 40h
  1821. .writelfn:
  1822.         or      al, cl
  1823.         mov     esi, [esp+4]
  1824.         push    ecx
  1825.         dec     ecx
  1826.         imul    ecx, 13
  1827.         add     esi, ecx
  1828.         stosb
  1829.         mov     cl, 5
  1830.         call    fs_RamdiskRewrite.read_symbols
  1831.         mov     ax, 0xF
  1832.         stosw
  1833.         mov     al, [esp+4]
  1834.         stosb
  1835.         mov     cl, 6
  1836.         call    fs_RamdiskRewrite.read_symbols
  1837.         xor     eax, eax
  1838.         stosw
  1839.         mov     cl, 2
  1840.         call    fs_RamdiskRewrite.read_symbols
  1841.         pop     ecx
  1842.         lea     eax, [esp+8+8+12+8]
  1843.         call    dword [eax+8]         ; next write
  1844.         xor     eax, eax
  1845.         loop    .writelfn
  1846.         pop     eax
  1847.         pop     esi
  1848. ;        lea     eax, [esp+8+12+8]
  1849. ;        call    dword [eax+12]          ; end write
  1850. .nolfn:
  1851.         xchg    esi, [esp]
  1852.         mov     ecx, 11
  1853.         rep     movsb
  1854.         mov     word [edi], 20h         ; attributes
  1855.         sub     edi, 11
  1856.         pop     esi ecx
  1857.         add     esp, 12
  1858.         mov     byte [edi+13], 0        ; tenths of a second at file creation time
  1859.         call    get_time_for_file
  1860.         mov     [edi+14], ax            ; creation time
  1861.         mov     [edi+22], ax            ; last write time
  1862.         call    get_date_for_file
  1863.         mov     [edi+16], ax            ; creation date
  1864.         mov     [edi+24], ax            ; last write date
  1865.         mov     [edi+18], ax            ; last access date
  1866.         and     word [edi+20], 0        ; high word of cluster
  1867.         and     word [edi+26], 0        ; low word of cluster - to be filled
  1868.         and     dword [edi+28], 0       ; file size - to be filled
  1869.         cmp     byte [esp+28+28], 0
  1870.         jz      .doit
  1871. ; create directory
  1872.         mov     byte [edi+11], 10h      ; attributes: folder
  1873.         mov     ecx, 32*2
  1874.         mov     edx, edi
  1875. .doit:
  1876.         lea     eax, [esp+8]
  1877.         call    dword [eax+12]  ; flush directory
  1878.         push    ecx
  1879.         push    edi
  1880.         push    0
  1881.         mov     esi, edx
  1882.         test    ecx, ecx
  1883.         jz      .done
  1884.         mov     ecx, 2849
  1885.         mov     edi, FLOPPY_FAT
  1886.         push    0       ; first cluster
  1887. .write_loop:
  1888. ; allocate new cluster
  1889.         xor     eax, eax
  1890.         repnz   scasw
  1891.         mov     al, ERROR_DISK_FULL
  1892.         jnz     .ret
  1893.         dec     edi
  1894.         dec     edi
  1895.         lea     eax, [edi-(FLOPPY_FAT)]
  1896.         shr     eax, 1                  ; eax = cluster
  1897.         mov     word [edi], 0xFFF       ; mark as last cluster
  1898.         xchg    edi, [esp+4]
  1899.         cmp     dword [esp], 0
  1900.         jz      .first
  1901.         stosw
  1902.         jmp     @f
  1903. .first:
  1904.         mov     [esp], eax
  1905. @@:
  1906.         mov     edi, [esp+4]
  1907.         inc     ecx
  1908. ; write data
  1909.         push    ecx edi
  1910.         mov     ecx, 512
  1911.         cmp     dword [esp+20], ecx
  1912.         jae     @f
  1913.         mov     ecx, [esp+20]
  1914. @@:
  1915.         mov     edi, FDD_BUFF
  1916.         cmp     byte [esp+24+28+28], 0
  1917.         jnz     .writedir
  1918.         push    ecx
  1919.         rep     movsb
  1920.         pop     ecx
  1921. .writedircont:
  1922.         push    ecx
  1923.         sub     ecx, 512
  1924.         neg     ecx
  1925.         push    eax
  1926.         xor     eax, eax
  1927.         rep     stosb
  1928.         pop     eax
  1929.         add     eax, 31
  1930.         pusha
  1931.         call    save_chs_sector
  1932.         popa
  1933.         pop     ecx
  1934.         cmp     [FDC_Status], 0
  1935.         jnz     .diskerr
  1936.         sub     [esp+20], ecx
  1937.         pop     edi ecx
  1938.         jnz     .write_loop
  1939. .done:
  1940.         xor     eax, eax
  1941. .ret:
  1942.         pop     ebx edi edi ecx
  1943.         mov     [esp+28+28], eax
  1944.         lea     eax, [esp+8]
  1945.         call    dword [eax+4]
  1946.         mov     [edi+26], bx
  1947.         mov     ebx, esi
  1948.         sub     ebx, edx
  1949.         mov     [edi+28], ebx
  1950.         call    dword [eax+12]
  1951.         mov     [esp+28+16], ebx
  1952.         test    ebp, ebp
  1953.         jnz     @f
  1954.         call    save_flp_root
  1955. @@:
  1956.         add     esp, 28
  1957.         cmp     [FDC_Status], 0
  1958.         jnz     .err3
  1959.         call    save_flp_fat
  1960.         cmp     [FDC_Status], 0
  1961.         jnz     .err3
  1962.         popa
  1963.         ret
  1964. .err3:
  1965.         popa
  1966.         mov     al, 11
  1967.         xor     ebx, ebx
  1968.         ret
  1969. .diskerr:
  1970.         sub     esi, ecx
  1971.         mov     eax, 11
  1972.         pop     edi ecx
  1973.         jmp     .ret
  1974. .writedir:
  1975.         push    ecx
  1976.         mov     ecx, 32/4
  1977.         push    ecx esi
  1978.         rep     movsd
  1979.         pop     esi ecx
  1980.         mov     dword [edi-32], '.   '
  1981.         mov     dword [edi-32+4], '    '
  1982.         mov     dword [edi-32+8], '    '
  1983.         mov     byte [edi-32+11], 10h
  1984.         mov     word [edi-32+26], ax
  1985.         push    esi
  1986.         rep     movsd
  1987.         pop     esi
  1988.         mov     dword [edi-32], '..  '
  1989.         mov     dword [edi-32+4], '    '
  1990.         mov     dword [edi-32+8], '    '
  1991.         mov     byte [edi-32+11], 10h
  1992.         mov     ecx, [esp+28+8]
  1993.         mov     word [edi-32+26], cx
  1994.         pop     ecx
  1995.         jmp     .writedircont
  1996.  
  1997. ;----------------------------------------------------------------
  1998. ;
  1999. ;  fs_FloppyWrite - LFN variant for writing to floppy
  2000. ;
  2001. ;  esi  points to filename
  2002. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  2003. ;       may be ebx=0 - start from first byte
  2004. ;  ecx  number of bytes to write, 0+
  2005. ;  edx  mem location to data
  2006. ;
  2007. ;  ret ebx = bytes written (maybe 0)
  2008. ;      eax = 0 ok write or other = errormsg
  2009. ;
  2010. ;--------------------------------------------------------------
  2011.  
  2012. @@:
  2013.         push    ERROR_ACCESS_DENIED
  2014. fs_FloppyWrite.ret0:
  2015.         pop     eax
  2016.         xor     ebx, ebx
  2017.         ret
  2018.  
  2019. fs_FloppyWrite.ret11:
  2020.         push    11
  2021.         jmp     fs_FloppyWrite.ret0
  2022.  
  2023. fs_FloppyWrite:
  2024.         cmp     byte [esi], 0
  2025.         jz      @b
  2026.         call    read_flp_fat
  2027.         cmp     [FDC_Status], 0
  2028.         jnz     .ret11
  2029.         pushad
  2030.         call    fd_find_lfn
  2031.         jnc     .found
  2032.         popad
  2033.         push    ERROR_FILE_NOT_FOUND
  2034.         jmp     .ret0
  2035. .found:
  2036. ; FAT does not support files larger than 4GB
  2037.         test    ebx, ebx
  2038.         jz      .l1
  2039.         cmp     dword [ebx+4], 0
  2040.         jz      @f
  2041. .eof:
  2042.         popad
  2043.         push    ERROR_END_OF_FILE
  2044.         jmp     .ret0
  2045. @@:
  2046.         mov     ebx, [ebx]
  2047. .l1:
  2048. ; now edi points to direntry, ebx=start byte to write,
  2049. ; ecx=number of bytes to write, edx=data pointer
  2050.  
  2051. ; extend file if needed
  2052.         add     ecx, ebx
  2053.         jc      .eof    ; FAT does not support files larger than 4GB
  2054.         push    eax     ; save directory cluster
  2055.         push    0       ; return value=0
  2056.  
  2057.         call    get_time_for_file
  2058.         mov     [edi+22], ax            ; last write time
  2059.         call    get_date_for_file
  2060.         mov     [edi+24], ax            ; last write date
  2061.         mov     [edi+18], ax            ; last access date
  2062.  
  2063.         push    dword [edi+28]          ; save current file size
  2064.         cmp     ecx, [edi+28]
  2065.         jbe     .length_ok
  2066.         cmp     ecx, ebx
  2067.         jz      .length_ok
  2068.         call    floppy_extend_file
  2069.         jnc     .length_ok
  2070.         mov     [esp+4], eax
  2071. ; floppy_extend_file can return two error codes: FAT table error or disk full.
  2072. ; First case is fatal error, in second case we may write some data
  2073.         cmp     al, ERROR_DISK_FULL
  2074.         jz      .disk_full
  2075.         pop     eax
  2076.         pop     eax
  2077.         mov     [esp+4+28], eax
  2078.         pop     eax
  2079.         popad
  2080.         xor     ebx, ebx
  2081.         ret
  2082. .disk_full:
  2083. ; correct number of bytes to write
  2084.         mov     ecx, [edi+28]
  2085.         cmp     ecx, ebx
  2086.         ja      .length_ok
  2087. .ret:
  2088.         pop     eax
  2089.         pop     eax
  2090.         mov     [esp+4+28], eax ; eax=return value
  2091.         pop     eax
  2092.         sub     edx, [esp+20]
  2093.         mov     [esp+16], edx   ; ebx=number of written bytes
  2094.         popad
  2095.         ret
  2096. .length_ok:
  2097. ; save FAT & directory
  2098. ; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
  2099.         mov     esi, [edi+28]
  2100.         movzx   edi, word [edi+26]      ; starting cluster
  2101.         mov     eax, [esp+8]
  2102.         pusha
  2103.         call    save_chs_sector
  2104.         popa
  2105.         cmp     [FDC_Status], 0
  2106.         jnz     .device_err
  2107.         call    save_flp_fat
  2108.         cmp     [FDC_Status], 0
  2109.         jz      @f
  2110. .device_err:
  2111.         mov     byte [esp+4], 11
  2112.         jmp     .ret
  2113. @@:
  2114.  
  2115. ; now ebx=start pos, ecx=end pos, both lie inside file
  2116.         sub     ecx, ebx
  2117.         jz      .ret
  2118.         call    SetUserInterrupts
  2119. .write_loop:
  2120. ; skip unmodified sectors
  2121.         cmp     dword [esp], 0x200
  2122.         jb      .modify
  2123.         sub     ebx, 0x200
  2124.         jae     .skip
  2125.         add     ebx, 0x200
  2126. .modify:
  2127.         lea     eax, [edi+31]   ; current sector
  2128. ; get length of data in current sector
  2129.         push    ecx
  2130.         sub     ebx, 0x200
  2131.         jb      .hasdata
  2132.         neg     ebx
  2133.         xor     ecx, ecx
  2134.         jmp     @f
  2135. .hasdata:
  2136.         neg     ebx
  2137.         cmp     ecx, ebx
  2138.         jbe     @f
  2139.         mov     ecx, ebx
  2140. @@:
  2141. ; load sector if needed
  2142.         cmp     dword [esp+4], 0        ; we don't need to read uninitialized data
  2143.         jz      .noread
  2144.         cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
  2145.         jz      .noread
  2146.         cmp     ecx, esi        ; (same for the last sector)
  2147.         jz      .noread
  2148.         pusha
  2149.         call    read_chs_sector
  2150.         popa
  2151.         cmp     [FDC_Status], 0
  2152.         jz      @f
  2153. .device_err2:
  2154.         pop     ecx
  2155.         jmp     .device_err
  2156. @@:
  2157. .noread:
  2158. ; zero uninitialized data if file was extended (because floppy_extend_file does not this)
  2159.         push    eax ecx edi
  2160.         xor     eax, eax
  2161.         mov     ecx, 0x200
  2162.         sub     ecx, [esp+4+12]
  2163.         jbe     @f
  2164.         mov     edi, FDD_BUFF
  2165.         add     edi, [esp+4+12]
  2166.         rep     stosb
  2167. @@:
  2168. ; zero uninitialized data in the last sector
  2169.         mov     ecx, 0x200
  2170.         sub     ecx, esi
  2171.         jbe     @f
  2172.         mov     edi, FDD_BUFF
  2173.         add     edi, esi
  2174.         rep     stosb
  2175. @@:
  2176.         pop     edi ecx eax
  2177. ; copy new data
  2178.         push    eax
  2179.         mov     eax, edx
  2180.         neg     ebx
  2181.         jecxz   @f
  2182.         add     ebx, FDD_BUFF+0x200
  2183.         call    memmove
  2184.         xor     ebx, ebx
  2185. @@:
  2186.         pop     eax
  2187. ; save sector
  2188.         pusha
  2189.         call    save_chs_sector
  2190.         popa
  2191.         cmp     [FDC_Status], 0
  2192.         jnz     .device_err2
  2193.         add     edx, ecx
  2194.         sub     [esp], ecx
  2195.         pop     ecx
  2196.         jz      .done
  2197. .skip:
  2198. .next_cluster:
  2199.         movzx   edi, word [edi*2+FLOPPY_FAT]
  2200.         sub     esi, 0x200
  2201.         jae     @f
  2202.         xor     esi, esi
  2203. @@:
  2204.         sub     dword [esp], 0x200
  2205.         jae     .write_loop
  2206.         and     dword [esp], 0
  2207.         jmp     .write_loop
  2208. .done:
  2209.         mov     [fdc_irq_func], fdc_null
  2210.         jmp     .ret
  2211.  
  2212. floppy_extend_file.zero_size:
  2213.         xor     eax, eax
  2214.         jmp     floppy_extend_file.start_extend
  2215.  
  2216. ; extends file on floppy to given size (new data area is undefined)
  2217. ; in: edi->direntry, ecx=new size
  2218. ; out: CF=0 => OK, eax=0
  2219. ;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
  2220. floppy_extend_file:
  2221.         push    ecx
  2222. ; find the last cluster of file
  2223.         movzx   eax, word [edi+26]      ; first cluster
  2224.         mov     ecx, [edi+28]
  2225.         jecxz   .zero_size
  2226. @@:
  2227.         sub     ecx, 0x200
  2228.         jbe     @f
  2229.         mov     eax, [eax*2+FLOPPY_FAT]
  2230.         and     eax, 0xFFF
  2231.         jz      .fat_err
  2232.         cmp     eax, 0xFF8
  2233.         jb      @b
  2234. .fat_err:
  2235.         pop     ecx
  2236.         push    ERROR_FAT_TABLE
  2237.         pop     eax
  2238.         stc
  2239.         ret
  2240. @@:
  2241.         push    eax
  2242.         mov     eax, [eax*2+FLOPPY_FAT]
  2243.         and     eax, 0xFFF
  2244.         cmp     eax, 0xFF8
  2245.         pop     eax
  2246.         jb      .fat_err
  2247. ; set length to full number of sectors
  2248.         sub     [edi+28], ecx
  2249. .start_extend:
  2250.         pop     ecx
  2251. ; now do extend
  2252.         push    edx esi
  2253.         mov     esi, FLOPPY_FAT+2*2       ; start scan from cluster 2
  2254.         mov     edx, 2847               ; number of clusters to scan
  2255. .extend_loop:
  2256.         cmp     [edi+28], ecx
  2257.         jae     .extend_done
  2258. ; add new sector
  2259.         push    ecx
  2260.         push    edi
  2261. .scan:
  2262.         mov     ecx, edx
  2263.         mov     edi, esi
  2264.         jecxz   .disk_full
  2265.         push    eax
  2266.         xor     eax, eax
  2267.         repnz   scasw
  2268.         pop     eax
  2269.         jnz     .disk_full
  2270.         mov     word [edi-2], 0xFFF
  2271.         mov     esi, edi
  2272.         mov     edx, ecx
  2273.         sub     edi, FLOPPY_FAT
  2274.         shr     edi, 1
  2275.         dec     edi     ; now edi=new cluster
  2276.         test    eax, eax
  2277.         jz      .first_cluster
  2278.         mov     [FLOPPY_FAT+eax*2], di
  2279.         jmp     @f
  2280. .first_cluster:
  2281.         pop     eax             ; eax->direntry
  2282.         push    eax
  2283.         mov     [eax+26], di
  2284. @@:
  2285.         mov     eax, edi        ; eax=new cluster
  2286.         pop     edi             ; edi->direntry
  2287.         pop     ecx             ; ecx=required size
  2288.         add     dword [edi+28], 0x200
  2289.         jmp     .extend_loop
  2290. .extend_done:
  2291.         mov     [edi+28], ecx
  2292.         pop     esi edx
  2293.         xor     eax, eax        ; CF=0
  2294.         ret
  2295. .disk_full:
  2296.         pop     edi ecx
  2297.         pop     esi edx
  2298.         stc
  2299.         push    ERROR_DISK_FULL
  2300.         pop     eax
  2301.         ret
  2302.  
  2303. ;----------------------------------------------------------------
  2304. ;
  2305. ;  fs_FloppySetFileEnd - set end of file on floppy
  2306. ;
  2307. ;  esi  points to filename
  2308. ;  ebx  points to 64-bit number = new file size
  2309. ;  ecx  ignored (reserved)
  2310. ;  edx  ignored (reserved)
  2311. ;
  2312. ;  ret eax = 0 ok or other = errormsg
  2313. ;
  2314. ;--------------------------------------------------------------
  2315. fs_FloppySetFileEnd:
  2316.         call    read_flp_fat
  2317.         cmp     [FDC_Status], 0
  2318.         jnz     ret11
  2319.         cmp     byte [esi], 0
  2320.         jnz     @f
  2321. .access_denied:
  2322.         push    ERROR_ACCESS_DENIED
  2323.         jmp     .ret
  2324. @@:
  2325.         push    edi
  2326.         call    fd_find_lfn
  2327.         jnc     @f
  2328.         pop     edi
  2329.         push    ERROR_FILE_NOT_FOUND
  2330. .ret:
  2331.         pop     eax
  2332.         jmp     .doret
  2333. @@:
  2334. ; must not be directory
  2335.         test    byte [edi+11], 10h
  2336.         jz      @f
  2337.         pop     edi
  2338.         jmp     .access_denied
  2339. @@:
  2340. ; file size must not exceed 4 Gb
  2341.         cmp     dword [ebx+4], 0
  2342.         jz      @f
  2343.         pop     edi
  2344.         push    ERROR_END_OF_FILE
  2345.         jmp     .ret
  2346. @@:
  2347.         push    eax
  2348. ; set file modification date/time to current
  2349.         call    fat_update_datetime
  2350.         mov     eax, [ebx]
  2351.         cmp     eax, [edi+28]
  2352.         jb      .truncate
  2353.         ja      .expand
  2354.         pop     eax
  2355.         pushad
  2356.         call    save_chs_sector
  2357.         popad
  2358.         pop     edi
  2359.         xor     eax, eax
  2360.         cmp     [FDC_Status], 0
  2361.         jz      @f
  2362.         mov     al, 11
  2363. @@:
  2364. .doret:
  2365.         mov     [fdc_irq_func], fdc_null
  2366.         ret
  2367. .expand:
  2368.         push    ecx
  2369.         push    dword [edi+28]  ; save old size
  2370.         mov     ecx, eax
  2371.         call    floppy_extend_file
  2372.         push    eax     ; return code
  2373.         jnc     .expand_ok
  2374.         cmp     al, ERROR_DISK_FULL
  2375.         jz      .disk_full
  2376.         pop     eax ecx ecx edi edi
  2377.         jmp     .doret
  2378. .device_err:
  2379.         pop     eax
  2380. .device_err2:
  2381.         pop     ecx ecx eax edi
  2382.         push    11
  2383.         jmp     .ret
  2384. .disk_full:
  2385. .expand_ok:
  2386. ; save directory & FAT
  2387.         mov     eax, [edi+28]
  2388.         xchg    eax, [esp+12]
  2389.         movzx   edi, word [edi+26]
  2390.         pusha
  2391.         call    save_chs_sector
  2392.         popa
  2393.         cmp     [FDC_Status], 0
  2394.         jnz     .device_err
  2395.         call    save_flp_fat
  2396.         cmp     [FDC_Status], 0
  2397.         jnz     .device_err
  2398.         call    SetUserInterrupts
  2399. ; now zero new data
  2400. ; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code
  2401. .zero_loop:
  2402.         sub     dword [esp+4], 0x200
  2403.         jae     .next_cluster
  2404.         cmp     dword [esp+4], -0x200
  2405.         jz      .noread
  2406.         lea     eax, [edi+31]
  2407.         pusha
  2408.         call    read_chs_sector
  2409.         popa
  2410.         cmp     [FDC_Status], 0
  2411.         jnz     .err_next
  2412. .noread:
  2413.         mov     ecx, [esp+4]
  2414.         neg     ecx
  2415.         push    edi
  2416.         mov     edi, FDD_BUFF+0x200
  2417.         add     edi, [esp+8]
  2418.         xor     eax, eax
  2419.         mov     [esp+8], eax
  2420.         rep     stosb
  2421.         pop     edi
  2422.         lea     eax, [edi+31]
  2423.         pusha
  2424.         call    save_chs_sector
  2425.         popa
  2426.         cmp     [FDC_Status], 0
  2427.         jz      .next_cluster
  2428. .err_next:
  2429.         mov     byte [esp], 11
  2430. .next_cluster:
  2431.         sub     dword [esp+12], 0x200
  2432.         jbe     .expand_done
  2433.         movzx   edi, word [FLOPPY_FAT+edi*2]
  2434.         jmp     .zero_loop
  2435. .expand_done:
  2436.         pop     eax ecx ecx edi edi
  2437.         jmp     .doret
  2438. .truncate:
  2439.         mov     [edi+28], eax
  2440.         push    ecx
  2441.         movzx   ecx, word [edi+26]
  2442.         test    eax, eax
  2443.         jz      .zero_size
  2444. ; find new last sector
  2445. @@:
  2446.         sub     eax, 0x200
  2447.         jbe     @f
  2448.         movzx   ecx, word [FLOPPY_FAT+ecx*2]
  2449.         jmp     @b
  2450. @@:
  2451. ; we will zero data at the end of last sector - remember it
  2452.         push    ecx
  2453. ; terminate FAT chain
  2454.         lea     ecx, [FLOPPY_FAT+ecx+ecx]
  2455.         push    dword [ecx]
  2456.         mov     word [ecx], 0xFFF
  2457.         pop     ecx
  2458.         and     ecx, 0xFFF
  2459.         jmp     .delete
  2460. .zero_size:
  2461.         and     word [edi+26], 0
  2462.         push    0
  2463. .delete:
  2464. ; delete FAT chain starting with ecx
  2465. ; mark all clusters as free
  2466.         cmp     ecx, 0xFF8
  2467.         jae     .deleted
  2468.         lea     ecx, [FLOPPY_FAT+ecx+ecx]
  2469.         push    dword [ecx]
  2470.         and     word [ecx], 0
  2471.         pop     ecx
  2472.         and     ecx, 0xFFF
  2473.         jmp     .delete
  2474. .deleted:
  2475.         mov     edi, [edi+28]
  2476. ; save directory & FAT
  2477.         mov     eax, [esp+8]
  2478.         pusha
  2479.         call    save_chs_sector
  2480.         popa
  2481.         cmp     [FDC_Status], 0
  2482.         jnz     .device_err2
  2483.         call    save_flp_fat
  2484.         cmp     [FDC_Status], 0
  2485.         jnz     .device_err2
  2486. ; zero last sector, ignore errors
  2487.         pop     eax
  2488.         add     eax, 31
  2489.         and     edi, 0x1FF
  2490.         jz      .truncate_done
  2491.         call    SetUserInterrupts
  2492.         pusha
  2493.         call    read_chs_sector
  2494.         popa
  2495.         add     edi, FDD_BUFF
  2496.         mov     ecx, FDD_BUFF+0x200
  2497.         sub     ecx, edi
  2498.         push    eax
  2499.         xor     eax, eax
  2500.         rep     stosb
  2501.         pop     eax
  2502.         pusha
  2503.         call    save_chs_sector
  2504.         popa
  2505. .truncate_done:
  2506.         pop     ecx eax edi
  2507.         xor     eax, eax
  2508.         jmp     .doret
  2509.  
  2510. fs_FloppyGetFileInfo:
  2511.         call    read_flp_fat
  2512.         cmp     [FDC_Status], 0
  2513.         jnz     ret11
  2514.         cmp     byte [esi], 0
  2515.         jnz     @f
  2516.         mov     eax, 2  ; unsupported
  2517.         ret
  2518. @@:
  2519.         push    edi
  2520.         call    fd_find_lfn
  2521.         jmp     fs_GetFileInfo_finish
  2522.  
  2523. ret11:
  2524.         mov     eax, 11
  2525.         ret
  2526.  
  2527. fs_FloppySetFileInfo:
  2528.         call    read_flp_fat
  2529.         cmp     [FDC_Status], 0
  2530.         jnz     ret11
  2531.         cmp     byte [esi], 0
  2532.         jnz     @f
  2533.         mov     eax, 2  ; unsupported
  2534.         ret
  2535. @@:
  2536.         push    edi
  2537.         call    fd_find_lfn
  2538.         jnc     @f
  2539.         pop     edi
  2540.         mov     eax, ERROR_FILE_NOT_FOUND
  2541.         ret
  2542. @@:
  2543.         push    eax
  2544.         call    bdfe_to_fat_entry
  2545.         pop     eax
  2546.         pusha
  2547.         call    save_chs_sector
  2548.         popa
  2549.         pop     edi
  2550.         xor     eax, eax
  2551.         cmp     [FDC_Status], 0
  2552.         jz      @f
  2553.         mov     al, 11
  2554. @@:
  2555.         ret
  2556.  
  2557. if 0
  2558. ;----------------------------------------------------------------
  2559. ;
  2560. ;  fs_FloppyExecute - LFN variant for executing from floppy
  2561. ;
  2562. ;  esi  points to floppy filename (e.g. 'dir1/name')
  2563. ;  ebp  points to full filename (e.g. '/fd/1/dir1/name')
  2564. ;  dword [ebx] = flags
  2565. ;  dword [ebx+4] = cmdline
  2566. ;
  2567. ;  ret ebx,edx destroyed
  2568. ;      eax > 0 - PID, < 0 - error
  2569. ;
  2570. ;--------------------------------------------------------------
  2571. fs_FloppyExecute:
  2572.         mov     edx, [ebx]
  2573.         mov     ebx, [ebx+4]
  2574.         test    ebx, ebx
  2575.         jz      @f
  2576.         add     ebx, std_application_base_address
  2577. @@:
  2578.  
  2579. ;----------------------------------------------------------------
  2580. ;
  2581. ; fs_FloppyExecute.flags - second entry
  2582. ;
  2583. ;  esi  points to floppy filename (kernel address)
  2584. ;  ebp  points to full filename
  2585. ;  edx  flags
  2586. ;  ebx  cmdline (kernel address)
  2587. ;
  2588. ;  ret  eax > 0 - PID, < 0 - error
  2589. ;
  2590. ;--------------------------------------------------------------
  2591.  
  2592. .flags:
  2593.         call    read_flp_fat
  2594.         cmp     byte [esi], 0
  2595.         jnz     @f
  2596. ; cannot execute root!
  2597.         mov     eax, -ERROR_ACCESS_DENIED
  2598.         ret
  2599. @@:
  2600.         push    edi
  2601.         call    fd_find_lfn
  2602.         jnc     .found
  2603.         pop     edi
  2604.         mov     eax, -ERROR_FILE_NOT_FOUND
  2605.         ret
  2606. .found:
  2607.         movzx   eax, word [edi+26]      ; cluster
  2608.         push    eax
  2609.         push    dword [edi+28]          ; size
  2610.         push    .DoRead
  2611.         call    fs_execute
  2612.         add     esp, 12
  2613.         pop     edi
  2614.         ret
  2615.  
  2616. .DoRead:
  2617. ; read next block
  2618. ; in: eax->parameters, edi->buffer
  2619. ; out: eax = error code
  2620.         pushad
  2621.         cmp     dword [eax], 0  ; file size
  2622.         jz      .eof
  2623.         mov     eax, [eax+4]    ; cluster
  2624.         add     eax, 31
  2625.         call    read_chs_sector
  2626.         cmp     [FDC_Status], 0
  2627.         jnz     .err
  2628.         pop     edi
  2629.         mov     esi, FDD_BUFF
  2630.         push    edi
  2631.         mov     ecx, 512/4
  2632.         rep     movsd
  2633.         mov     eax, [esp+28]
  2634.         mov     ecx, [eax]
  2635.         sub     ecx, 512
  2636.         jae     @f
  2637.         add     edi, ecx
  2638.         neg     ecx
  2639.         push    eax
  2640.         xor     eax, eax
  2641.         rep     stosb
  2642.         pop     eax
  2643. @@:
  2644.         mov     [eax], ecx
  2645.         mov     edx, [eax+4]
  2646.         mov     dx, [edx*2+FLOPPY_FAT]
  2647.         mov     [eax+4], dx     ; high word is already zero
  2648.         popad
  2649.         xor     eax, eax
  2650.         ret
  2651. .eof:
  2652.         popad
  2653.         mov     eax, 6
  2654.         ret
  2655. .err:
  2656.         popad
  2657.         mov     eax, 11
  2658.         ret
  2659. end if
  2660.  
  2661. ;----------------------------------------------------------------
  2662. ;
  2663. ;  fs_FloppyDelete - delete file or empty folder from floppy
  2664. ;
  2665. ;  esi  points to filename
  2666. ;
  2667. ;  ret  eax = 0 ok or other = errormsg
  2668. ;
  2669. ;--------------------------------------------------------------
  2670. fs_FloppyDelete:
  2671.         call    read_flp_fat
  2672.         cmp     [FDC_Status], 0
  2673.         jz      @f
  2674.         push    11
  2675.         jmp     .pop_ret
  2676. @@:
  2677.         cmp     byte [esi], 0
  2678.         jnz     @f
  2679. ; cannot delete root!
  2680. .access_denied:
  2681.         push    ERROR_ACCESS_DENIED
  2682. .pop_ret:
  2683.         pop     eax
  2684.         ret
  2685. @@:
  2686.         and     [fd_prev_sector], 0
  2687.         and     [fd_prev_prev_sector], 0
  2688.         push    edi
  2689.         call    fd_find_lfn
  2690.         jnc     .found
  2691.         pop     edi
  2692.         push    ERROR_FILE_NOT_FOUND
  2693.         jmp     .pop_ret
  2694. .found:
  2695.         cmp     dword [edi], '.   '
  2696.         jz      .access_denied2
  2697.         cmp     dword [edi], '..  '
  2698.         jz      .access_denied2
  2699.         test    byte [edi+11], 10h
  2700.         jz      .dodel
  2701. ; we can delete only empty folders!
  2702.         push    eax
  2703.         movzx   eax, word [edi+26]
  2704.         push    ebx
  2705.         pusha
  2706.         add     eax, 31
  2707.         call    read_chs_sector
  2708.         popa
  2709.         mov     ebx, FDD_BUFF + 2*0x20
  2710. .checkempty:
  2711.         cmp     byte [ebx], 0
  2712.         jz      .empty
  2713.         cmp     byte [ebx], 0xE5
  2714.         jnz     .notempty
  2715.         add     ebx, 0x20
  2716.         cmp     ebx, FDD_BUFF + 0x200
  2717.         jb      .checkempty
  2718.         movzx   eax, word [FLOPPY_FAT + eax*2]
  2719.         pusha
  2720.         add     eax, 31
  2721.         call    read_chs_sector
  2722.         popa
  2723.         mov     ebx, FDD_BUFF
  2724.         jmp     .checkempty
  2725. .notempty:
  2726.         pop     ebx
  2727.         pop     eax
  2728. .access_denied2:
  2729.         pop     edi
  2730.         jmp     .access_denied
  2731. .empty:
  2732.         pop     ebx
  2733.         pop     eax
  2734.         pusha
  2735.         call    read_chs_sector
  2736.         popa
  2737. .dodel:
  2738.         push    eax
  2739.         movzx   eax, word [edi+26]
  2740.         xchg    eax, [esp]
  2741. ; delete folder entry
  2742.         mov     byte [edi], 0xE5
  2743. ; delete LFN (if present)
  2744. .lfndel:
  2745.         cmp     edi, FDD_BUFF
  2746.         ja      @f
  2747.         cmp     [fd_prev_sector], 0
  2748.         jz      .lfndone
  2749.         push    [fd_prev_sector]
  2750.         push    [fd_prev_prev_sector]
  2751.         pop     [fd_prev_sector]
  2752.         and     [fd_prev_prev_sector], 0
  2753.         pusha
  2754.         call    save_chs_sector
  2755.         popa
  2756.         pop     eax
  2757.         pusha
  2758.         call    read_chs_sector
  2759.         popa
  2760.         mov     edi, FDD_BUFF+0x200
  2761. @@:
  2762.         sub     edi, 0x20
  2763.         cmp     byte [edi], 0xE5
  2764.         jz      .lfndone
  2765.         cmp     byte [edi+11], 0xF
  2766.         jnz     .lfndone
  2767.         mov     byte [edi], 0xE5
  2768.         jmp     .lfndel
  2769. .lfndone:
  2770.         pusha
  2771.         call    save_chs_sector
  2772.         popa
  2773. ; delete FAT chain
  2774.         pop     eax
  2775.         test    eax, eax
  2776.         jz      .done
  2777. @@:
  2778.         lea     eax, [FLOPPY_FAT + eax*2]
  2779.         push    dword [eax]
  2780.         and     word [eax], 0
  2781.         pop     eax
  2782.         and     eax, 0xFFF
  2783.         jnz     @b
  2784. .done:
  2785.         call    save_flp_fat
  2786.         pop     edi
  2787.         xor     eax, eax
  2788.         ret
  2789.  
  2790. ; \end{diamond}
  2791.