Subversion Repositories Kolibri OS

Rev

Rev 431 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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