Subversion Repositories Kolibri OS

Rev

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

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