Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 465 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                                      ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;                                                              ;;
  8. ;; System service for filesystem call                                   ;;
  9. ;; (C) 2004 Ville Turjanmaa, License: GPL                               ;;
  10. ;; 29.04.2006 Elimination of hangup after the                           ;;
  11. ;;            expiration hd_wait_timeout (for LBA) -  Mario79           ;;
  12. ;; 15.01.2005 get file size/attr/date,                          ;;
  13. ;;            file_append (only for hd) - ATV                   ;;
  14. ;; 23.11.2004 test if hd/partition is set - ATV                         ;;
  15. ;; 18.11.2004 get_disk_info and more error codes - ATV                  ;;
  16. ;; 08.11.2004 expand_pathz and rename (only for hd) - ATV               ;;
  17. ;; 20.10.2004 Makedir/Removedir (only for hd) - ATV                     ;;
  18. ;;                                                                      ;;
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20.  
  21. iglobal
  22. dir0:        db  'HARDDISK   '
  23.              db  'RAMDISK    '
  24.              db  'FLOPPYDISK '
  25.              db  0
  26.  
  27. dir1:        db  'FIRST      '
  28.              db  'SECOND     '
  29.              db  'THIRD      '
  30.              db  'FOURTH     '
  31.              db  0
  32.  
  33. not_select_IDE db 0
  34.  
  35. hd_address_table:  dd  0x1f0,0x00,0x1f0,0x10
  36.                    dd  0x170,0x00,0x170,0x10
  37. endg
  38.  
  39. file_system:
  40.  
  41. ; IN:
  42. ;
  43. ; eax = 0  ; read file          /RamDisk/First  6
  44. ; eax = 1  ; write file         /RamDisk/First 33   /HardDisk/First 56
  45. ; eax = 8  ; lba read
  46. ; eax = 15 ; get_disk_info
  47. ;
  48. ; OUT:
  49. ;
  50. ; eax = 0  : read ok
  51. ; eax = 1  : no hd base and/or partition defined
  52. ; eax = 2  : function is unsupported for this FS
  53. ; eax = 3  : unknown FS
  54. ; eax = 4  : partition not defined at hd
  55. ; eax = 5  : file not found
  56. ; eax = 6  : end of file
  57. ; eax = 7  : memory pointer not in application area
  58. ; eax = 8  : disk full
  59. ; eax = 9  : fat table corrupted
  60. ; eax = 10 : access denied
  61. ; eax = 11 : disk error
  62. ;
  63. ; ebx = size
  64.  
  65. ; \begin{diamond}[18.03.2006]
  66. ; for subfunction 16 (start application) error codes must be negative
  67. ;    because positive values are valid PIDs
  68. ; so possible return values are:
  69. ; eax > 0 : process created, eax=PID
  70.  
  71. ; -0x10 <= eax < 0 : -eax is filesystem error code:
  72. ; eax = -1  = 0xFFFFFFFF : no hd base and/or partition defined
  73. ; eax = -3  = 0xFFFFFFFD : unknown FS
  74. ; eax = -5  = 0xFFFFFFFB : file not found
  75. ; eax = -6  = 0xFFFFFFFA : unexpected end of file (probably not executable file)
  76. ; eax = -9  = 0xFFFFFFF7 : fat table corrupted
  77. ; eax = -10 = 0xFFFFFFF6 : access denied
  78.  
  79. ; -0x20 <= eax < -0x10: eax is process creation error code:
  80. ; eax = -0x20 = 0xFFFFFFE0 : too many processes
  81. ; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
  82. ; eax = -0x1E = 0xFFFFFFE2 : no memory
  83.  
  84. ; ebx is not changed
  85.  
  86. ; \end{diamond}[18.03.2006]
  87.  
  88.     ; Extract parameters
  89.  ;   add    eax, std_application_base_address    ; abs start of info block
  90.  
  91.     cmp   dword [eax+0],15      ; GET_DISK_INFO
  92.     je    fs_info
  93.  
  94.     cmp   dword [CURRENT_TASK],1      ; no memory checks for kernel requests
  95.     jz    no_checks_for_kernel
  96.     mov   edx,eax
  97.     cmp   dword [eax+0],1
  98.     jnz   .usual_check
  99.     mov   ebx,[eax+12]
  100.  ;   add   ebx,std_application_base_address
  101.     mov   ecx,[eax+8]
  102.     call  check_region
  103.     test  eax,eax
  104.     jnz   area_in_app_mem
  105.  
  106. .error_output:
  107.     mov   esi,buffer_failed
  108.     call  sys_msg_board_str
  109. ;    mov   eax,7
  110.     mov   dword [esp+36],7
  111.     ret
  112. iglobal
  113.   buffer_failed db 'K : Buffer check failed',13,10,0
  114. endg
  115. .usual_check:
  116.     cmp   dword [eax+0],0
  117.     mov   ecx,512
  118.     jnz   .small_size
  119.     mov   ecx,[eax+8]
  120.     shl   ecx,9
  121. .small_size:
  122.     mov   ebx,[eax+12]
  123.  ;   add   ebx,std_application_base_address
  124.     call  check_region
  125.     test  eax,eax
  126.     jz    .error_output
  127.   area_in_app_mem:
  128.     mov   eax,edx
  129.   no_checks_for_kernel:
  130.  
  131.   fs_read:
  132.  
  133.     mov   ebx,[eax+20]          ; program wants root directory ?
  134.     test  bl,bl
  135.     je    fs_getroot
  136.     test  bh,bh
  137.     jne   fs_noroot
  138.   fs_getroot:
  139. ; \begin{diamond}[18.03.2006]
  140. ; root - only read is allowed
  141. ; other operations return "access denied", eax=10
  142. ; (execute operation returns eax=-10)
  143.     cmp    dword [eax], 0
  144.     jz    .read_root
  145.     mov    dword [esp+36], 10
  146.     ret
  147. .read_root:
  148. ; \end{diamond}[18.03.2006]
  149.     mov   esi,dir0
  150.     mov   edi,[eax+12]
  151.  ;   add   edi,std_application_base_address
  152.     mov   ecx,11
  153.     push  ecx
  154. ;    cld    ; already is
  155.     rep   movsb
  156.     mov   al,0x10
  157.     stosb
  158.     add   edi,32-11-1
  159.     pop   ecx
  160.     rep   movsb
  161.     stosb
  162.     and   dword [esp+36],0      ; ok read
  163.     mov   dword [esp+24],32*2   ; size of root
  164.     ret
  165.  
  166.   fs_info:                      ;start of code - Mihasik
  167.     push  eax
  168.     cmp   [eax+21],byte 'h'
  169.     je    fs_info_h
  170.     cmp   [eax+21],byte 'H'
  171.     je    fs_info_h
  172.     cmp   [eax+21],byte 'r'
  173.     je    fs_info_r
  174.     cmp   [eax+21],byte 'R'
  175.     je    fs_info_r
  176.     mov   eax,3                 ;if unknown disk
  177.     xor   ebx,ebx
  178.     xor   ecx,ecx
  179.     xor   edx,edx
  180.     jmp   fs_info1
  181.   fs_info_r:
  182.     call  ramdisk_free_space    ;if ramdisk
  183.     mov   ecx,edi               ;free space in ecx
  184.     shr   ecx,9                 ;free clusters
  185.     mov   ebx,2847              ;total clusters
  186.     mov   edx,512               ;cluster size
  187.     xor   eax,eax               ;always 0
  188.     jmp   fs_info1
  189.   fs_info_h:                    ;if harddisk
  190.     call  get_hd_info
  191.   fs_info1:
  192.     pop   edi
  193.     mov   [esp+36],eax
  194.     mov   [esp+24],ebx           ; total clusters on disk
  195.     mov   [esp+32],ecx           ; free clusters on disk
  196.     mov   [edi],edx              ; cluster size in bytes
  197.     ret                          ;end of code - Mihasik
  198.  
  199.   fs_noroot:
  200.  
  201.     push  dword [eax+0]         ; read/write/delete/.../makedir/rename/lba/run
  202.     push  dword [eax+4]         ; 512 block number to read
  203.     push  dword [eax+8]         ; bytes to write/append or 512 blocks to read
  204.     mov   ebx,[eax+12]
  205.  ;   add   ebx,std_application_base_address
  206.     push  ebx                   ; abs start of return/save area
  207.  
  208.     lea   esi,[eax+20]          ; abs start of dir + filename
  209.     mov   edi,[eax+16]
  210.  ;   add   edi,std_application_base_address    ; abs start of work area
  211.  
  212.     call  expand_pathz
  213.  
  214.     push  edi                   ; dir start
  215.     push  ebx                   ; name of file start
  216.  
  217.     mov   eax,[edi+1]
  218.     cmp   eax,'RD  '
  219.     je    fs_yesramdisk
  220.     cmp   eax,'RAMD'
  221.     jne   fs_noramdisk
  222.  
  223.   fs_yesramdisk:
  224.  
  225.     cmp   byte [edi+1+11],0
  226.     je    fs_give_dir1
  227.  
  228.     mov   eax,[edi+1+12]
  229.     cmp   eax,'1   '
  230.     je    fs_yesramdisk_first
  231.     cmp   eax,'FIRS'
  232.     jne   fs_noramdisk
  233.  
  234.   fs_yesramdisk_first:
  235.  
  236.     cmp   dword [esp+20],8      ; LBA read ramdisk
  237.     jne   fs_no_LBA_read_ramdisk
  238.  
  239.     mov   eax,[esp+16]          ; LBA block to read
  240.     mov   ecx,[esp+8]           ; abs pointer to return area
  241.  
  242.     call  LBA_read_ramdisk
  243.     jmp   file_system_return
  244.  
  245.  
  246.   fs_no_LBA_read_ramdisk:
  247.  
  248.     cmp   dword [esp+20],0      ; READ
  249.     jne   fs_noramdisk_read
  250.  
  251.     mov   eax,[esp+4]           ; fname
  252.     add   eax,2*12+1
  253.     mov   ebx,[esp+16]          ; block start
  254.     inc   ebx
  255.     mov   ecx,[esp+12]          ; block count
  256.     mov   edx,[esp+8]           ; return
  257.     mov   esi,[esp+0]
  258.     sub   esi,eax
  259.     add   esi,12+1              ; file name length
  260.     call  fileread
  261.  
  262.     jmp   file_system_return
  263.  
  264.  
  265.   fs_noramdisk_read:
  266.  
  267.     cmp   dword [esp+20],1      ; WRITE
  268.     jne   fs_noramdisk_write
  269.  
  270.     mov   eax,[esp+4]           ; fname
  271.     add   eax,2*12+1
  272.     mov   ebx,[esp+8]           ; buffer
  273.     mov   ecx,[esp+12]          ; count to write
  274.     mov   edx,0                 ; create new
  275.     call  filesave
  276.  
  277.     ; eax=0 ok - eax=1 not enough free space
  278.  
  279.     jmp   file_system_return
  280.  
  281.   fs_noramdisk_write:
  282.   fs_noramdisk:
  283.  
  284.   ;********************************************************************
  285.     mov   eax,[edi+1]
  286.     cmp   eax,'FD  '
  287.     je    fs_yesflpdisk
  288.     cmp   eax,'FLOP'
  289.     jne   fs_noflpdisk
  290.  
  291.   fs_yesflpdisk:
  292.     call   reserve_flp
  293.  
  294.     cmp   byte [edi+1+11],0
  295.     je    fs_give_dir1
  296.  
  297.     mov   eax,[edi+1+12]
  298.     cmp   eax,'1   '
  299.     je    fs_yesflpdisk_first
  300.     cmp   eax,'FIRS'
  301.     je    fs_yesflpdisk_first
  302.     cmp   eax,'2   '
  303.     je    fs_yesflpdisk_second
  304.     cmp   eax,'SECO'
  305.     jne   fs_noflpdisk
  306.     jmp   fs_yesflpdisk_second
  307.  
  308.   fs_yesflpdisk_first:
  309.     mov   [flp_number],1
  310.     jmp   fs_yesflpdisk_start
  311.   fs_yesflpdisk_second:
  312.     mov   [flp_number],2
  313.   fs_yesflpdisk_start:
  314.     cmp   dword [esp+20],0      ; READ
  315.     jne   fs_noflpdisk_read
  316.  
  317.     mov   eax,[esp+4]           ; fname
  318.     add   eax,2*12+1
  319.     mov   ebx,[esp+16]          ; block start
  320.     inc   ebx
  321.     mov   ecx,[esp+12]          ; block count
  322.     mov   edx,[esp+8]           ; return
  323.     mov   esi,[esp+0]
  324.     sub   esi,eax
  325.     add   esi,12+1              ; file name length
  326.     call  floppy_fileread
  327.  
  328.     jmp   file_system_return
  329.  
  330.  
  331.   fs_noflpdisk_read:
  332.  
  333.     cmp   dword [esp+20],1      ; WRITE
  334.     jne   fs_noflpdisk_write
  335.  
  336.     mov   eax,[esp+4]           ; fname
  337.     add   eax,2*12+1
  338.     mov   ebx,[esp+8]           ; buffer
  339.     mov   ecx,[esp+12]          ; count to write
  340.     mov   edx,0                 ; create new
  341.     call  floppy_filesave
  342.  
  343.     ; eax=0 ok - eax=1 not enough free space
  344.  
  345.     jmp   file_system_return
  346.  
  347.   fs_noflpdisk_write:
  348.  
  349.   fs_noflpdisk:
  350.   ;*****************************************************************
  351.  
  352.     mov   eax,[edi+1]
  353.     cmp   eax,'HD0 '
  354.     je    fs_yesharddisk_IDE0
  355.     cmp   eax,'HD1 '
  356.     je    fs_yesharddisk_IDE1
  357.     cmp   eax,'HD2 '
  358.     je    fs_yesharddisk_IDE2
  359.     cmp   eax,'HD3 '
  360.     je    fs_yesharddisk_IDE3
  361.     jmp   old_path_harddisk
  362. fs_yesharddisk_IDE0:
  363.      call  reserve_hd1
  364.      mov  [hdbase],0x1f0
  365.      mov  [hdid],0x0
  366.      mov  [hdpos],1
  367.      jmp  fs_yesharddisk_partition
  368. fs_yesharddisk_IDE1:
  369.      call  reserve_hd1
  370.      mov  [hdbase],0x1f0
  371.      mov  [hdid],0x10
  372.      mov  [hdpos],2
  373.      jmp  fs_yesharddisk_partition
  374. fs_yesharddisk_IDE2:
  375.      call  reserve_hd1
  376.      mov  [hdbase],0x170
  377.      mov  [hdid],0x0
  378.      mov  [hdpos],3
  379.      jmp  fs_yesharddisk_partition
  380. fs_yesharddisk_IDE3:
  381.      call  reserve_hd1
  382.      mov  [hdbase],0x170
  383.      mov  [hdid],0x10
  384.      mov  [hdpos],4
  385. fs_yesharddisk_partition:
  386.         call    reserve_hd_channel
  387. ;    call  choice_necessity_partition
  388. ;    jmp   fs_yesharddisk_all
  389.     jmp   fs_for_new_semantic
  390.  
  391. choice_necessity_partition:
  392.     mov   eax,[edi+1+12]
  393.     call  StringToNumber
  394.         mov   [fat32part],eax
  395. choice_necessity_partition_1:
  396.     mov   ecx,[hdpos]
  397.     xor   eax,eax
  398.     mov   [hd_entries], eax    ; entries in hd cache
  399.     mov   edx,DRIVE_DATA+2
  400.  search_partition_array:
  401.     mov   bl,[edx]
  402.     movzx ebx,bl
  403.     add   eax,ebx
  404.     inc   edx
  405.     loop  search_partition_array
  406.     sub   eax,ebx
  407.     add   eax,[fat32part]
  408.     dec   eax
  409.     xor   edx,edx
  410.     imul  eax,100
  411.     add   eax,DRIVE_DATA+0xa
  412.     mov   [transfer_adress],eax
  413.     call  partition_data_transfer_1
  414.     ret
  415.  
  416.  old_path_harddisk:
  417.     mov   eax,[edi+1]
  418.     cmp   eax,'HD  '
  419.     je    fs_yesharddisk
  420.     cmp   eax,'HARD'
  421.     jne   fs_noharddisk
  422.  
  423.   fs_yesharddisk:
  424.     cmp   dword [esp+20],8      ; LBA read
  425.     jne   fs_no_LBA_read
  426.     mov   eax,[esp+16]          ; LBA block to read
  427.     lea   ebx,[edi+1+12]        ; pointer to FIRST/SECOND/THIRD/FOURTH
  428.     mov   ecx,[esp+8]           ; abs pointer to return area
  429.     call  LBA_read
  430.     jmp   file_system_return
  431.  
  432.   fs_no_LBA_read:
  433.  
  434.     cmp   byte [edi+1+11],0     ; directory read
  435.     je    fs_give_dir1
  436.     call  reserve_hd1
  437.  fs_for_new_semantic:
  438.     call  choice_necessity_partition
  439.  
  440.   fs_yesharddisk_all:
  441.     mov   eax,1
  442.     mov    ebx, [esp+24+24]
  443.     cmp   [hdpos],0             ; is hd base set?
  444.     jz    hd_err_return
  445.     cmp   [fat32part],0         ; is partition set?
  446.     jnz   @f
  447. hd_err_return:
  448.     call  free_hd_channel
  449.     and   [hd1_status], 0
  450.     jmp   file_system_return
  451. @@:
  452.  
  453.     cmp   dword [esp+20],0      ; READ
  454.     jne   fs_noharddisk_read
  455.  
  456.     mov   eax,[esp+0]           ; /fname
  457.     lea   edi,[eax+12]
  458.     mov   byte [eax],0          ; path to asciiz
  459.     inc   eax                   ; filename start
  460.  
  461.     mov   ebx,[esp+12]          ; count to read
  462.     mov   ecx,[esp+8]           ; buffer
  463.     mov   edx,[esp+4]
  464.     add   edx,12*2              ; dir start
  465.     sub   edi,edx               ; path length
  466.     mov   esi,[esp+16]          ; blocks to read
  467.  
  468.     call  file_read
  469.  
  470.     mov   edi,[esp+0]
  471.     mov   byte [edi],'/'
  472.  
  473.     call  free_hd_channel
  474.     and   [hd1_status], 0
  475.     jmp   file_system_return
  476.  
  477.   fs_noharddisk_read:
  478.  
  479.  
  480.     cmp   dword [esp+20],1      ; WRITE
  481.     jne   fs_noharddisk_write
  482.  
  483.     mov   eax,[esp+0]           ; /fname
  484.     mov   byte [eax],0          ; path to asciiz
  485.     inc   eax                   ; filename start
  486.  
  487.     mov   ebx,[esp+12]          ; count to write
  488.     mov   ecx,[esp+8]           ; buffer
  489.     mov   edx,[esp+4]
  490.     add   edx,12*2              ; path start
  491.  
  492.     call  file_write
  493.  
  494.     mov   edi,[esp+0]
  495.     mov   byte [edi],'/'
  496.  
  497.     ; eax=0 ok - eax=1 not enough free space
  498.  
  499.     call  free_hd_channel
  500.     and   [hd1_status], 0
  501.     jmp   file_system_return
  502.  
  503.  
  504.   fs_noharddisk_write:
  505.  
  506.  
  507.     call  free_hd_channel
  508.     and   [hd1_status], 0
  509.  
  510.   fs_noharddisk:
  511. ; \begin{diamond}[18.03.2006]
  512.     mov    eax, 5        ; file not found
  513. ; р ьюцхЄ с√Є№, тючтЁр∙рЄ№ фЁєующ ъюф ю°шсъш?
  514.     mov    ebx, [esp+24+24]    ; do not change ebx in application
  515. ; \end{diamond}[18.03.2006]
  516.  
  517.   file_system_return:
  518.  
  519.     add   esp,24
  520.  
  521.     mov   [esp+36],eax
  522.     mov   [esp+24],ebx
  523.     ret
  524.  
  525.  
  526.   fs_give_dir1:
  527.  
  528. ; \begin{diamond}[18.03.2006]
  529. ; /RD,/FD,/HD - only read is allowed
  530. ; other operations return "access denied", eax=10
  531. ; (execute operation returns eax=-10)
  532.     cmp    dword [esp+20], 0
  533.     jz    .read
  534.     add    esp, 20
  535.     pop    ecx
  536.     mov    dword [esp+36], 10
  537.     ret
  538. .read:
  539. ; \end{diamond}[18.03.2006]
  540.     mov   al,0x10
  541.     mov   ebx,1
  542.     mov   edi,[esp+8]
  543.     mov   esi,dir1
  544.   fs_d1_new:
  545.     mov   ecx,11
  546. ;    cld
  547.     rep   movsb
  548.     stosb
  549.     add   edi,32-11-1
  550.     dec   ebx
  551.     jne   fs_d1_new
  552.  
  553.     add   esp,24
  554.  
  555.     and   dword [esp+36],0      ; ok read
  556.     mov   dword [esp+24],32*1   ; dir/data size
  557.     ret
  558.  
  559.  
  560.  
  561. LBA_read_ramdisk:
  562.  
  563.     cmp   [lba_read_enabled],1
  564.     je    lbarrl1
  565.  
  566.     xor   ebx,ebx
  567.     mov   eax,2
  568.     ret
  569.  
  570.   lbarrl1:
  571.  
  572.     cmp   eax,18*2*80
  573.     jb    lbarrl2
  574.     xor   ebx,ebx
  575.     mov   eax,3
  576.     ret
  577.  
  578.   lbarrl2:
  579.  
  580.     pushad
  581.  
  582.     call  restorefatchain
  583.  
  584.     mov   edi,ecx
  585.     mov   esi,eax
  586.  
  587.     shl   esi,9
  588.     add   esi,RAMDISK
  589.     mov   ecx,512/4
  590. ;    cld
  591.     rep   movsd
  592.  
  593.     popad
  594.  
  595.     xor   ebx,ebx
  596.     xor   eax,eax
  597.     ret
  598.  
  599. LBA_read:
  600.  
  601. ; IN:
  602. ;
  603. ; eax = LBA block to read
  604. ; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
  605. ; ecx = abs pointer to return area
  606.  
  607.     cmp   [lba_read_enabled],1
  608.     je    lbarl1
  609.     mov   eax,2
  610.     ret
  611.  
  612.   lbarl1:
  613.  
  614.     call  reserve_hd1
  615.  
  616.     push  eax
  617.     push  ecx
  618.  
  619.     mov   edi,hd_address_table
  620.     mov   esi,dir1
  621.     mov   eax,[ebx]
  622.     mov   edx,'1   '
  623.     mov   ecx,4
  624.   blar0:
  625.     cmp   eax,[esi]
  626.     je    blar2
  627.     cmp   eax,edx
  628.     je    blar2
  629.     inc   edx
  630.     add   edi,8
  631.     add   esi,11
  632.     dec   ecx
  633.     jnz   blar0
  634.  
  635.     mov   eax,1
  636.     mov   ebx,1
  637.     jmp   LBA_read_ret
  638.  
  639.   blar2:
  640.     mov   eax,[edi+0]
  641.     mov   ebx,[edi+4]
  642.  
  643.     mov  [hdbase],eax
  644.     mov  [hdid],ebx
  645.  
  646.     call  wait_for_hd_idle
  647.     cmp   [hd_error],0
  648.     jne   hd_lba_error
  649.  
  650.     ; eax = hd port
  651.     ; ebx = set for primary (0x00) or slave (0x10)
  652.  
  653.     cli
  654.  
  655.     mov   edx,eax
  656.     inc   edx
  657.     xor   eax,eax
  658.     out   dx,al
  659.     inc   edx
  660.     inc   eax
  661.     out   dx,al
  662.     inc   edx
  663.     mov   eax,[esp+4]
  664.     out   dx,al
  665.     shr   eax,8
  666.     inc   edx
  667.     out   dx,al
  668.     shr   eax,8
  669.     inc   edx
  670.     out   dx,al
  671.     shr   eax,8
  672.     inc   edx
  673.     and   al,1+2+4+8
  674.     add   al,bl
  675.     add   al,128+64+32
  676.     out   dx,al
  677.  
  678.     inc   edx
  679.     mov   al,20h
  680.     out   dx,al
  681.  
  682.     sti
  683.  
  684.     call  wait_for_sector_buffer
  685.     cmp   [hd_error],0
  686.     jne   hd_lba_error
  687.  
  688.     cli
  689.  
  690.     mov   edi,[esp+0]
  691.     mov   ecx,256
  692.     sub   edx,7
  693.     cld
  694.     rep   insw
  695.  
  696.     sti
  697.  
  698.     xor   eax,eax
  699.     xor   ebx,ebx
  700.  
  701.   LBA_read_ret:
  702.     mov [hd_error],0
  703.     mov   [hd1_status],0
  704.     add   esp,2*4
  705.  
  706.     ret
  707.  
  708.  
  709. expand_pathz:
  710. ; IN:
  711. ;   esi = asciiz path & file
  712. ;   edi = buffer for path & file name
  713. ; OUT:
  714. ;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
  715. ;   ebx = /file name - zero terminated
  716. ;   esi = pointer after source
  717.  
  718.     push  eax
  719.     push  ecx
  720.     push  edi ;[esp+0]
  721.  
  722.   pathz_start:
  723.     mov   byte [edi],'/'
  724.     inc   edi
  725.     mov   al,32
  726.     mov   ecx,11
  727.     cld
  728.     rep   stosb                 ; clear filename area
  729.     sub   edi,11
  730.     mov   ebx,edi               ; start of dir/file name
  731.  
  732.   pathz_new_char:
  733.     mov   al,[esi]
  734.     inc   esi
  735.     cmp   al,0
  736.     je    pathz_end
  737.  
  738.     cmp   al,'/'
  739.     jne   pathz_not_path
  740.     cmp   edi,ebx               ; skip first '/'
  741.     jz    pathz_new_char
  742.     lea   edi,[ebx+11]          ; start of next directory
  743.     jmp   pathz_start
  744.  
  745.   pathz_not_path:
  746.     cmp   al,'.'
  747.     jne   pathz_not_ext
  748.     lea   edi,[ebx+8]           ; start of extension
  749.     jmp   pathz_new_char
  750.  
  751.   pathz_not_ext:
  752.     cmp   al,'a'
  753.     jb    pathz_not_low
  754.     cmp   al,'z'
  755.     ja    pathz_not_low
  756.     sub   al,0x20               ; char to uppercase
  757.  
  758.   pathz_not_low:
  759.     mov   [edi],al
  760.     inc   edi
  761.     mov   eax,[esp+0]           ; start_of_dest_path
  762.     add   eax,512               ; keep maximum path under 512 bytes
  763.     cmp   edi,eax
  764.     jb    pathz_new_char
  765.  
  766.   pathz_end:
  767.     cmp   ebx,edi               ; if path end with '/'
  768.     jnz   pathz_put_zero        ; go back 1 level
  769.     sub   ebx,12
  770.  
  771.   pathz_put_zero:
  772.     mov   byte [ebx+11],0
  773.     dec   ebx                   ; include '/' char into file name
  774.     pop   edi
  775.     pop   ecx
  776.     pop   eax
  777.     ret
  778.  
  779. ;*******************************************
  780. ;* string to number
  781. ;* input eax - 4 byte string
  782. ;* output eax - number
  783. ;*******************************************
  784. StringToNumber:
  785. ;    ╧┼╨┼┬╬─ ╤╥╨╬╩╬┬╬├╬ ╫╚╤╦└ ┬ ╫╚╤╦╬┬╬╔ ┬╚─
  786. ;    ┬їюф:
  787. ;        EDI - рфЁхё ёЄЁюъш ё ўшёыюь. ╩юэхЎ ўшёыр юЄьхўхэ ъюфюь 0Dh
  788. ;    ┬√їюф:
  789. ;        CF - шэфшърЄюЁ ю°шсюъ:
  790. ;            0 - ю°шсюъ эхЄ;
  791. ;            1 - ю°шсър
  792. ;        ┼ёыш CF=0, Єю AX - ўшёыю.
  793.  
  794.     push    bx
  795.     push    cx
  796.     push    dx
  797.     push    edi
  798.     mov   [partition_string],eax
  799.     mov    edi,partition_string
  800.     xor    cx,cx
  801. i1:
  802.     mov    al,[edi]
  803.     cmp    al,32  ;13
  804.     je    i_exit
  805. ;    cmp    al,'0'
  806. ;    jb    err
  807. ;    cmp    al,'9'
  808. ;    ja    err
  809.     sub    al,48
  810.     shl    cx,1
  811.     jc    err
  812.     mov    bx,cx
  813.     shl    cx,1
  814.     jc    err
  815.     shl    cx,1
  816.     jc    err
  817.     add    cx,bx
  818.     jc    err
  819.     cbw
  820.     add    cx,ax
  821.     jc    err
  822. i3:
  823.     inc    edi
  824.     jmp    i1
  825. i_exit:
  826.     mov    ax,cx
  827.     clc
  828. i4:
  829.     movzx  eax,ax
  830.     pop    edi
  831.     pop    dx
  832.     pop    cx
  833.     pop    bx
  834.     ret
  835.  
  836. err:
  837.     stc
  838.     jmp    i4
  839.  
  840. partition_string: dd 0
  841.                   db 32
  842.