Subversion Repositories Kolibri OS

Rev

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