Subversion Repositories Kolibri OS

Rev

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

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