Subversion Repositories Kolibri OS

Rev

Rev 425 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. $Revision: 431 $
  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, 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, 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, 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, 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, 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.         lea     eax, [edi-(FLOPPY_FAT)]
  1899.         shr     eax, 1                  ; eax = cluster
  1900.         mov     word [edi], 0xFFF       ; mark as last cluster
  1901.         xchg    edi, [esp+4]
  1902.         cmp     dword [esp], 0
  1903.         jz      .first
  1904.         stosw
  1905.         jmp     @f
  1906. .first:
  1907.         mov     [esp], eax
  1908. @@:
  1909.         mov     edi, [esp+4]
  1910.         inc     ecx
  1911. ; write data
  1912.         push    ecx edi
  1913.         mov     ecx, 512
  1914.         cmp     dword [esp+20], ecx
  1915.         jae     @f
  1916.         mov     ecx, [esp+20]
  1917. @@:
  1918.         mov     edi, FDD_BUFF
  1919.         cmp     byte [esp+24+28+28], 0
  1920.         jnz     .writedir
  1921.         push    ecx
  1922.         rep     movsb
  1923.         pop     ecx
  1924. .writedircont:
  1925.         push    ecx
  1926.         sub     ecx, 512
  1927.         neg     ecx
  1928.         push    eax
  1929.         xor     eax, eax
  1930.         rep     stosb
  1931.         pop     eax
  1932.         add     eax, 31
  1933.         pusha
  1934.         call    save_chs_sector
  1935.         popa
  1936.         pop     ecx
  1937.         cmp     [FDC_Status], 0
  1938.         jnz     .diskerr
  1939.         sub     [esp+20], ecx
  1940.         pop     edi ecx
  1941.         jnz     .write_loop
  1942. .done:
  1943.         xor     eax, eax
  1944. .ret:
  1945.         pop     ebx edi edi ecx
  1946.         mov     [esp+28+28], eax
  1947.         lea     eax, [esp+8]
  1948.         call    dword [eax+4]
  1949.         mov     [edi+26], bx
  1950.         mov     ebx, esi
  1951.         sub     ebx, edx
  1952.         mov     [edi+28], ebx
  1953.         call    dword [eax+12]
  1954.         mov     [esp+28+16], ebx
  1955.         test    ebp, ebp
  1956.         jnz     @f
  1957.         call    save_flp_root
  1958. @@:
  1959.         add     esp, 28
  1960.         cmp     [FDC_Status], 0
  1961.         jnz     .err3
  1962.         call    save_flp_fat
  1963.         cmp     [FDC_Status], 0
  1964.         jnz     .err3
  1965.         popa
  1966.         ret
  1967. .err3:
  1968.         popa
  1969.         mov     al, 11
  1970.         xor     ebx, ebx
  1971.         ret
  1972. .diskerr:
  1973.         sub     esi, ecx
  1974.         mov     eax, 11
  1975.         pop     edi ecx
  1976.         jmp     .ret
  1977. .writedir:
  1978.         push    ecx
  1979.         mov     ecx, 32/4
  1980.         push    ecx esi
  1981.         rep     movsd
  1982.         pop     esi ecx
  1983.         mov     dword [edi-32], '.   '
  1984.         mov     dword [edi-32+4], '    '
  1985.         mov     dword [edi-32+8], '    '
  1986.         mov     byte [edi-32+11], 10h
  1987.         mov     word [edi-32+26], ax
  1988.         push    esi
  1989.         rep     movsd
  1990.         pop     esi
  1991.         mov     dword [edi-32], '..  '
  1992.         mov     dword [edi-32+4], '    '
  1993.         mov     dword [edi-32+8], '    '
  1994.         mov     byte [edi-32+11], 10h
  1995.         mov     ecx, [esp+28+8]
  1996.         mov     word [edi-32+26], cx
  1997.         pop     ecx
  1998.         jmp     .writedircont
  1999.  
  2000. ;----------------------------------------------------------------
  2001. ;
  2002. ;  fs_FloppyWrite - LFN variant for writing to floppy
  2003. ;
  2004. ;  esi  points to filename
  2005. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  2006. ;       may be ebx=0 - start from first byte
  2007. ;  ecx  number of bytes to write, 0+
  2008. ;  edx  mem location to data
  2009. ;
  2010. ;  ret ebx = bytes written (maybe 0)
  2011. ;      eax = 0 ok write or other = errormsg
  2012. ;
  2013. ;--------------------------------------------------------------
  2014.  
  2015. @@:
  2016.         push    ERROR_ACCESS_DENIED
  2017. fs_FloppyWrite.ret0:
  2018.         pop     eax
  2019.         xor     ebx, ebx
  2020.         ret
  2021.  
  2022. fs_FloppyWrite.ret11:
  2023.         push    11
  2024.         jmp     fs_FloppyWrite.ret0
  2025.  
  2026. fs_FloppyWrite:
  2027.         cmp     byte [esi], 0
  2028.         jz      @b
  2029.         call    read_flp_fat
  2030.         cmp     [FDC_Status], 0
  2031.         jnz     .ret11
  2032.         pushad
  2033.         call    fd_find_lfn
  2034.         jnc     .found
  2035.         popad
  2036.         push    ERROR_FILE_NOT_FOUND
  2037.         jmp     .ret0
  2038. .found:
  2039. ; FAT does not support files larger than 4GB
  2040.         test    ebx, ebx
  2041.         jz      .l1
  2042.         cmp     dword [ebx+4], 0
  2043.         jz      @f
  2044. .eof:
  2045.         popad
  2046.         push    ERROR_END_OF_FILE
  2047.         jmp     .ret0
  2048. @@:
  2049.         mov     ebx, [ebx]
  2050. .l1:
  2051. ; now edi points to direntry, ebx=start byte to write,
  2052. ; ecx=number of bytes to write, edx=data pointer
  2053.  
  2054. ; extend file if needed
  2055.         add     ecx, ebx
  2056.         jc      .eof    ; FAT does not support files larger than 4GB
  2057.         push    eax     ; save directory cluster
  2058.         push    0       ; return value=0
  2059.  
  2060.         call    get_time_for_file
  2061.         mov     [edi+22], ax            ; last write time
  2062.         call    get_date_for_file
  2063.         mov     [edi+24], ax            ; last write date
  2064.         mov     [edi+18], ax            ; last access date
  2065.  
  2066.         push    dword [edi+28]          ; save current file size
  2067.         cmp     ecx, [edi+28]
  2068.         jbe     .length_ok
  2069.         cmp     ecx, ebx
  2070.         jz      .length_ok
  2071.         call    floppy_extend_file
  2072.         jnc     .length_ok
  2073.         mov     [esp+4], eax
  2074. ; floppy_extend_file can return two error codes: FAT table error or disk full.
  2075. ; First case is fatal error, in second case we may write some data
  2076.         cmp     al, ERROR_DISK_FULL
  2077.         jz      .disk_full
  2078.         pop     eax
  2079.         pop     eax
  2080.         mov     [esp+4+28], eax
  2081.         pop     eax
  2082.         popad
  2083.         xor     ebx, ebx
  2084.         ret
  2085. .disk_full:
  2086. ; correct number of bytes to write
  2087.         mov     ecx, [edi+28]
  2088.         cmp     ecx, ebx
  2089.         ja      .length_ok
  2090. .ret:
  2091.         pop     eax
  2092.         pop     eax
  2093.         mov     [esp+4+28], eax ; eax=return value
  2094.         pop     eax
  2095.         sub     edx, [esp+20]
  2096.         mov     [esp+16], edx   ; ebx=number of written bytes
  2097.         popad
  2098.         ret
  2099. .length_ok:
  2100. ; save FAT & directory
  2101. ; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
  2102.         mov     esi, [edi+28]
  2103.         movzx   edi, word [edi+26]      ; starting cluster
  2104.         mov     eax, [esp+8]
  2105.         pusha
  2106.         call    save_chs_sector
  2107.         popa
  2108.         cmp     [FDC_Status], 0
  2109.         jnz     .device_err
  2110.         call    save_flp_fat
  2111.         cmp     [FDC_Status], 0
  2112.         jz      @f
  2113. .device_err:
  2114.         mov     byte [esp+4], 11
  2115.         jmp     .ret
  2116. @@:
  2117.  
  2118. ; now ebx=start pos, ecx=end pos, both lie inside file
  2119.         sub     ecx, ebx
  2120.         jz      .ret
  2121.         call    SetUserInterrupts
  2122. .write_loop:
  2123. ; skip unmodified sectors
  2124.         cmp     dword [esp], 0x200
  2125.         jb      .modify
  2126.         sub     ebx, 0x200
  2127.         jae     .skip
  2128.         add     ebx, 0x200
  2129. .modify:
  2130.         lea     eax, [edi+31]   ; current sector
  2131. ; get length of data in current sector
  2132.         push    ecx
  2133.         sub     ebx, 0x200
  2134.         jb      .hasdata
  2135.         neg     ebx
  2136.         xor     ecx, ecx
  2137.         jmp     @f
  2138. .hasdata:
  2139.         neg     ebx
  2140.         cmp     ecx, ebx
  2141.         jbe     @f
  2142.         mov     ecx, ebx
  2143. @@:
  2144. ; load sector if needed
  2145.         cmp     dword [esp+4], 0        ; we don't need to read uninitialized data
  2146.         jz      .noread
  2147.         cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
  2148.         jz      .noread
  2149.         cmp     ecx, esi        ; (same for the last sector)
  2150.         jz      .noread
  2151.         pusha
  2152.         call    read_chs_sector
  2153.         popa
  2154.         cmp     [FDC_Status], 0
  2155.         jz      @f
  2156. .device_err2:
  2157.         pop     ecx
  2158.         jmp     .device_err
  2159. @@:
  2160. .noread:
  2161. ; zero uninitialized data if file was extended (because floppy_extend_file does not this)
  2162.         push    eax ecx edi
  2163.         xor     eax, eax
  2164.         mov     ecx, 0x200
  2165.         sub     ecx, [esp+4+12]
  2166.         jbe     @f
  2167.         mov     edi, FDD_BUFF
  2168.         add     edi, [esp+4+12]
  2169.         rep     stosb
  2170. @@:
  2171. ; zero uninitialized data in the last sector
  2172.         mov     ecx, 0x200
  2173.         sub     ecx, esi
  2174.         jbe     @f
  2175.         mov     edi, FDD_BUFF
  2176.         add     edi, esi
  2177.         rep     stosb
  2178. @@:
  2179.         pop     edi ecx eax
  2180. ; copy new data
  2181.         push    eax
  2182.         mov     eax, edx
  2183.         neg     ebx
  2184.         jecxz   @f
  2185.         add     ebx, FDD_BUFF+0x200
  2186.         call    memmove
  2187.         xor     ebx, ebx
  2188. @@:
  2189.         pop     eax
  2190. ; save sector
  2191.         pusha
  2192.         call    save_chs_sector
  2193.         popa
  2194.         cmp     [FDC_Status], 0
  2195.         jnz     .device_err2
  2196.         add     edx, ecx
  2197.         sub     [esp], ecx
  2198.         pop     ecx
  2199.         jz      .done
  2200. .skip:
  2201. .next_cluster:
  2202.         movzx   edi, word [edi*2+FLOPPY_FAT]
  2203.         sub     esi, 0x200
  2204.         jae     @f
  2205.         xor     esi, esi
  2206. @@:
  2207.         sub     dword [esp], 0x200
  2208.         jae     .write_loop
  2209.         and     dword [esp], 0
  2210.         jmp     .write_loop
  2211. .done:
  2212.         mov     [fdc_irq_func], fdc_null
  2213.         jmp     .ret
  2214.  
  2215. floppy_extend_file.zero_size:
  2216.         xor     eax, eax
  2217.         jmp     floppy_extend_file.start_extend
  2218.  
  2219. ; extends file on floppy to given size (new data area is undefined)
  2220. ; in: edi->direntry, ecx=new size
  2221. ; out: CF=0 => OK, eax=0
  2222. ;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
  2223. floppy_extend_file:
  2224.         push    ecx
  2225. ; find the last cluster of file
  2226.         movzx   eax, word [edi+26]      ; first cluster
  2227.         mov     ecx, [edi+28]
  2228.         jecxz   .zero_size
  2229. @@:
  2230.         sub     ecx, 0x200
  2231.         jbe     @f
  2232.         mov     eax, [eax*2+FLOPPY_FAT]
  2233.         and     eax, 0xFFF
  2234.         jz      .fat_err
  2235.         cmp     eax, 0xFF8
  2236.         jb      @b
  2237. .fat_err:
  2238.         pop     ecx
  2239.         push    ERROR_FAT_TABLE
  2240.         pop     eax
  2241.         stc
  2242.         ret
  2243. @@:
  2244.         push    eax
  2245.         mov     eax, [eax*2+FLOPPY_FAT]
  2246.         and     eax, 0xFFF
  2247.         cmp     eax, 0xFF8
  2248.         pop     eax
  2249.         jb      .fat_err
  2250. ; set length to full number of sectors
  2251.         sub     [edi+28], ecx
  2252. .start_extend:
  2253.         pop     ecx
  2254. ; now do extend
  2255.         push    edx esi
  2256.         mov     esi, FLOPPY_FAT+2*2       ; start scan from cluster 2
  2257.         mov     edx, 2847               ; number of clusters to scan
  2258. .extend_loop:
  2259.         cmp     [edi+28], ecx
  2260.         jae     .extend_done
  2261. ; add new sector
  2262.         push    ecx
  2263.         push    edi
  2264. .scan:
  2265.         mov     ecx, edx
  2266.         mov     edi, esi
  2267.         jecxz   .disk_full
  2268.         push    eax
  2269.         xor     eax, eax
  2270.         repnz   scasw
  2271.         pop     eax
  2272.         jnz     .disk_full
  2273.         mov     word [edi-2], 0xFFF
  2274.         mov     esi, edi
  2275.         mov     edx, ecx
  2276.         sub     edi, FLOPPY_FAT
  2277.         shr     edi, 1
  2278.         dec     edi     ; now edi=new cluster
  2279.         test    eax, eax
  2280.         jz      .first_cluster
  2281.         mov     [FLOPPY_FAT+eax*2], di
  2282.         jmp     @f
  2283. .first_cluster:
  2284.         pop     eax             ; eax->direntry
  2285.         push    eax
  2286.         mov     [eax+26], di
  2287. @@:
  2288.         mov     eax, edi        ; eax=new cluster
  2289.         pop     edi             ; edi->direntry
  2290.         pop     ecx             ; ecx=required size
  2291.         add     dword [edi+28], 0x200
  2292.         jmp     .extend_loop
  2293. .extend_done:
  2294.         mov     [edi+28], ecx
  2295.         pop     esi edx
  2296.         xor     eax, eax        ; CF=0
  2297.         ret
  2298. .disk_full:
  2299.         pop     edi ecx
  2300.         pop     esi edx
  2301.         stc
  2302.         push    ERROR_DISK_FULL
  2303.         pop     eax
  2304.         ret
  2305.  
  2306. ;----------------------------------------------------------------
  2307. ;
  2308. ;  fs_FloppySetFileEnd - set end of file on floppy
  2309. ;
  2310. ;  esi  points to filename
  2311. ;  ebx  points to 64-bit number = new file size
  2312. ;  ecx  ignored (reserved)
  2313. ;  edx  ignored (reserved)
  2314. ;
  2315. ;  ret eax = 0 ok or other = errormsg
  2316. ;
  2317. ;--------------------------------------------------------------
  2318. fs_FloppySetFileEnd:
  2319.         call    read_flp_fat
  2320.         cmp     [FDC_Status], 0
  2321.         jnz     ret11
  2322.         cmp     byte [esi], 0
  2323.         jnz     @f
  2324. .access_denied:
  2325.         push    ERROR_ACCESS_DENIED
  2326.         jmp     .ret
  2327. @@:
  2328.         push    edi
  2329.         call    fd_find_lfn
  2330.         jnc     @f
  2331.         pop     edi
  2332.         push    ERROR_FILE_NOT_FOUND
  2333. .ret:
  2334.         pop     eax
  2335.         jmp     .doret
  2336. @@:
  2337. ; must not be directory
  2338.         test    byte [edi+11], 10h
  2339.         jz      @f
  2340.         pop     edi
  2341.         jmp     .access_denied
  2342. @@:
  2343. ; file size must not exceed 4 Gb
  2344.         cmp     dword [ebx+4], 0
  2345.         jz      @f
  2346.         pop     edi
  2347.         push    ERROR_END_OF_FILE
  2348.         jmp     .ret
  2349. @@:
  2350.         push    eax
  2351. ; set file modification date/time to current
  2352.         call    fat_update_datetime
  2353.         mov     eax, [ebx]
  2354.         cmp     eax, [edi+28]
  2355.         jb      .truncate
  2356.         ja      .expand
  2357.         pop     eax
  2358.         pushad
  2359.         call    save_chs_sector
  2360.         popad
  2361.         pop     edi
  2362.         xor     eax, eax
  2363.         cmp     [FDC_Status], 0
  2364.         jz      @f
  2365.         mov     al, 11
  2366. @@:
  2367. .doret:
  2368.         mov     [fdc_irq_func], fdc_null
  2369.         ret
  2370. .expand:
  2371.         push    ecx
  2372.         push    dword [edi+28]  ; save old size
  2373.         mov     ecx, eax
  2374.         call    floppy_extend_file
  2375.         push    eax     ; return code
  2376.         jnc     .expand_ok
  2377.         cmp     al, ERROR_DISK_FULL
  2378.         jz      .disk_full
  2379.         pop     eax ecx ecx edi edi
  2380.         jmp     .doret
  2381. .device_err:
  2382.         pop     eax
  2383. .device_err2:
  2384.         pop     ecx ecx eax edi
  2385.         push    11
  2386.         jmp     .ret
  2387. .disk_full:
  2388. .expand_ok:
  2389. ; save directory & FAT
  2390.         mov     eax, [edi+28]
  2391.         xchg    eax, [esp+12]
  2392.         movzx   edi, word [edi+26]
  2393.         pusha
  2394.         call    save_chs_sector
  2395.         popa
  2396.         cmp     [FDC_Status], 0
  2397.         jnz     .device_err
  2398.         call    save_flp_fat
  2399.         cmp     [FDC_Status], 0
  2400.         jnz     .device_err
  2401.         call    SetUserInterrupts
  2402. ; now zero new data
  2403. ; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code
  2404. .zero_loop:
  2405.         sub     dword [esp+4], 0x200
  2406.         jae     .next_cluster
  2407.         cmp     dword [esp+4], -0x200
  2408.         jz      .noread
  2409.         lea     eax, [edi+31]
  2410.         pusha
  2411.         call    read_chs_sector
  2412.         popa
  2413.         cmp     [FDC_Status], 0
  2414.         jnz     .err_next
  2415. .noread:
  2416.         mov     ecx, [esp+4]
  2417.         neg     ecx
  2418.         push    edi
  2419.         mov     edi, FDD_BUFF+0x200
  2420.         add     edi, [esp+8]
  2421.         xor     eax, eax
  2422.         mov     [esp+8], eax
  2423.         rep     stosb
  2424.         pop     edi
  2425.         lea     eax, [edi+31]
  2426.         pusha
  2427.         call    save_chs_sector
  2428.         popa
  2429.         cmp     [FDC_Status], 0
  2430.         jz      .next_cluster
  2431. .err_next:
  2432.         mov     byte [esp], 11
  2433. .next_cluster:
  2434.         sub     dword [esp+12], 0x200
  2435.         jbe     .expand_done
  2436.         movzx   edi, word [FLOPPY_FAT+edi*2]
  2437.         jmp     .zero_loop
  2438. .expand_done:
  2439.         pop     eax ecx ecx edi edi
  2440.         jmp     .doret
  2441. .truncate:
  2442.         mov     [edi+28], eax
  2443.         push    ecx
  2444.         movzx   ecx, word [edi+26]
  2445.         test    eax, eax
  2446.         jz      .zero_size
  2447. ; find new last sector
  2448. @@:
  2449.         sub     eax, 0x200
  2450.         jbe     @f
  2451.         movzx   ecx, word [FLOPPY_FAT+ecx*2]
  2452.         jmp     @b
  2453. @@:
  2454. ; we will zero data at the end of last sector - remember it
  2455.         push    ecx
  2456. ; terminate FAT chain
  2457.         lea     ecx, [FLOPPY_FAT+ecx+ecx]
  2458.         push    dword [ecx]
  2459.         mov     word [ecx], 0xFFF
  2460.         pop     ecx
  2461.         and     ecx, 0xFFF
  2462.         jmp     .delete
  2463. .zero_size:
  2464.         and     word [edi+26], 0
  2465.         push    0
  2466. .delete:
  2467. ; delete FAT chain starting with ecx
  2468. ; mark all clusters as free
  2469.         cmp     ecx, 0xFF8
  2470.         jae     .deleted
  2471.         lea     ecx, [FLOPPY_FAT+ecx+ecx]
  2472.         push    dword [ecx]
  2473.         and     word [ecx], 0
  2474.         pop     ecx
  2475.         and     ecx, 0xFFF
  2476.         jmp     .delete
  2477. .deleted:
  2478.         mov     edi, [edi+28]
  2479. ; save directory & FAT
  2480.         mov     eax, [esp+8]
  2481.         pusha
  2482.         call    save_chs_sector
  2483.         popa
  2484.         cmp     [FDC_Status], 0
  2485.         jnz     .device_err2
  2486.         call    save_flp_fat
  2487.         cmp     [FDC_Status], 0
  2488.         jnz     .device_err2
  2489. ; zero last sector, ignore errors
  2490.         pop     eax
  2491.         add     eax, 31
  2492.         and     edi, 0x1FF
  2493.         jz      .truncate_done
  2494.         call    SetUserInterrupts
  2495.         pusha
  2496.         call    read_chs_sector
  2497.         popa
  2498.         add     edi, FDD_BUFF
  2499.         mov     ecx, FDD_BUFF+0x200
  2500.         sub     ecx, edi
  2501.         push    eax
  2502.         xor     eax, eax
  2503.         rep     stosb
  2504.         pop     eax
  2505.         pusha
  2506.         call    save_chs_sector
  2507.         popa
  2508. .truncate_done:
  2509.         pop     ecx eax edi
  2510.         xor     eax, eax
  2511.         jmp     .doret
  2512.  
  2513. fs_FloppyGetFileInfo:
  2514.         call    read_flp_fat
  2515.         cmp     [FDC_Status], 0
  2516.         jnz     ret11
  2517.         cmp     byte [esi], 0
  2518.         jnz     @f
  2519.         mov     eax, 2  ; unsupported
  2520.         ret
  2521. @@:
  2522.         push    edi
  2523.         call    fd_find_lfn
  2524.         jmp     fs_GetFileInfo_finish
  2525.  
  2526. ret11:
  2527.         mov     eax, 11
  2528.         ret
  2529.  
  2530. fs_FloppySetFileInfo:
  2531.         call    read_flp_fat
  2532.         cmp     [FDC_Status], 0
  2533.         jnz     ret11
  2534.         cmp     byte [esi], 0
  2535.         jnz     @f
  2536.         mov     eax, 2  ; unsupported
  2537.         ret
  2538. @@:
  2539.         push    edi
  2540.         call    fd_find_lfn
  2541.         jnc     @f
  2542.         pop     edi
  2543.         mov     eax, ERROR_FILE_NOT_FOUND
  2544.         ret
  2545. @@:
  2546.         push    eax
  2547.         call    bdfe_to_fat_entry
  2548.         pop     eax
  2549.         pusha
  2550.         call    save_chs_sector
  2551.         popa
  2552.         pop     edi
  2553.         xor     eax, eax
  2554.         cmp     [FDC_Status], 0
  2555.         jz      @f
  2556.         mov     al, 11
  2557. @@:
  2558.         ret
  2559.  
  2560. if 0
  2561. ;----------------------------------------------------------------
  2562. ;
  2563. ;  fs_FloppyExecute - LFN variant for executing from floppy
  2564. ;
  2565. ;  esi  points to floppy filename (e.g. 'dir1/name')
  2566. ;  ebp  points to full filename (e.g. '/fd/1/dir1/name')
  2567. ;  dword [ebx] = flags
  2568. ;  dword [ebx+4] = cmdline
  2569. ;
  2570. ;  ret ebx,edx destroyed
  2571. ;      eax > 0 - PID, < 0 - error
  2572. ;
  2573. ;--------------------------------------------------------------
  2574. fs_FloppyExecute:
  2575.         mov     edx, [ebx]
  2576.         mov     ebx, [ebx+4]
  2577.         test    ebx, ebx
  2578.         jz      @f
  2579.         add     ebx, std_application_base_address
  2580. @@:
  2581.  
  2582. ;----------------------------------------------------------------
  2583. ;
  2584. ; fs_FloppyExecute.flags - second entry
  2585. ;
  2586. ;  esi  points to floppy filename (kernel address)
  2587. ;  ebp  points to full filename
  2588. ;  edx  flags
  2589. ;  ebx  cmdline (kernel address)
  2590. ;
  2591. ;  ret  eax > 0 - PID, < 0 - error
  2592. ;
  2593. ;--------------------------------------------------------------
  2594.  
  2595. .flags:
  2596.         call    read_flp_fat
  2597.         cmp     byte [esi], 0
  2598.         jnz     @f
  2599. ; cannot execute root!
  2600.         mov     eax, -ERROR_ACCESS_DENIED
  2601.         ret
  2602. @@:
  2603.         push    edi
  2604.         call    fd_find_lfn
  2605.         jnc     .found
  2606.         pop     edi
  2607.         mov     eax, -ERROR_FILE_NOT_FOUND
  2608.         ret
  2609. .found:
  2610.         movzx   eax, word [edi+26]      ; cluster
  2611.         push    eax
  2612.         push    dword [edi+28]          ; size
  2613.         push    .DoRead
  2614.         call    fs_execute
  2615.         add     esp, 12
  2616.         pop     edi
  2617.         ret
  2618.  
  2619. .DoRead:
  2620. ; read next block
  2621. ; in: eax->parameters, edi->buffer
  2622. ; out: eax = error code
  2623.         pushad
  2624.         cmp     dword [eax], 0  ; file size
  2625.         jz      .eof
  2626.         mov     eax, [eax+4]    ; cluster
  2627.         add     eax, 31
  2628.         call    read_chs_sector
  2629.         cmp     [FDC_Status], 0
  2630.         jnz     .err
  2631.         pop     edi
  2632.         mov     esi, FDD_BUFF
  2633.         push    edi
  2634.         mov     ecx, 512/4
  2635.         rep     movsd
  2636.         mov     eax, [esp+28]
  2637.         mov     ecx, [eax]
  2638.         sub     ecx, 512
  2639.         jae     @f
  2640.         add     edi, ecx
  2641.         neg     ecx
  2642.         push    eax
  2643.         xor     eax, eax
  2644.         rep     stosb
  2645.         pop     eax
  2646. @@:
  2647.         mov     [eax], ecx
  2648.         mov     edx, [eax+4]
  2649.         mov     dx, [edx*2+FLOPPY_FAT]
  2650.         mov     [eax+4], dx     ; high word is already zero
  2651.         popad
  2652.         xor     eax, eax
  2653.         ret
  2654. .eof:
  2655.         popad
  2656.         mov     eax, 6
  2657.         ret
  2658. .err:
  2659.         popad
  2660.         mov     eax, 11
  2661.         ret
  2662. end if
  2663.  
  2664. ;----------------------------------------------------------------
  2665. ;
  2666. ;  fs_FloppyDelete - delete file or empty folder from floppy
  2667. ;
  2668. ;  esi  points to filename
  2669. ;
  2670. ;  ret  eax = 0 ok or other = errormsg
  2671. ;
  2672. ;--------------------------------------------------------------
  2673. fs_FloppyDelete:
  2674.         call    read_flp_fat
  2675.         cmp     [FDC_Status], 0
  2676.         jz      @f
  2677.         push    11
  2678.         jmp     .pop_ret
  2679. @@:
  2680.         cmp     byte [esi], 0
  2681.         jnz     @f
  2682. ; cannot delete root!
  2683. .access_denied:
  2684.         push    ERROR_ACCESS_DENIED
  2685. .pop_ret:
  2686.         pop     eax
  2687.         ret
  2688. @@:
  2689.         and     [fd_prev_sector], 0
  2690.         and     [fd_prev_prev_sector], 0
  2691.         push    edi
  2692.         call    fd_find_lfn
  2693.         jnc     .found
  2694.         pop     edi
  2695.         push    ERROR_FILE_NOT_FOUND
  2696.         jmp     .pop_ret
  2697. .found:
  2698.         cmp     dword [edi], '.   '
  2699.         jz      .access_denied2
  2700.         cmp     dword [edi], '..  '
  2701.         jz      .access_denied2
  2702.         test    byte [edi+11], 10h
  2703.         jz      .dodel
  2704. ; we can delete only empty folders!
  2705.         push    eax
  2706.         movzx   eax, word [edi+26]
  2707.         push    ebx
  2708.         pusha
  2709.         add     eax, 31
  2710.         call    read_chs_sector
  2711.         popa
  2712.         mov     ebx, FDD_BUFF + 2*0x20
  2713. .checkempty:
  2714.         cmp     byte [ebx], 0
  2715.         jz      .empty
  2716.         cmp     byte [ebx], 0xE5
  2717.         jnz     .notempty
  2718.         add     ebx, 0x20
  2719.         cmp     ebx, FDD_BUFF + 0x200
  2720.         jb      .checkempty
  2721.         movzx   eax, word [FLOPPY_FAT + eax*2]
  2722.         pusha
  2723.         add     eax, 31
  2724.         call    read_chs_sector
  2725.         popa
  2726.         mov     ebx, FDD_BUFF
  2727.         jmp     .checkempty
  2728. .notempty:
  2729.         pop     ebx
  2730.         pop     eax
  2731. .access_denied2:
  2732.         pop     edi
  2733.         jmp     .access_denied
  2734. .empty:
  2735.         pop     ebx
  2736.         pop     eax
  2737.         pusha
  2738.         call    read_chs_sector
  2739.         popa
  2740. .dodel:
  2741.         push    eax
  2742.         movzx   eax, word [edi+26]
  2743.         xchg    eax, [esp]
  2744. ; delete folder entry
  2745.         mov     byte [edi], 0xE5
  2746. ; delete LFN (if present)
  2747. .lfndel:
  2748.         cmp     edi, FDD_BUFF
  2749.         ja      @f
  2750.         cmp     [fd_prev_sector], 0
  2751.         jz      .lfndone
  2752.         push    [fd_prev_sector]
  2753.         push    [fd_prev_prev_sector]
  2754.         pop     [fd_prev_sector]
  2755.         and     [fd_prev_prev_sector], 0
  2756.         pusha
  2757.         call    save_chs_sector
  2758.         popa
  2759.         pop     eax
  2760.         pusha
  2761.         call    read_chs_sector
  2762.         popa
  2763.         mov     edi, FDD_BUFF+0x200
  2764. @@:
  2765.         sub     edi, 0x20
  2766.         cmp     byte [edi], 0xE5
  2767.         jz      .lfndone
  2768.         cmp     byte [edi+11], 0xF
  2769.         jnz     .lfndone
  2770.         mov     byte [edi], 0xE5
  2771.         jmp     .lfndel
  2772. .lfndone:
  2773.         pusha
  2774.         call    save_chs_sector
  2775.         popa
  2776. ; delete FAT chain
  2777.         pop     eax
  2778.         test    eax, eax
  2779.         jz      .done
  2780. @@:
  2781.         lea     eax, [FLOPPY_FAT + eax*2]
  2782.         push    dword [eax]
  2783.         and     word [eax], 0
  2784.         pop     eax
  2785.         and     eax, 0xFFF
  2786.         jnz     @b
  2787. .done:
  2788.         call    save_flp_fat
  2789.         pop     edi
  2790.         xor     eax, eax
  2791.         ret
  2792.  
  2793. ; \end{diamond}
  2794.