Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                      ;;
  3. ;; FAT12.INC                                                            ;;
  4. ;; (C) 2005 Mario79, License: GPL                                       ;;
  5. ;;                                                                      ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. n_sector    dd 0  ; temporary save for sector value
  9. flp_status  dd 0
  10. clust_tmp_flp dd 0  ; used by analyze_directory and analyze_directory_to_write
  11. path_pointer_flp dd 0
  12. pointer_file_name_flp dd 0
  13. save_root_flag db 0
  14. save_flag   db 0
  15. root_read   db 0  ; 0-necessary to load root, 1-not to load root
  16. flp_fat     db 0  ; 0-necessary to load fat, 1-not to load fat
  17. flp_number  db 0  ; 1- Floppy A, 2-Floppy B
  18. old_track   db 0  ; old value track
  19. flp_label   rb 15 ; Label and ID of inserted floppy disk
  20.  
  21. reserve_flp:
  22.  
  23.     cli
  24.     cmp   [flp_status],0
  25.     je    reserve_flp_ok
  26.  
  27.     sti
  28.     call  change_task
  29.     jmp   reserve_flp
  30.  
  31.   reserve_flp_ok:
  32.  
  33.     push  eax
  34.     mov   eax,[0x3000]
  35.     shl   eax,5
  36.     mov   eax,[eax+0x3000+4]
  37.     mov   [flp_status],eax
  38.     pop   eax
  39.     sti
  40.     ret
  41.  
  42. floppy_free_space:
  43. ;---------------------------------------------
  44. ;
  45. ; returns free space in edi
  46. ;
  47. ;---------------------------------------------
  48.     push   eax ebx ecx
  49.     call   read_flp_fat
  50.     cmp    [FDC_Status],0
  51.     jne    fdc_status_error_2
  52.     mov    eax,0x282000
  53.     xor    edi,edi
  54.     mov    ecx,2847   ;1448000/512
  55. rdfs1_1:
  56.     mov    ebx,[eax]
  57.     and    ebx,4095
  58.     cmp    ebx,0
  59.     jne    rdfs2_1
  60.     add    edi,512
  61. rdfs2_1:
  62.     add    eax,2
  63.     loop   rdfs1_1
  64. fdc_status_error_2:
  65.     pop    ecx ebx eax
  66.     ret
  67.    
  68.  
  69.    
  70.  
  71. floppy_fileread:
  72. ;----------------------------------------------------------------
  73. ;
  74. ;  fileread - sys floppy
  75. ;
  76. ;  eax  points to filename 11 chars  - for root directory
  77. ;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
  78. ;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
  79. ;  edx  mem location to return data
  80. ;  esi  length of filename 12*X
  81. ;  edi  pointer to path   /fd/1/......  - for all files in nested directories
  82. ;
  83. ;  ret ebx = size or 0xffffffff file not found
  84. ;      eax = 0 ok read or other = errormsg
  85. ;            10 = access denied
  86. ;--------------------------------------------------------------
  87.  
  88.     mov    [save_flag],0
  89.     mov    [path_pointer_flp],edi
  90.     cmp    esi,0           ; return ramdisk root
  91.     jne    fr_noroot_1
  92.     cmp    ebx,224/16
  93.     jbe    fr_do_1
  94.     mov    eax,5
  95.     mov    ebx,0
  96.     mov   [flp_status],0
  97.     ret
  98.  
  99. fr_do_1:
  100.     push ebx ecx edx
  101.     call  read_flp_root
  102.     pop edx ecx ebx
  103.     cmp    [FDC_Status],0
  104.     jne    fdc_status_error_1
  105.     mov    edi,edx
  106.     dec    ebx
  107.     shl    ebx,9
  108.     mov    esi,0x8000
  109.     add    esi,ebx
  110.     shl    ecx,9
  111.     cld
  112.     rep    movsb
  113.     mov    eax,0 ; ok read
  114.     mov    ebx,0
  115.     mov   [flp_status],0
  116.     ret
  117. fdc_status_error_1:
  118.     mov   [flp_status],0
  119.     mov    eax,10
  120.     mov    ebx,-1
  121.     ret
  122.  
  123. fr_noroot_1:
  124.     sub    esp,32
  125.     call   expand_filename
  126. frfloppy_1:
  127.     cmp    ebx,0
  128.     jne    frfl5_1
  129.     mov    ebx,1
  130. frfl5_1:
  131.     cmp    ecx,0
  132.     jne    frfl6_1
  133.     mov    ecx,1
  134. frfl6_1:
  135.     dec    ebx
  136.     push   eax
  137.     push   eax ebx ecx edx esi edi
  138.     call   read_flp_fat
  139.     cmp    [FDC_Status],0
  140.     jne    fdc_status_error_3_1
  141.     mov    [FDD_Track],0      ; Öèëèíäð
  142.     mov    [FDD_Head],1      ; Ñòîðîíà
  143.     mov    [FDD_Sector],2      ; Ñåêòîð
  144.     call    SeekTrack
  145.     mov     dh,14
  146. l.20_1:
  147.     call    ReadSectWithRetr
  148.     cmp    [FDC_Status],0
  149.     jne    fdc_status_error_3_1
  150.     mov     dl,16
  151.     mov     edi,0xD000
  152.     inc     [FDD_Sector]
  153. l.21_1:
  154.     mov    esi,eax            ;Name of file we want
  155.     mov    ecx,11
  156.     cld
  157.     rep    cmpsb            ;Found the file?
  158.     je     fifound_1          ;Yes
  159.     add    ecx,21
  160.     add    edi, ecx         ;Advance to next entry
  161.     dec    dl
  162.     cmp    dl,0
  163.     jne    l.21_1
  164.     dec    dh
  165.     cmp    dh,0
  166.     jne    l.20_1
  167. fdc_status_error_3:
  168.     mov    eax,5            ; file not found ?
  169.     mov    ebx,-1
  170.     add    esp,32+28
  171.     mov   [flp_status],0
  172.     ret
  173. fdc_status_error_3_2:
  174.     cmp    [FDC_Status],0
  175.     je    fdc_status_error_3
  176. fdc_status_error_3_1:
  177.     add    esp,32+28
  178.     jmp    fdc_status_error_1
  179.  
  180. fifound_1:
  181.     mov    eax,[path_pointer_flp]
  182.     cmp    [eax+36],byte 0
  183.     je     fifound_2
  184.     add    edi,0xf
  185.     mov    eax,[edi]
  186.     and    eax,65535
  187.     mov    ebx,[path_pointer_flp]
  188.     add    ebx,36
  189.     call   get_cluster_of_a_path_flp
  190.     jc     fdc_status_error_3_2
  191.     mov    ebx,[ebx-11+28]        ;file size
  192.     mov    [esp+20],ebx
  193.     mov    [esp+24],ebx
  194.     jmp     fifound_3
  195. fifound_2:
  196.     mov    ebx,[edi-11+28]        ;file size
  197.     mov    [esp+20],ebx
  198.     mov    [esp+24],ebx
  199.     add    edi,0xf
  200.     mov    eax,[edi]
  201. fifound_3:
  202.     and    eax,65535
  203.     mov    [n_sector],eax            ;eax=cluster
  204. frnew_1:
  205.     add    eax,31            ;bootsector+2*fat+filenames
  206.     cmp    [esp+16],dword 0     ; wanted cluster ?
  207.     jne    frfl7_1
  208.     call   read_chs_sector
  209.     cmp    [FDC_Status],0
  210.     jne    fdc_status_error_5
  211.     mov    edi,[esp+8]
  212.     call    give_back_application_data_1
  213.     add    [esp+8],dword 512
  214.     dec    dword [esp+12]        ; last wanted cluster ?
  215.     cmp    [esp+12],dword 0
  216.     je     frnoread_1
  217.     jmp    frfl8_1
  218. frfl7_1:
  219.     dec    dword [esp+16]
  220. frfl8_1:
  221.     mov    edi,[n_sector]
  222.     shl    edi,1            ;find next cluster from FAT
  223.     add    edi,0x282000
  224.     mov    eax,[edi]
  225.     and    eax,4095
  226.     mov    edi,eax
  227.     mov    [n_sector],edi
  228.     cmp    edi,4095         ;eof  - cluster
  229.     jz     frnoread2_1
  230.     cmp    [esp+24],dword 512    ;eof  - size
  231.     jb     frnoread_1
  232.     sub    [esp+24],dword 512
  233.     jmp    frnew_1
  234.  
  235. read_chs_sector:    
  236.     call    calculate_chs
  237.     call    ReadSectWithRetr
  238.     ret
  239.  
  240. frnoread2_1:
  241.     cmp    [esp+16],dword 0     ; eof without read ?
  242.     je     frnoread_1
  243.     mov    [fdc_irq_func],fdc_null
  244.     pop    edi esi edx ecx
  245.     add    esp,4
  246.     pop    ebx     ; ebx <- eax : size of file
  247.     add    esp,36
  248.     mov    eax,6   ; end of file
  249.     mov    [flp_status],0
  250.     ret
  251.  
  252. frnoread_1:
  253.     pop    edi esi edx ecx
  254.     add    esp,4
  255.     pop    ebx     ; ebx <- eax : size of file
  256.     add    esp,36
  257.     mov    eax,0
  258.     mov    [flp_status],0
  259.     ret
  260.  
  261. fdc_status_error_5:
  262.     pop    edi esi edx ecx
  263.     add    esp,4
  264.     pop    ebx     ; ebx <- eax : size of file
  265.     add    esp,36
  266.     jmp    fdc_status_error_1
  267.  
  268. read_flp_root:
  269.     pusha
  270.     call  check_label
  271.     cmp    [FDC_Status],0
  272.     jne    unnecessary_root_read
  273.     cmp   [root_read],1
  274.     je    unnecessary_root_read
  275.     mov    [FDD_Track],0      ; Öèëèíäð
  276.     mov    [FDD_Head],1      ; Ñòîðîíà
  277.     mov    [FDD_Sector],2      ; Ñåêòîð    
  278.     mov    edi,0x8000
  279.     call   SeekTrack
  280. read_flp_root_1:
  281.     call   ReadSectWithRetr
  282.     cmp    [FDC_Status],0
  283.     jne    unnecessary_root_read
  284.     push   edi
  285.     call   give_back_application_data_1
  286.     pop    edi
  287.     add    edi,512
  288.     inc    [FDD_Sector]
  289.     cmp    [FDD_Sector],16
  290.     jne    read_flp_root_1
  291.     mov    [root_read],1
  292. unnecessary_root_read:
  293.     popa
  294.     ret
  295.  
  296.  
  297. read_flp_fat:
  298.     pusha
  299.     call  check_label
  300.     cmp    [FDC_Status],0
  301.     jne    unnecessary_flp_fat
  302.     cmp   [flp_fat],1
  303.     je    unnecessary_flp_fat
  304.     mov    [FDD_Track],0      ; Öèëèíäð
  305.     mov    [FDD_Head],0      ; Ñòîðîíà
  306.     mov    [FDD_Sector],2      ; Ñåêòîð    
  307.     mov    edi,0x8000
  308.     call   SeekTrack
  309. read_flp_fat_1:
  310.     call   ReadSectWithRetr
  311.     cmp    [FDC_Status],0
  312.     jne    unnecessary_flp_fat
  313.     push   edi
  314.     call   give_back_application_data_1
  315.     pop    edi
  316.     add    edi,512
  317.     inc    [FDD_Sector]
  318.     cmp    [FDD_Sector],19
  319.     jne    read_flp_fat_1
  320.     mov    [FDD_Sector],1
  321.     mov    [FDD_Head],1
  322.     call   ReadSectWithRetr
  323.     cmp    [FDC_Status],0
  324.     jne    unnecessary_flp_fat
  325.     call   give_back_application_data_1
  326.     call   calculatefatchain_flp
  327.     mov    [root_read],0
  328.     mov    [flp_fat],1
  329. unnecessary_flp_fat:
  330.     popa
  331.     ret
  332.  
  333. calculatefatchain_flp:
  334.    pushad
  335.  
  336.    mov  esi,0x8000
  337.    mov  edi,0x282000
  338.  
  339.  fcnew_1:
  340.    mov  eax,dword [esi]
  341.    mov  ebx,dword [esi+4]
  342.    mov  ecx,dword [esi+8]
  343.    mov  edx,ecx
  344.    shr  edx,4   ;8 ok
  345.    shr  dx,4    ;7 ok
  346.    xor  ch,ch
  347.    shld ecx,ebx,20 ;6 ok
  348.    shr  cx,4     ;5 ok
  349.    shld ebx,eax,12
  350.    and  ebx,0x0fffffff  ;4 ok
  351.    shr  bx,4    ;3 ok
  352.    shl  eax,4
  353.    and  eax,0x0fffffff  ;2 ok
  354.    shr  ax,4  ;1 ok
  355.    mov dword [edi],eax
  356.    add  edi,4
  357.    mov dword [edi],ebx
  358.    add  edi,4
  359.    mov dword [edi],ecx
  360.    add  edi,4
  361.    mov dword [edi],edx
  362.    add  edi,4  
  363.    add  esi,12
  364.  
  365.    cmp  edi,0x282000+2856*2   ;2849 clusters
  366.    jnz  fcnew_1
  367.  
  368.    popad
  369.    ret
  370.  
  371. check_label:
  372.     pushad
  373.     mov    [FDD_Track],0      ; Öèëèíäð
  374.     mov    [FDD_Head],0      ; Ñòîðîíà
  375.     mov    [FDD_Sector],1      ; Ñåêòîð  
  376.     call   SetUserInterrupts
  377.     call   FDDMotorON
  378.     call   RecalibrateFDD
  379.     cmp    [FDC_Status],0
  380.     jne    fdc_status_error
  381.     call   SeekTrack
  382.     cmp    [FDC_Status],0
  383.     jne    fdc_status_error
  384.     call   ReadSectWithRetr
  385.     cmp    [FDC_Status],0
  386.     jne    fdc_status_error    
  387.     mov    esi,flp_label
  388.     mov    edi,0xD000+39
  389.     mov    ecx,15
  390.     cld
  391.     rep    cmpsb    
  392.     je     same_label
  393.     mov    [root_read],0
  394.     mov    [flp_fat],0
  395. same_label:
  396.     mov    esi,0xD000+39
  397.     mov    edi,flp_label
  398.     mov    ecx,15
  399.     cld
  400.     rep    movsb
  401.     popad
  402.     ret
  403. fdc_status_error:
  404.     popad
  405.     ret
  406.  
  407. save_flp_root:
  408.     pusha
  409.     call  check_label
  410.     cmp    [FDC_Status],0
  411.     jne    unnecessary_root_save
  412.     cmp   [root_read],0
  413.     je    unnecessary_root_save
  414.     mov    [FDD_Track],0      ; Öèëèíäð
  415.     mov    [FDD_Head],1      ; Ñòîðîíà
  416.     mov    [FDD_Sector],2      ; Ñåêòîð    
  417.     mov    esi,0x8000
  418.     call   SeekTrack
  419. save_flp_root_1:
  420.     push   esi
  421.     call   take_data_from_application_1
  422.     pop    esi
  423.     add    esi,512
  424.     call   WriteSectWithRetr
  425.     cmp    [FDC_Status],0
  426.     jne    unnecessary_root_save
  427.     inc    [FDD_Sector]
  428.     cmp    [FDD_Sector],16
  429.     jne    save_flp_root_1
  430. unnecessary_root_save:
  431.     mov    [fdc_irq_func],fdc_null
  432.     popa
  433.     ret
  434.    
  435. save_flp_fat:
  436.     pusha
  437.     call  check_label
  438.     cmp    [FDC_Status],0
  439.     jne    unnecessary_flp_fat_save
  440.     cmp   [flp_fat],0
  441.     je    unnecessary_flp_fat_save
  442.     call   restorefatchain_flp
  443.     mov    [FDD_Track],0      ; Öèëèíäð
  444.     mov    [FDD_Head],0      ; Ñòîðîíà
  445.     mov    [FDD_Sector],2      ; Ñåêòîð    
  446.     mov    esi,0x8000
  447.     call   SeekTrack
  448. save_flp_fat_1:
  449.     push   esi
  450.     call   take_data_from_application_1
  451.     pop    esi
  452.     add    esi,512
  453.     call   WriteSectWithRetr
  454.     cmp    [FDC_Status],0
  455.     jne    unnecessary_flp_fat_save
  456.     inc    [FDD_Sector]
  457.     cmp    [FDD_Sector],19
  458.     jne    save_flp_fat_1
  459.     mov    [FDD_Sector],1
  460.     mov    [FDD_Head],1
  461.     call   take_data_from_application_1
  462.     call   WriteSectWithRetr
  463.     cmp    [FDC_Status],0
  464.     jne    unnecessary_flp_fat_save
  465.     mov    [root_read],0
  466. unnecessary_flp_fat_save:
  467.     mov    [fdc_irq_func],fdc_null
  468.     popa
  469.     ret
  470.  
  471.    
  472. restorefatchain_flp:   ; restore fat chain
  473.    pushad
  474.  
  475.    mov  esi,0x282000
  476.    mov  edi,0x8000
  477.  
  478.   fcnew2_1:
  479.    mov  eax,dword [esi]
  480.    mov  ebx,dword [esi+4]
  481.    shl  ax,4
  482.    shl  eax,4
  483.    shl  bx,4
  484.    shr  ebx,4
  485.    shrd eax,ebx,8
  486.    shr  ebx,8
  487.    mov dword [edi],eax
  488.    add  edi,4
  489.    mov word [edi],bx
  490.    add  edi,2
  491.    add  esi,8
  492.  
  493.    cmp  edi,0x8000+0x1200     ;4274 bytes - all used FAT
  494.    jb   fcnew2_1
  495.  
  496.    mov  esi,0x8000           ; duplicate fat chain
  497.    mov  edi,0x8000+0x1200
  498.    mov  ecx,0x1200/4
  499.    cld
  500.    rep  movsd
  501.  
  502.    popad
  503.    ret
  504.  
  505.  
  506. floppy_filedelete:
  507. ;--------------------------------------------
  508. ;
  509. ; filedelete - sys floppy
  510. ; in:
  511. ; eax - filename 11 chars - for root directory
  512. ; edi  pointer to path   /fd/1/...... - for all files in nested directories
  513. ;
  514. ; out:
  515. ; eax - 0 = successful, 1 = file not found, 10 = access denied
  516. ;
  517. ;--------------------------------------------
  518.     mov    [path_pointer_flp],edi
  519.     mov    [save_flag],0
  520.     mov    ebp,1  ; file not found as default
  521. filedelete_newtry_1:
  522.     sub    esp,32
  523.     call   expand_filename
  524.     push   eax ebx ecx edx esi edi
  525.     call   read_flp_fat
  526.     cmp    [FDC_Status],0
  527.     jne    frnoreadd_1
  528.     mov    [FDD_Track],0      ; Öèëèíäð
  529.     mov    [FDD_Head],1      ; Ñòîðîíà
  530.     mov    [FDD_Sector],2      ; Ñåêòîð
  531.     call    SeekTrack
  532.     mov     dh,14
  533. l.20_2:
  534.     call    ReadSectWithRetr
  535.     cmp    [FDC_Status],0
  536.     jne    fdc_status_error_4
  537.     mov     dl,16
  538.     mov     edi,0xD000
  539.     inc     [FDD_Sector]
  540. l.21_2:
  541.     mov    esi,eax            ;Name of file we want
  542.     mov    ecx,11
  543.     cld
  544.     rep    cmpsb            ;Found the file?
  545.     je     fifoundd_1          ;Yes
  546.     add    ecx,21
  547.     add    edi, ecx         ;Advance to next entry
  548.     dec    dl
  549.     cmp    dl,0
  550.     jne    l.21_2
  551.     dec    dh
  552.     cmp    dh,0
  553.     jne    l.20_2
  554.     jmp    frnoreadd_1
  555.  
  556. fdc_status_error_4:
  557.     pop    edi esi edx ecx ebx eax
  558.     add    esp,32
  559.     jmp    fdc_status_error_1
  560.  
  561. fifoundd_1:
  562.     mov    eax,[path_pointer_flp]
  563.     cmp    [eax+36],byte 0
  564.     je    fifoundd_2
  565.     add    edi,0xf
  566.     mov    eax,[edi]
  567.     and    eax,65535
  568.     mov    ebx,[path_pointer_flp]
  569.     add    ebx,36
  570.     call   get_cluster_of_a_path_flp
  571.     jc     frnoreadd_1_1    
  572.     mov    edi,ebx
  573.     add    edi,11
  574.     jmp    fifoundd_2_1
  575. fifoundd_2:
  576.     dec    [FDD_Sector]
  577. fifoundd_2_1:
  578.     mov    [edi-11],byte 0xE5    ;mark filename deleted
  579.     add    edi,0xf
  580.     mov    eax,[edi]
  581.     and    eax,65535
  582.     mov    edi,eax            ;edi = cluster
  583. frnewd_1:
  584.     shl    edi,1            ;find next cluster from FAT
  585.     add    edi,0x282000
  586.     mov    eax,[edi]
  587.     mov    [edi],word 0x0        ;clear fat chain cluster
  588.     and    eax,4095
  589.     mov    edi,eax
  590.     cmp    edi,dword 4095        ;last cluster ?
  591.     jz     frnoreadd2_1
  592.     jmp    frnewd_1
  593.  
  594. frnoreadd2_1:
  595.     call   WriteSectWithRetr
  596.     cmp    [FDC_Status],0
  597.     jne    fdc_status_error_4
  598.     call   save_flp_fat
  599.     cmp    [FDC_Status],0
  600.     jne    fdc_status_error_4
  601. ;    pop    edi esi edx ecx ebx eax
  602. ;    add    esp,32
  603.     mov    ebp,0       ; file found
  604. ;    jmp    filedelete_newtry_1
  605.     jmp    frnoreadd_1
  606.  
  607. frnoreadd_1_1:
  608.     cmp    [FDC_Status],0
  609.     jne    fdc_status_error_4
  610. frnoreadd_1:
  611.     pop    edi esi edx ecx ebx eax
  612.     add    esp,32
  613.     mov    eax,ebp
  614.     ret
  615.  
  616. floppy_filesave:
  617. ;----------------------------------------------------------
  618. ;
  619. ; filesave - sys floppy
  620. ;
  621. ; eax      ; pointer to file name 11 chars - for root directory
  622. ; ebx      ; buffer
  623. ; ecx      ; count to write in bytes
  624. ; edx      ; 0 create new , 1 append
  625. ; edi  pointer to path   /fd/1/......  - for all files in nested directories
  626. ;
  627. ; output : eax = 0 - ok
  628. ;                5 - file not found / directory not found
  629. ;                8 - disk full
  630. ;               10 - access denied
  631. ;-----------------------------------------------------------
  632.     mov    [path_pointer_flp],edi
  633.     sub  esp,32
  634.     call expand_filename
  635.     cmp  edx,0
  636.     jnz  fsdel_1
  637.     pusha
  638.     call floppy_filedelete
  639.     cmp    [FDC_Status],0
  640.     jne    fdc_status_error_6
  641.     popa
  642.     mov    [save_flag],1
  643. fsdel_1:
  644.     call   floppy_free_space
  645.     cmp    [FDC_Status],0
  646.     jne    fdc_status_error_6
  647.     cmp    ecx,edi
  648.     jb     rd_do_save_1
  649.     add    esp,32
  650.     mov    eax,8    ; not enough free space
  651.     mov   [flp_status],0
  652.     ret
  653.  
  654. fdc_status_error_6:
  655.     popa
  656.     add    esp,32
  657.     jmp    fdc_status_error_1
  658.    
  659. rd_do_save_1:
  660.     push   eax ebx ecx edx esi edi
  661.     call   read_flp_fat
  662.     cmp    [FDC_Status],0
  663.     jne    fdc_status_error_7
  664.     push   eax
  665.     mov    eax,[path_pointer_flp]
  666.     cmp    [eax+36],byte 0
  667.     jne    fifoundds_2
  668.     pop    eax
  669.     mov    [save_root_flag],1
  670.     call   read_flp_root
  671.     cmp    [FDC_Status],0
  672.     jne    fdc_status_error_7
  673.     mov    edi,0x8000   ;Point at directory
  674.     mov    edx,224 +1
  675.     ; find an empty spot for filename in the root dir
  676. l20ds_1:
  677.     sub    edx,1
  678.     cmp    edx,0
  679.     jnz    l21ds_1
  680.     jmp    frnoreadds_1
  681. l21ds_1:
  682.     cmp    [edi],byte 0xE5
  683.     jz     fifoundds_1
  684.     cmp    [edi],byte 0x0
  685.     jz     fifoundds_1
  686.     add    edi,32            ; Advance to next entry
  687.     jmp    l20ds_1
  688.  
  689. fifoundds_2:
  690.     pop    eax
  691.     mov    [save_root_flag],0
  692.     mov    [FDD_Track],0      ; Öèëèíäð
  693.     mov    [FDD_Head],1       ; Ñòîðîíà
  694.     mov    [FDD_Sector],2      ; Ñåêòîð
  695.     call   SeekTrack
  696.     mov    dh,14
  697. l.20_3:
  698.     call    ReadSectWithRetr
  699.     cmp    [FDC_Status],0
  700.     jne    fdc_status_error_7
  701.     mov    dl,16
  702.     mov    edi,0xD000
  703.     inc     [FDD_Sector]
  704. l.21_3:
  705.     mov    esi,eax            ;Name of file we want
  706.     mov    ecx,11
  707.     cld
  708.     rep    cmpsb            ;Found the file?
  709.     je     fifoundds_3          ;Yes
  710.     add    ecx,21
  711.     add    edi, ecx         ;Advance to next entry
  712.     dec    dl
  713.     cmp    dl,0
  714.     jne    l.21_3
  715.     dec    dh
  716.     cmp    dh,0
  717.     jne    l.20_3
  718. fdc_status_error_8:
  719.     pop     edi esi edx ecx ebx eax
  720.     mov    eax,5            ; file not found ?
  721.     mov    ebx,-1
  722.     add    esp,32
  723.     mov    [flp_status],0
  724.     ret
  725.  
  726. fifoundds_3:
  727.     add    edi,0xf
  728.     mov    eax,[edi]
  729.     and    eax,65535
  730.     mov    ebx,[path_pointer_flp]
  731.     add    ebx,36
  732.     call   get_cluster_of_a_path_flp
  733.     jc     fdc_status_error_7_1
  734. found_directory_for_writing_flp:
  735.     call   analyze_directory_to_write_flp
  736.     jc     fdc_status_error_7_1
  737.     mov    edi,ebx
  738. fifoundds_1:
  739.     push   edi            ; move the filename to root dir
  740.     mov    esi,[esp+4+20]
  741.     cmp    [save_root_flag],0
  742.     jne    fifoundds_4
  743.     mov    esi,[pointer_file_name_flp]
  744. fifoundds_4:
  745.     mov    ecx,11
  746.     cld
  747.     rep    movsb
  748.     pop    edi
  749.     mov    edx,edi
  750.     add    edx,11+0xf        ; edx <- cluster save position
  751.     mov    ebx,[esp+12]        ; save file size
  752.     mov    [edi+28],ebx
  753.     mov    [edi+11],byte 0x20    ; attribute
  754.     call   get_date_for_file     ; from FAT32.INC
  755.     mov    [edi+24],ax      ; date
  756.     mov    [edi+18],ax      ; date
  757.     call   get_time_for_file     ; from FAT32.INC
  758.     mov    [edi+22],ax      ; time
  759.     xor    ax,ax
  760.     mov    [edi+20],ax
  761.     mov    ebx,1            ; first cluster
  762.     cmp    [save_root_flag],0
  763.     jne    frnewds_1
  764.     call   frnewds_2
  765.     pusha
  766.     call   WriteSectWithRetr
  767.     popa
  768.     cmp    [FDC_Status],0
  769.     jne    fdc_status_error_7
  770.     jmp    frnewds_3
  771.  
  772. frnewds_1:
  773.     call   frnewds_2
  774. frnewds_3:
  775.     pusha                ; move save to floppy cluster
  776.     add    ebx,31
  777.     mov    eax,ebx
  778.     mov    esi,[esp+32+16]
  779.     call   take_data_from_application_1
  780.     call   save_chs_sector
  781.     cmp    [FDC_Status],0
  782.     jne    fdc_status_error_7
  783.     popa
  784.     mov    eax,[esp+12]
  785.     cmp    eax,512
  786.     jb     flnsa_1
  787.     sub    eax,512
  788.     mov    [esp+12],eax
  789.     mov    eax,[esp+16]
  790.     add    eax,512
  791.     mov    [esp+16],eax
  792.     jmp    frnewds_1
  793.  
  794. frnewds_2:
  795.     add    ebx,1
  796.     mov    edi,ebx            ; find free cluster in FAT
  797.     shl    edi,1
  798.     add    edi,0x282000
  799.     mov    eax,[edi]
  800.     and    eax,4095
  801.     cmp    eax,0x0
  802.     jnz    frnewds_2
  803.     mov    [edx],bx         ; save next cluster pos. to prev cl.
  804.     mov    edx,edi            ; next save pos abs mem add
  805.     ret
  806.  
  807. flnsa_1:
  808.     mov    [edi],word 4095        ; mark end of file - last cluster
  809.     cmp    [save_root_flag],1
  810.     jne    flnsa_2
  811.     call   save_flp_root
  812.     cmp    [FDC_Status],0
  813.     jne    fdc_status_error_7
  814. flnsa_2:
  815.     call   save_flp_fat
  816.     cmp    [FDC_Status],0
  817.     jne    fdc_status_error_7
  818. frnoreadds_1:
  819.     pop    edi esi edx ecx ebx eax
  820.     add    esp,32
  821.     mov    eax,0
  822.     mov   [flp_status],0
  823.     ret
  824.  
  825. fdc_status_error_7_1:
  826.     cmp    [FDC_Status],0
  827.     je    fdc_status_error_8    
  828. fdc_status_error_7:
  829.     pop    edi esi edx ecx ebx eax
  830.     add    esp,32
  831.     jmp    fdc_status_error_1
  832.  
  833. save_chs_sector:
  834.     call    calculate_chs
  835.     call    WriteSectWithRetr
  836.     ret
  837.    
  838. calculate_chs:
  839.     mov    bl,[FDD_Track]
  840.     mov    [old_track],bl    
  841.     mov    ebx,18
  842.     xor    edx,edx
  843.     div    ebx
  844.     inc    edx
  845.     mov    [FDD_Sector],dl
  846.     xor    edx,edx
  847.     mov    ebx,2
  848.     div    ebx
  849.     mov    [FDD_Track],al
  850.     mov    [FDD_Head],0
  851.     cmp    edx,0
  852.     je     no_head_2
  853.     inc    [FDD_Head]
  854. no_head_2:
  855.     mov     dl,[old_track]
  856.     cmp     dl,[FDD_Track]
  857.     je      no_seek_track_1
  858.     call    SeekTrack
  859. no_seek_track_1:
  860.     ret
  861.  
  862.    
  863. get_cluster_of_a_path_flp:
  864. ;---------------------------------------------------------
  865. ; input  : EBX = pointer to a path string
  866. ;          (example: the path "/files/data/document" become
  867. ;                             "files......data.......document...0"
  868. ;          '.' = space char
  869. ;          '0' = char(0) (ASCII=0) !!! )
  870. ; output : if (CARRY=1) -> ERROR in the PATH
  871. ;          if (CARRY=0) -> EAX=cluster
  872. ;---------------------------------------------------------
  873.  
  874.     push  edx
  875.     mov   edx,ebx
  876.  
  877. search_end_of_path_flp:
  878.     cmp   [save_flag],0
  879.     jne   search_end_of_path_flp_1
  880.     cmp   byte [edx],0
  881.     je    found_end_of_path_flp
  882.     jmp   search_end_of_path_flp_2
  883. search_end_of_path_flp_1:
  884.     cmp   byte [edx+12],0
  885.     je    found_end_of_path_flp
  886. search_end_of_path_flp_2:
  887.     inc   edx ; '/'
  888.     call  analyze_directory_flp
  889.     jc    directory_not_found_flp
  890.  
  891.     mov   eax,[ebx+20-2]        ; read the HIGH 16bit cluster field
  892.     mov   ax,[ebx+26]           ; read the LOW 16bit cluster field
  893.     and   eax,0xfff           ;[fatMASK]
  894.     add   edx,11                ; 8+3 (name+extension)
  895.     jmp   search_end_of_path_flp
  896.  
  897. found_end_of_path_flp:
  898.     inc   edx
  899.     mov   [pointer_file_name_flp],edx
  900.     pop   edx
  901.     clc                         ; no errors
  902.     ret
  903.  
  904. directory_not_found_flp:
  905.     pop   edx
  906.     stc                         ; errors occour
  907.     ret
  908.    
  909. analyze_directory_flp:
  910. ;--------------------------------
  911. ; input  : EAX = first cluster of the directory
  912. ;          EBX = pointer to filename
  913. ; output : IF CARRY=0 EAX = sector where th file is found
  914. ;                     EBX = pointer in buffer
  915. ;                     [buffer .. buffer+511]
  916. ;                     ECX,EDX,EDI,EDI not changed
  917. ;          IF CARRY=1
  918. ;--------------------------------
  919.    push ebx ;[esp+16]
  920.    push ecx
  921.    push edx
  922.    push esi
  923.    push edi
  924.    
  925.    
  926. adr56_flp:
  927.    mov [clust_tmp_flp],eax
  928.    add    eax,31
  929.    pusha
  930.    call   read_chs_sector
  931.    popa
  932.    cmp    [FDC_Status],0
  933.    jne    not_found_file_analyze_flp
  934.  
  935.    mov ecx,512/32
  936.    mov ebx,0xD000
  937.    
  938. adr1_analyze_flp:
  939.    mov esi,edx   ;[esp+16]
  940.    mov edi,ebx
  941.    cld
  942.    push ecx
  943.    mov ecx,11
  944.    rep cmpsb
  945.    pop ecx
  946.    je found_file_analyze_flp
  947.    
  948.    add ebx,32
  949.    loop adr1_analyze_flp
  950.    
  951.     mov eax,[clust_tmp_flp]
  952.     shl    eax,1            ;find next cluster from FAT
  953.     add    eax,0x282000
  954.     mov    eax,[eax]
  955.     and    eax,4095
  956.     cmp eax,0x0ff8
  957.     jb  adr56_flp
  958. not_found_file_analyze_flp:  
  959.    pop edi
  960.    pop esi
  961.    pop edx
  962.    pop ecx
  963.    add esp,4
  964.    stc        ;file not found
  965.    ret
  966.    
  967. found_file_analyze_flp:
  968.    pop edi
  969.    pop esi
  970.    pop edx
  971.    pop ecx
  972.    add esp,4
  973.    clc        ;file found
  974.    ret
  975.    
  976.    
  977. analyze_directory_to_write_flp:
  978. ;--------------------------------
  979. ; input  : EAX = first cluster of the directory
  980. ; output : IF CARRY=0 EAX = sector where the file is found
  981. ;                     EBX = pointer in buffer
  982. ;                     [buffer .. buffer+511]
  983. ;                     ECX,EDX,EDI,EDI not changed
  984. ;          IF CARRY=1
  985. ;--------------------------------
  986.    
  987.    push ecx
  988.    push edx
  989.    push esi
  990.    
  991. adr561:
  992.    mov [clust_tmp_flp],eax
  993.    add    eax,31
  994.    pusha
  995.    call   read_chs_sector  
  996.    popa
  997.    cmp    [FDC_Status],0
  998.    jne    error_found_file_analyze1
  999.  
  1000.    mov ecx,512/32
  1001.    mov ebx,0xD000
  1002.    
  1003. adr1_analyze1:
  1004.    cmp byte [ebx],0x00
  1005.    je  found_file_analyze1
  1006.    cmp byte [ebx],0xe5
  1007.    je  found_file_analyze1
  1008.    
  1009. avanti:
  1010.    add ebx,32
  1011.    loop adr1_analyze1
  1012.    
  1013.    mov eax,[clust_tmp_flp]
  1014.    shl    eax,1            ;find next cluster from FAT
  1015.    add    eax,0x282000
  1016.    mov    eax,[eax]
  1017.    and    eax,4095
  1018.    cmp eax,0x0ff8
  1019.    jb  adr561
  1020.    
  1021.    call get_free_FAT               ;this block of code add a new cluster
  1022.                                    ;for the directory because the directory
  1023.                                    ;is full
  1024.  
  1025.    mov [edi],word 0x0fff
  1026.    
  1027.    mov eax,[clust_tmp_flp]
  1028.    shl    eax,1            ;find next cluster from FAT
  1029.    add    eax,0x282000
  1030.    sub    edi,0x282000
  1031.    mov    [eax],di
  1032.  
  1033.    pusha
  1034.    mov ecx,512/4
  1035.    xor eax,eax
  1036.    mov edi,0xD000
  1037.    cld
  1038.    rep stosd
  1039.    popa
  1040.  
  1041.    mov    eax,edi
  1042.    add    eax,31
  1043.    pusha
  1044.    call   save_chs_sector  
  1045.    popa
  1046.    cmp    [FDC_Status],0
  1047.    jne    error_found_file_analyze1
  1048.    mov    ebx,0xD000
  1049.  
  1050. found_file_analyze1:
  1051.    
  1052.    pop esi
  1053.    pop edx
  1054.    pop ecx
  1055.    clc        ;file found
  1056.    ret
  1057.  
  1058. error_found_file_analyze1:
  1059.    pop esi
  1060.    pop edx
  1061.    pop ecx
  1062.    stc
  1063.    ret  
  1064.    
  1065. get_free_FAT_flp:
  1066. ;------------------------------------------
  1067. ; input  :  EAX = # cluster for start the searching
  1068. ; output :  EAX = # first cluster found free
  1069. ;-------------------------------------------
  1070.    push ebx
  1071.  
  1072.     mov    ebx,1
  1073. check_new_flp:
  1074.     add    ebx,1
  1075.     mov    edi,ebx            ; find free cluster in FAT
  1076.     shl    edi,1
  1077.     add    edi,0x282000
  1078.     mov    eax,[edi]
  1079.     and    eax,4095
  1080.     cmp    eax,0x0
  1081.     jnz    check_new_flp
  1082.  
  1083.    pop ebx
  1084.    ret
  1085.  
  1086. ; \begin{diamond}
  1087. fd_find_lfn:
  1088. ; in: esi->name
  1089. ; out: CF=1 - file not found
  1090. ;      else CF=0 and edi->direntry
  1091.         pusha
  1092.         sub     esp, 262*2      ; reserve place for LFN
  1093.         mov     ebp, esp
  1094.         push    0               ; for fat_get_name: read ASCII name
  1095.         call    read_flp_fat
  1096.         cmp     [FDC_Status], 0
  1097.         jnz     .error
  1098.         mov     eax, 19
  1099.         mov     dh, 14
  1100. .main_loop:
  1101. .20_1:
  1102.         pusha
  1103.         call    read_chs_sector
  1104.         popa
  1105.         cmp     [FDC_Status], 0
  1106.         jnz     .error
  1107.         mov     edi, 0xD000
  1108.         inc     [FDD_Sector]
  1109.         push    eax
  1110. .21_1:
  1111.         call    fat_get_name
  1112.         jc      @f
  1113.         call    fat_compare_name
  1114.         jz      .found
  1115. @@:
  1116.         add     edi, 0x20
  1117.         cmp     edi, 0xD200
  1118.         jb      .21_1
  1119.         pop     eax
  1120.         inc     eax
  1121.         dec     dh
  1122.         js      @f
  1123.         jnz     .20_1
  1124. .error:
  1125.         add     esp, 262*2+4
  1126.         popa
  1127.         stc
  1128.         ret
  1129. @@:
  1130. ; read next sector from FAT
  1131.         mov     eax, [(eax-31-1)*2+0x282000]
  1132.         and     eax, 0xFFF
  1133.         cmp     eax, 0xFF8
  1134.         jae     .error
  1135.         add     eax, 31
  1136.         jmp     .main_loop
  1137. .found:
  1138.         pop     eax
  1139. ; if LFN entry, advance to corresponding short entry
  1140.         cmp     byte [edi+11], 0xF
  1141.         jnz     .entryfound
  1142.         add     edi, 0x20
  1143.         cmp     edi, 0xD200
  1144.         jb      .entryfound
  1145.         dec     dh
  1146.         jz      .error
  1147.         inc     eax
  1148.         call    read_chs_sector
  1149.         cmp     [FDC_Status], 0
  1150.         jnz     .error
  1151.         mov     edi, 0xD000
  1152. .entryfound:
  1153.         cmp     byte [esi], 0
  1154.         jz      .done
  1155.         test    byte [edi+11], 10h      ; is a directory?
  1156.         jz      .error
  1157.         movzx   eax, word [edi+26]
  1158.         add     eax, 31
  1159.         mov     dh, 0
  1160.         jmp     .main_loop
  1161. .done:
  1162.         add     esp, 262*2+4+4
  1163.         push    edi
  1164.         popad
  1165.         ret
  1166.  
  1167. ;----------------------------------------------------------------
  1168. ;
  1169. ;  fs_FloppyRead - LFN variant for reading floppy
  1170. ;
  1171. ;  esi  points to filename
  1172. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  1173. ;       may be ebx=0 - start from first byte
  1174. ;  ecx  number of bytes to read, 0+
  1175. ;  edx  mem location to return data
  1176. ;
  1177. ;  ret ebx = bytes read or 0xffffffff file not found
  1178. ;      eax = 0 ok read or other = errormsg
  1179. ;
  1180. ;--------------------------------------------------------------
  1181. fs_FloppyRead:
  1182.         call    read_flp_fat
  1183.         cmp     byte [esi], 0
  1184.         jnz     @f
  1185.         or      ebx, -1
  1186.         mov     eax, 10         ; access denied
  1187.         ret
  1188. @@:
  1189.         push    edi
  1190.         call    fd_find_lfn
  1191.         jnc     .found
  1192.         pop     edi
  1193.         or      ebx, -1
  1194.         mov     eax, 5          ; file not found
  1195.         ret
  1196. .found:
  1197.         test    ebx, ebx
  1198.         jz      .l1
  1199.         cmp     dword [ebx+4], 0
  1200.         jz      @f
  1201.         xor     ebx, ebx
  1202. .reteof:
  1203.         mov     eax, 6          ; EOF
  1204.         pop     edi
  1205.         ret
  1206. @@:
  1207.         mov     ebx, [ebx]
  1208. .l1:
  1209.         push    ecx edx
  1210.         push    0
  1211.         mov     eax, [edi+28]
  1212.         sub     eax, ebx
  1213.         jb      .eof
  1214.         cmp     eax, ecx
  1215.         jae     @f
  1216.         mov     ecx, eax
  1217.         mov     byte [esp], 6           ; EOF
  1218. @@:
  1219.         movzx   edi, word [edi+26]
  1220. .new:
  1221.         jecxz   .done
  1222.         test    edi, edi
  1223.         jz      .eof
  1224.         cmp     edi, 0xFF8
  1225.         jae     .eof
  1226.         lea     eax, [edi+31]
  1227.         pusha
  1228.         call    read_chs_sector
  1229.         popa
  1230.         cmp     [FDC_Status], 0
  1231.         jnz     .err
  1232.         sub     ebx, 512
  1233.         jae     .skip
  1234.         lea     eax, [0xD000+ebx+512]
  1235.         neg     ebx
  1236.         push    ecx
  1237.         cmp     ecx, ebx
  1238.         jbe     @f
  1239.         mov     ecx, ebx
  1240. @@:
  1241.         mov     ebx, edx
  1242.         call    memmove
  1243.         add     edx, ecx
  1244.         sub     [esp], ecx
  1245.         pop     ecx
  1246.         xor     ebx, ebx
  1247. .skip:
  1248.         movzx   edi, word [edi*2+0x282000]
  1249.         jmp     .new
  1250. .done:
  1251.         mov     ebx, edx
  1252.         pop     eax edx ecx edi
  1253.         sub     ebx, edx
  1254.         ret
  1255. .eof:
  1256.         mov     ebx, edx
  1257.         pop     eax edx ecx
  1258.         jmp     .reteof
  1259. .err:
  1260.         mov     ebx, edx
  1261.         pop     eax edx ecx edi
  1262.         sub     ebx, edx
  1263.         mov     al, 5  ; may be other error code?
  1264.         ret
  1265.  
  1266. ;----------------------------------------------------------------
  1267. ;
  1268. ;  fs_FloppyReadFolder - LFN variant for reading floppy folders
  1269. ;
  1270. ;  esi  points to filename
  1271. ;  ebx  pointer to 32-bit number = first wanted block, 0+
  1272. ;  ecx  number of blocks to read, 0+
  1273. ;  edx  mem location to return data
  1274. ;
  1275. ;  ret ebx = blocks read or 0xffffffff folder not found
  1276. ;      eax = 0 ok read or other = errormsg
  1277. ;
  1278. ;--------------------------------------------------------------
  1279. fs_FloppyReadFolder:
  1280.         call    read_flp_fat
  1281.         mov     ebx, [ebx]
  1282.         push    edi
  1283.         cmp     byte [esi], 0
  1284.         jz      .root
  1285.         call    fd_find_lfn
  1286.         jnc     .found
  1287.         pop     edi
  1288.         or      ebx, -1
  1289.         mov     eax, ERROR_FILE_NOT_FOUND
  1290.         ret
  1291. .found:
  1292.         test    byte [edi+11], 0x10     ; do not allow read files
  1293.         jnz     .found_dir
  1294.         pop     edi
  1295.         or      ebx, -1
  1296.         mov     eax, ERROR_ACCESS_DENIED
  1297.         ret
  1298. .found_dir:
  1299.         movzx   eax, word [edi+26]
  1300.         add     eax, 31
  1301.         push    0
  1302.         jmp     .doit
  1303. .root:
  1304.         mov     eax, 19
  1305.         push    14
  1306. .doit:
  1307.         push    ecx ebp
  1308.         sub     esp, 262*2      ; reserve space for LFN
  1309.         mov     ebp, esp
  1310.         push    1               ; for fat_get_name: read UNICODE names
  1311. ; init header
  1312.         push    eax ecx
  1313.         mov     edi, edx
  1314.         mov     ecx, 32/4
  1315.         xor     eax, eax
  1316.         rep     stosd
  1317.         pop     ecx eax
  1318.         mov     byte [edx], 1   ; version
  1319.         mov     esi, edi        ; esi points to BDFE
  1320. .main_loop:
  1321.         pusha
  1322.         call    read_chs_sector
  1323.         popa
  1324.         cmp     [FDC_Status], 0
  1325.         jnz     .error
  1326.         mov     edi, 0xD000
  1327.         push    eax
  1328. .l1:
  1329.         call    fat_get_name
  1330.         jc      .l2
  1331.         cmp     byte [edi+11], 0xF
  1332.         jnz     .do_bdfe
  1333.         add     edi, 0x20
  1334.         cmp     edi, 0xD200
  1335.         jb      .do_bdfe
  1336.         pop     eax
  1337.         inc     eax
  1338.         dec     byte [esp+262*2+12]
  1339.         jz      .done
  1340.         jns     @f
  1341. ; read next sector from FAT
  1342.         mov     eax, [(eax-31-1)*2+0x282000]
  1343.         and     eax, 0xFFF
  1344.         cmp     eax, 0xFF8
  1345.         jae     .done
  1346.         add     eax, 31
  1347.         mov     byte [esp+262*2+12], 0
  1348. @@:
  1349.         pusha
  1350.         call    read_chs_sector
  1351.         popa
  1352.         cmp     [FDC_Status], 0
  1353.         jnz     .error
  1354.         mov     edi, 0xD000
  1355.         push    eax
  1356. .do_bdfe:
  1357.         inc     dword [edx+8]   ; new file found
  1358.         dec     ebx
  1359.         jns     .l2
  1360.         dec     ecx
  1361.         js      .l2
  1362.         inc     dword [edx+4]   ; new file block copied
  1363.         call    fat_entry_to_bdfe
  1364. .l2:
  1365.         add     edi, 0x20
  1366.         cmp     edi, 0xD200
  1367.         jb      .l1
  1368.         pop     eax
  1369.         inc     eax
  1370.         dec     byte [esp+262*2+12]
  1371.         jz      .done
  1372.         jns     @f
  1373. ; read next sector from FAT
  1374.         mov     eax, [(eax-31-1)*2+0x282000]
  1375.         and     eax, 0xFFF
  1376.         cmp     eax, 0xFF8
  1377.         jae     .done
  1378.         add     eax, 31
  1379.         mov     byte [esp+262*2+12], 0
  1380. @@:
  1381.         jmp     .main_loop
  1382. .error:
  1383.         add     esp, 262*2+4
  1384.         pop     ebp ecx edi edi
  1385.         or      ebx, -1
  1386.         mov     eax, ERROR_FILE_NOT_FOUND
  1387.         ret
  1388. .done:
  1389.         add     esp, 262*2+4
  1390.         pop     ebp
  1391.         mov     ebx, [edx+4]
  1392.         xor     eax, eax
  1393.         dec     ecx
  1394.         js      @f
  1395.         mov     al, ERROR_END_OF_FILE
  1396. @@:
  1397.         pop     ecx edi edi
  1398.         ret
  1399.  
  1400. ; \end{diamond}