Subversion Repositories Kolibri OS

Rev

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

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