Subversion Repositories Kolibri OS

Rev

Rev 83 | 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   /HardDisk/First 30
  39. ; eax = 1  ; write file         /RamDisk/First 33   /HardDisk/First 56
  40. ; eax = 2  ; delete file        /RamDisk/First 32   /HardDisk/First 57
  41. ; eax = 3  ; append to a file   /RamDisk/First ??   /HardDisk/First ??
  42. ; eax = 4  ; makedir
  43. ; eax = 5  ; rename file/directory
  44. ; eax = 8  ; lba read
  45. ; eax = 15 ; get_disk_info
  46. ; eax = 16 ; start application
  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.     cmp   dword [eax+0],16      ; RUN - dont care about read&write blocks
  94.     je    fs_read
  95.     cmp   dword [eax+0],5       ; RENAME - dont care about read&write blocks
  96.     je    fs_read
  97.     cmp   dword [eax+0],4       ; MAKEDIR - dont care about read&write blocks
  98.     je    fs_read
  99.     cmp   dword [eax+0],2       ; DELETE - dont care about read&write blocks
  100.     je    fs_read
  101.  
  102.     cmp   dword [0x3000],1      ; no memory checks for kernel requests
  103.     jz    no_checks_for_kernel
  104.     mov   edx,eax
  105.     cmp   dword [eax+0],1
  106.     jz    .check_for_write_op
  107.     cmp   dword [eax+0],3
  108.     jnz   .usual_check
  109. .check_for_write_op:    
  110.     mov   ebx,[eax+12]
  111.     add   ebx,std_application_base_address
  112.     mov   ecx,[eax+8]
  113.     call  check_region
  114.     test  eax,eax
  115.     jnz   area_in_app_mem
  116.    
  117. .error_output:
  118.     mov   esi,buffer_failed
  119.     call  sys_msg_board_str
  120. ;    mov   eax,7
  121.     mov   dword [esp+36],7
  122.     ret
  123. iglobal
  124.   buffer_failed db 'K : Buffer check failed',13,10,0
  125. endg
  126. .usual_check:
  127.     cmp   dword [eax+0],0
  128.     mov   ecx,512
  129.     jnz   .small_size
  130.     mov   ecx,[eax+8]
  131.     shl   ecx,9
  132. .small_size:
  133.     mov   ebx,[eax+12]
  134.     add   ebx,std_application_base_address
  135.     call  check_region
  136.     test  eax,eax
  137.     jz    .error_output
  138.   area_in_app_mem:
  139.     mov   eax,edx
  140.   no_checks_for_kernel:
  141.  
  142.  
  143.     cmp   dword [eax+0],3       ; APPEND - allow write 0 bytes (truncate)
  144.     je    fs_read
  145.     cmp   dword [eax+8],0       ; read or write 0 blocks/bytes ?
  146.     jne   fs_read
  147.     and   dword [esp+36],0
  148.     ret
  149.   fs_read:
  150.  
  151.     mov   ebx,[eax+20]          ; program wants root directory ?
  152.     test  bl,bl
  153.     je    fs_getroot
  154.     test  bh,bh
  155.     jne   fs_noroot
  156.   fs_getroot:
  157. ; \begin{diamond}[18.03.2006]
  158. ; root - only read is allowed
  159. ; other operations return "access denied", eax=10
  160. ; (execute operation returns eax=-10)
  161.     cmp    dword [eax], 0
  162.     jz    .read_root
  163.     mov    ecx, 10
  164.     cmp    dword [eax], 16
  165.     jnz    @f
  166.     neg    ecx
  167. @@:    mov    [esp+36], ecx
  168.     ret
  169. .read_root:
  170. ; \end{diamond}[18.03.2006]
  171.     mov   esi,dir0
  172.     mov   edi,[eax+12]
  173.     add   edi,std_application_base_address
  174.     mov   ecx,11
  175.     push  ecx
  176. ;    cld    ; already is
  177.     rep   movsb
  178.     mov   al,0x10
  179.     stosb
  180.     add   edi,32-11-1
  181.     pop   ecx
  182.     rep   movsb
  183.     stosb
  184.     and   dword [esp+36],0      ; ok read
  185.     mov   dword [esp+24],32*2   ; size of root
  186.     ret
  187.  
  188.   fs_info:                      ;start of code - Mihasik
  189.     push  eax
  190.     cmp   [eax+21],byte 'h'
  191.     je    fs_info_h
  192.     cmp   [eax+21],byte 'H'
  193.     je    fs_info_h
  194.     cmp   [eax+21],byte 'r'
  195.     je    fs_info_r
  196.     cmp   [eax+21],byte 'R'
  197.     je    fs_info_r
  198.     mov   eax,3                 ;if unknown disk
  199.     xor   ebx,ebx
  200.     xor   ecx,ecx
  201.     xor   edx,edx
  202.     jmp   fs_info1
  203.   fs_info_r:
  204.     call  ramdisk_free_space    ;if ramdisk
  205.     mov   ecx,edi               ;free space in ecx
  206.     shr   ecx,9                 ;free clusters
  207.     mov   ebx,2847              ;total clusters
  208.     mov   edx,512               ;cluster size
  209.     xor   eax,eax               ;always 0
  210.     jmp   fs_info1
  211.   fs_info_h:                    ;if harddisk
  212.     call  get_hd_info
  213.   fs_info1:
  214.     pop   edi
  215.     mov   [esp+36],eax
  216.     mov   [esp+24],ebx           ; total clusters on disk
  217.     mov   [esp+32],ecx           ; free clusters on disk
  218.     mov   [edi],edx              ; cluster size in bytes
  219.     ret                          ;end of code - Mihasik
  220.  
  221.   fs_noroot:
  222.  
  223.     push  dword [eax+0]         ; read/write/delete/.../makedir/rename/lba/run
  224.     push  dword [eax+4]         ; 512 block number to read
  225.     push  dword [eax+8]         ; bytes to write/append or 512 blocks to read
  226.     mov   ebx,[eax+12]
  227.     add   ebx,std_application_base_address
  228.     push  ebx                   ; abs start of return/save area
  229.  
  230.     lea   esi,[eax+20]          ; abs start of dir + filename
  231.     mov   edi,[eax+16]
  232.     add   edi,std_application_base_address    ; abs start of work area
  233.  
  234.     call  expand_pathz
  235.  
  236.     push  edi                   ; dir start
  237.     push  ebx                   ; name of file start
  238.  
  239.     mov   eax,[edi+1]
  240.     cmp   eax,'RD  '
  241.     je    fs_yesramdisk
  242.     cmp   eax,'RAMD'
  243.     jne   fs_noramdisk
  244.  
  245.   fs_yesramdisk:
  246.  
  247.     cmp   byte [edi+1+11],0
  248.     je    fs_give_dir1
  249.  
  250.     mov   eax,[edi+1+12]
  251.     cmp   eax,'1   '
  252.     je    fs_yesramdisk_first
  253.     cmp   eax,'FIRS'
  254.     jne   fs_noramdisk
  255.  
  256.   fs_yesramdisk_first:
  257.  
  258.     cmp   dword [esp+20],8      ; LBA read ramdisk
  259.     jne   fs_no_LBA_read_ramdisk
  260.  
  261.     mov   eax,[esp+16]          ; LBA block to read
  262.     mov   ecx,[esp+8]           ; abs pointer to return area
  263.  
  264.     call  LBA_read_ramdisk
  265.     jmp   file_system_return
  266.  
  267.  
  268.   fs_no_LBA_read_ramdisk:
  269.  
  270.     cmp   dword [esp+20],0      ; READ
  271.     jne   fs_noramdisk_read
  272.  
  273.     mov   eax,[esp+4]           ; fname
  274.     add   eax,2*12+1
  275.     mov   ebx,[esp+16]          ; block start
  276.     inc   ebx
  277.     mov   ecx,[esp+12]          ; block count
  278.     mov   edx,[esp+8]           ; return
  279.     mov   esi,[esp+0]
  280.     sub   esi,eax
  281.     add   esi,12+1              ; file name length
  282.     call  fileread
  283.  
  284.     jmp   file_system_return
  285.  
  286.  
  287.   fs_noramdisk_read:
  288.  
  289.     cmp   dword [esp+20],1      ; WRITE
  290.     jne   fs_noramdisk_write
  291.  
  292.     mov   eax,[esp+4]           ; fname
  293.     add   eax,2*12+1
  294.     mov   ebx,[esp+8]           ; buffer
  295.     mov   ecx,[esp+12]          ; count to write
  296.     mov   edx,0                 ; create new
  297.     call  filesave
  298.  
  299.     ; eax=0 ok - eax=1 not enough free space
  300.  
  301.     jmp   file_system_return
  302.  
  303.   fs_noramdisk_write:
  304.  
  305.     cmp   dword [esp+20],16     ; START APPLICATION
  306.     jne   fs_noramdisk_start_application
  307.  
  308.     mov   eax,[esp+4]           ; fname
  309.     add   eax,2*12+1
  310.  
  311.     xor   ebx,ebx               ; parameters to pass
  312.     cmp   dword [esp+12],ebx;0
  313.     je    no_fl_start_param
  314.     mov   ebx, [esp+12]
  315.     add   ebx, std_application_base_address
  316.   no_fl_start_param:
  317.     mov   edx,[esp+16]        ; flags
  318.  
  319.     call  start_application_fl
  320.  
  321.     jmp   file_system_startapp_return
  322.  
  323.   fs_noramdisk_start_application:     ;there's new code - Mihasik
  324.     cmp   dword [esp+20],2      ;DELETE
  325.     jne   fs_noramdisk_delete
  326.     mov   eax,[esp+4]           ; fname
  327.     add   eax,2*12+1
  328.     call  filedelete
  329.     jmp   file_system_return
  330.  
  331.   fs_noramdisk_delete:
  332.   fs_noramdisk:
  333.  
  334.   ;********************************************************************
  335.     mov   eax,[edi+1]
  336.     cmp   eax,'FD  '
  337.     je    fs_yesflpdisk
  338.     cmp   eax,'FLOP'
  339.     jne   fs_noflpdisk
  340.  
  341.   fs_yesflpdisk:
  342.     call   reserve_flp
  343.  
  344.     cmp   byte [edi+1+11],0
  345.     je    fs_give_dir1
  346.  
  347.     mov   eax,[edi+1+12]
  348.     cmp   eax,'1   '            
  349.     je    fs_yesflpdisk_first
  350.     cmp   eax,'FIRS'
  351.     je    fs_yesflpdisk_first
  352.     cmp   eax,'2   '
  353.     je    fs_yesflpdisk_second
  354.     cmp   eax,'SECO'
  355.     jne   fs_noflpdisk
  356.     jmp   fs_yesflpdisk_second
  357.  
  358.   fs_yesflpdisk_first:
  359.     mov   [flp_number],1
  360.     jmp   fs_yesflpdisk_start
  361.   fs_yesflpdisk_second:
  362.     mov   [flp_number],2
  363.   fs_yesflpdisk_start:
  364.     cmp   dword [esp+20],0      ; READ
  365.     jne   fs_noflpdisk_read
  366.  
  367.     mov   eax,[esp+4]           ; fname
  368.     add   eax,2*12+1
  369.     mov   ebx,[esp+16]          ; block start
  370.     inc   ebx
  371.     mov   ecx,[esp+12]          ; block count
  372.     mov   edx,[esp+8]           ; return
  373.     mov   esi,[esp+0]
  374.     sub   esi,eax
  375.     add   esi,12+1              ; file name length
  376.     call  floppy_fileread
  377.  
  378.     jmp   file_system_return
  379.  
  380.  
  381.   fs_noflpdisk_read:
  382.  
  383.     cmp   dword [esp+20],1      ; WRITE
  384.     jne   fs_noflpdisk_write
  385.  
  386.     mov   eax,[esp+4]           ; fname
  387.     add   eax,2*12+1
  388.     mov   ebx,[esp+8]           ; buffer
  389.     mov   ecx,[esp+12]          ; count to write
  390.     mov   edx,0                 ; create new
  391.     call  floppy_filesave
  392.  
  393.     ; eax=0 ok - eax=1 not enough free space
  394.  
  395.     jmp   file_system_return
  396.  
  397.   fs_noflpdisk_write:
  398.  
  399.     cmp   dword [esp+20],2      ; DELETE
  400.     jne   fs_noflpdisk_delete
  401.  
  402.     mov   eax,[esp+4]           ; fname
  403.     add   eax,2*12+1
  404.     call  floppy_filedelete
  405.     mov   [flp_status],0
  406.     jmp   file_system_return
  407.  
  408.   fs_noflpdisk_delete:
  409.     cmp   dword [esp+20],16     ; START APPLICATION
  410.     jne   fs_noflpdisk_start_application
  411.  
  412.     mov   eax,[esp+4]           ; fname
  413.     add   eax,2*12+1
  414.  
  415.     xor   ebx,ebx               ; parameters to pass
  416.     cmp   dword [esp+12],ebx;0
  417.     je    no_flp_start_param
  418.     mov   ebx,[0x3010]
  419.     mov   ebx,[ebx+0x10]
  420.     add   ebx,[esp+12]
  421.  
  422.   no_flp_start_param:
  423.     mov   edx,[esp+16]        ; flags
  424.  
  425.     call  start_application_floppy
  426.  
  427. file_system_startapp_return:
  428.     mov    ebx, [esp+24+24]    ; do not modify ebx in application
  429.     jmp   file_system_return
  430.  
  431.   fs_noflpdisk_start_application:
  432.  
  433.   fs_noflpdisk:
  434.   ;*****************************************************************
  435.  
  436.     mov   eax,[edi+1]
  437.     cmp   eax,'HD0 '
  438.     je    fs_yesharddisk_IDE0
  439.     cmp   eax,'HD1 '
  440.     je    fs_yesharddisk_IDE1
  441.     cmp   eax,'HD2 '
  442.     je    fs_yesharddisk_IDE2
  443.     cmp   eax,'HD3 '
  444.     je    fs_yesharddisk_IDE3
  445.     jmp   old_path_harddisk
  446. fs_yesharddisk_IDE0:
  447.      call  reserve_hd1
  448.      mov  [hdbase],0x1f0
  449.      mov  [hdid],0x0
  450.      mov  [hdpos],1
  451.      jmp  fs_yesharddisk_partition
  452. fs_yesharddisk_IDE1:
  453.      call  reserve_hd1
  454.      mov  [hdbase],0x1f0
  455.      mov  [hdid],0x10
  456.      mov  [hdpos],2
  457.      jmp  fs_yesharddisk_partition
  458. fs_yesharddisk_IDE2:
  459.      call  reserve_hd1
  460.      mov  [hdbase],0x170
  461.      mov  [hdid],0x0
  462.      mov  [hdpos],3
  463.      jmp  fs_yesharddisk_partition
  464. fs_yesharddisk_IDE3:
  465.      call  reserve_hd1
  466.      mov  [hdbase],0x170
  467.      mov  [hdid],0x10
  468.      mov  [hdpos],4
  469. fs_yesharddisk_partition:
  470. ;    call  choice_necessity_partition
  471. ;    jmp   fs_yesharddisk_all    
  472.     jmp   fs_for_new_semantic
  473.  
  474. choice_necessity_partition:
  475.     mov   eax,[edi+1+12]
  476.     call  StringToNumber
  477.         mov   [fat32part],eax
  478. choice_necessity_partition_1:
  479.     mov   ecx,[hdpos]
  480.     xor   eax,eax
  481.     mov   [0xfe10], eax    ; entries in hd cache
  482.     mov   edx,0x40002
  483.  search_partition_array:
  484.     mov   bl,[edx]
  485.     movzx ebx,bl
  486.     add   eax,ebx
  487.     inc   edx
  488.     loop  search_partition_array
  489.     sub   eax,ebx
  490.     add   eax,[fat32part]
  491.     dec   eax
  492.     xor   edx,edx
  493.     imul  eax,100
  494.     add   eax,0x4000a
  495.     mov   [transfer_adress],eax
  496.     call  partition_data_transfer_1
  497.     ret
  498.  
  499.  old_path_harddisk:
  500.     mov   eax,[edi+1]
  501.     cmp   eax,'HD  '
  502.     je    fs_yesharddisk
  503.     cmp   eax,'HARD'
  504.     jne   fs_noharddisk
  505.  
  506.   fs_yesharddisk:
  507.     cmp   dword [esp+20],8      ; LBA read
  508.     jne   fs_no_LBA_read
  509.     mov   eax,[esp+16]          ; LBA block to read
  510.     lea   ebx,[edi+1+12]        ; pointer to FIRST/SECOND/THIRD/FOURTH
  511.     mov   ecx,[esp+8]           ; abs pointer to return area
  512.     call  LBA_read
  513.     jmp   file_system_return
  514.  
  515.   fs_no_LBA_read:
  516.  
  517.     cmp   byte [edi+1+11],0     ; directory read
  518.     je    fs_give_dir1
  519.     call  reserve_hd1
  520.  fs_for_new_semantic:
  521.     call  choice_necessity_partition
  522.  
  523.   fs_yesharddisk_all:
  524.     mov   eax,1
  525.     cmp    dword [esp+20], 16
  526.     jnz    @f
  527.     neg    eax
  528. @@:    mov    ebx, [esp+24+24]
  529.     cmp   [hdpos],0             ; is hd base set?
  530.     jz    hd_err_return
  531.     cmp   [fat32part],0         ; is partition set?
  532.     jnz   @f
  533. hd_err_return:
  534.     and   [hd1_status], 0
  535.     jmp   file_system_return
  536. @@:
  537.  
  538.     cmp   dword [esp+20],0      ; READ
  539.     jne   fs_noharddisk_read
  540.  
  541.     mov   eax,[esp+0]           ; /fname
  542.     lea   edi,[eax+12]
  543.     mov   byte [eax],0          ; path to asciiz
  544.     inc   eax                   ; filename start
  545.  
  546.     mov   ebx,[esp+12]          ; count to read
  547.     mov   ecx,[esp+8]           ; buffer
  548.     mov   edx,[esp+4]
  549.     add   edx,12*2              ; dir start
  550.     sub   edi,edx               ; path length
  551.     mov   esi,[esp+16]          ; blocks to read
  552.  
  553.     call  file_read
  554.  
  555.     mov   edi,[esp+0]
  556.     mov   byte [edi],'/'
  557.  
  558.     jmp   file_system_return
  559.  
  560.   fs_noharddisk_read:
  561.  
  562.  
  563.     cmp   dword [esp+20],1      ; WRITE
  564.     jne   fs_noharddisk_write
  565.  
  566.     mov   eax,[esp+0]           ; /fname
  567.     mov   byte [eax],0          ; path to asciiz
  568.     inc   eax                   ; filename start
  569.  
  570.     mov   ebx,[esp+12]          ; count to write
  571.     mov   ecx,[esp+8]           ; buffer
  572.     mov   edx,[esp+4]
  573.     add   edx,12*2              ; path start
  574.  
  575.     call  file_write
  576.  
  577.     mov   edi,[esp+0]
  578.     mov   byte [edi],'/'
  579.  
  580.     ; eax=0 ok - eax=1 not enough free space
  581.  
  582.     jmp   file_system_return
  583.  
  584.  
  585.   fs_noharddisk_write:
  586.  
  587.     cmp   dword [esp+20],2      ; DELETE
  588.     jne   fs_noharddisk_delete
  589.  
  590.     mov   eax,[esp+0]           ; /dirname or /filename
  591.     mov   byte [eax],0          ; path to asciiz
  592.     inc   eax                   ; filename start
  593.     mov   edx,[esp+4]
  594.     add   edx,12*2              ; path start
  595.  
  596.     call  removedir
  597.  
  598.     mov   edi,[esp+0]
  599.     mov   byte [edi],'/'
  600.  
  601.     jmp   file_system_return
  602.  
  603.   fs_noharddisk_delete:
  604.  
  605.     cmp   dword [esp+20],3      ; APPEND
  606.     jne   fs_noharddisk_append
  607.  
  608.     mov   eax,[esp+0]           ; /dirname or /filename
  609.     mov   byte [eax],0          ; path to asciiz
  610.     inc   eax                   ; filename start
  611.     mov   edx,[esp+4]
  612.     add   edx,12*2              ; path start
  613.     mov   ecx,[esp+8]           ; buffer
  614.     mov   ebx,[esp+12]          ; count to write
  615.     mov   esi,[esp+16]          ; bytes to skip over
  616.  
  617.     call  file_append
  618.  
  619.     mov   edi,[esp+0]
  620.     mov   byte [edi],'/'
  621.  
  622.     jmp   file_system_return
  623.  
  624.   fs_noharddisk_append:
  625.  
  626.     cmp   dword [esp+20],4      ; MAKEDIR
  627.     jne   fs_noharddisk_makedir
  628.  
  629.     mov   eax,[esp+0]           ; /dirname
  630.     mov   byte [eax],0          ; path to asciiz
  631.     inc   eax                   ; filename start
  632.     mov   edx,[esp+4]
  633.     add   edx,12*2              ; path start
  634.  
  635.     call  makedir
  636.  
  637.     mov   edi,[esp+0]
  638.     mov   byte [edi],'/'
  639.  
  640.     jmp   file_system_return
  641.  
  642.   fs_noharddisk_makedir:
  643.  
  644.     cmp   dword [esp+20],5      ; RENAME
  645.     jne   fs_noharddisk_rename
  646.  
  647.     mov   edi,[esp+0]           ; start of source file name
  648.     add   edi,12+1              ; continue after name
  649.     call  expand_pathz          ; convert destination name
  650.  
  651.     mov   eax,[edi+1]
  652.     cmp   eax,'HD  '
  653.     je    fs_rename_test1
  654.     cmp   eax,'HARD'
  655.     jne   fs_rename_error
  656.  
  657.   fs_rename_test1:
  658.     mov   eax,[edi+1+12]
  659.     cmp   eax,'1   '
  660.     je    fs_rename_start
  661.     cmp   eax,'FIRS'
  662.     jne   fs_rename_error
  663.  
  664.   fs_rename_start:
  665.     mov   byte [ebx],0          ; path to asciiz
  666.     inc   ebx                   ; filename start
  667.     add   edi,12*2              ; path start
  668.     cmp   byte [ebx],0
  669.     je    fs_rename_error
  670.     cmp   byte [ebx],32
  671.     je    fs_rename_error
  672.  
  673.     mov   eax,[esp+0]           ; /filename
  674.     mov   byte [eax],0          ; path to asciiz
  675.     inc   eax                   ; filename start
  676.     mov   edx,[esp+4]
  677.     add   edx,12*2              ; path start
  678.  
  679.     call  rename
  680.  
  681.     mov   edi,[esp+0]
  682.     mov   byte [edi],'/'
  683.  
  684.     jmp   file_system_return
  685.  
  686.   fs_rename_error:
  687.     mov   eax,4                 ; partition not defined at hd
  688.     jmp   file_system_return
  689.  
  690.   fs_noharddisk_rename:
  691.  
  692.     cmp   dword [esp+20],16     ; START APPLICATION
  693.     jne   fs_noharddisk_start_application
  694.  
  695.     mov   eax,[esp+4]           ; fname
  696.     add   eax,12*2
  697.  
  698.     mov   ebx,[esp+0]           ; length
  699.     sub   ebx,eax
  700.     add   ebx,12
  701.  
  702.     mov   ecx,[esp+4]           ; work area
  703.     add   ecx,512
  704.  
  705.     xor   ebp,ebp               ; parameters to pass
  706.     cmp   dword [esp+12],ebp;0
  707.     je    no_hd_start_param
  708.     mov   ebp, [esp+12]
  709.     add   ebp, std_application_base_address
  710.   no_hd_start_param:
  711.     mov   edx,[esp+16]        ; flags
  712.  
  713.     call  start_application_hd
  714.  
  715.     jmp   file_system_startapp_return
  716.  
  717.   fs_noharddisk_start_application:
  718.  
  719.   fs_noharddisk:
  720. ; \begin{diamond}[18.03.2006]
  721.     mov    eax, 5        ; file not found
  722. ; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
  723.     cmp    dword [esp+20], 16
  724.     jnz    @f
  725.     neg    eax
  726. @@:    mov    ebx, [esp+24+24]    ; do not change ebx in application
  727. ; \end{diamond}[18.03.2006]
  728.  
  729.   file_system_return:
  730.  
  731.     add   esp,24
  732.  
  733.     mov   [esp+36],eax
  734.     mov   [esp+24],ebx
  735.     ret
  736.  
  737.  
  738.   fs_give_dir1:
  739.  
  740. ; \begin{diamond}[18.03.2006]
  741. ; /RD,/FD,/HD - only read is allowed
  742. ; other operations return "access denied", eax=10
  743. ; (execute operation returns eax=-10)
  744.     cmp    dword [esp+20], 0
  745.     jz    .read
  746.     add    esp, 20
  747.     pop    ecx
  748.     mov    eax, 10
  749.     cmp    ecx, 16
  750.     jnz    @f
  751.     neg    eax
  752. @@:    mov    [esp+36], eax
  753.     ret
  754. .read:
  755. ; \end{diamond}[18.03.2006]
  756.     mov   al,0x10
  757.     mov   ebx,1
  758.     mov   edi,[esp+8]
  759.     mov   esi,dir1
  760.   fs_d1_new:
  761.     mov   ecx,11
  762. ;    cld
  763.     rep   movsb
  764.     stosb
  765.     add   edi,32-11-1
  766.     dec   ebx
  767.     jne   fs_d1_new
  768.  
  769.     add   esp,24
  770.  
  771.     and   dword [esp+36],0      ; ok read
  772.     mov   dword [esp+24],32*1   ; dir/data size
  773.     ret
  774.  
  775.  
  776.  
  777. LBA_read_ramdisk:
  778.  
  779.     cmp   [lba_read_enabled],1
  780.     je    lbarrl1
  781.  
  782.     xor   ebx,ebx
  783.     mov   eax,2
  784.     ret
  785.  
  786.   lbarrl1:
  787.  
  788.     cmp   eax,18*2*80
  789.     jb    lbarrl2
  790.     xor   ebx,ebx
  791.     mov   eax,3
  792.     ret
  793.  
  794.   lbarrl2:
  795.  
  796.     pushad
  797.  
  798.     call  restorefatchain
  799.  
  800.     mov   edi,ecx
  801.     mov   esi,eax
  802.  
  803.     shl   esi,9
  804.     add   esi,0x100000
  805.     mov   ecx,512/4
  806. ;    cld
  807.     rep   movsd
  808.  
  809.     popad
  810.  
  811.     xor   ebx,ebx
  812.     xor   eax,eax
  813.     ret
  814.  
  815. LBA_read:
  816.  
  817. ; IN:
  818. ;
  819. ; eax = LBA block to read
  820. ; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
  821. ; ecx = abs pointer to return area
  822.  
  823.     cmp   [lba_read_enabled],1
  824.     je    lbarl1
  825.     mov   eax,2
  826.     ret
  827.  
  828.   lbarl1:
  829.  
  830.     call  reserve_hd1
  831.  
  832.     push  eax
  833.     push  ecx
  834.  
  835.     mov   edi,hd_address_table
  836.     mov   esi,dir1
  837.     mov   eax,[ebx]
  838.     mov   edx,'1   '
  839.     mov   ecx,4
  840.   blar0:
  841.     cmp   eax,[esi]
  842.     je    blar2
  843.     cmp   eax,edx
  844.     je    blar2
  845.     inc   edx
  846.     add   edi,8
  847.     add   esi,11
  848.     dec   ecx
  849.     jnz   blar0
  850.  
  851.     mov   eax,1
  852.     mov   ebx,1
  853.     jmp   LBA_read_ret
  854.  
  855.   blar2:
  856.     mov   eax,[edi+0]
  857.     mov   ebx,[edi+4]
  858.  
  859.     mov  [hdbase],eax
  860.     mov  [hdid],ebx
  861.  
  862.     call  wait_for_hd_idle
  863.     cmp   [hd_error],0
  864.     jne   hd_lba_error
  865.  
  866.     ; eax = hd port
  867.     ; ebx = set for primary (0x00) or slave (0x10)
  868.  
  869.     cli
  870.  
  871.     mov   edx,eax
  872.     inc   edx
  873.     xor   eax,eax
  874.     out   dx,al
  875.     inc   edx
  876.     inc   eax
  877.     out   dx,al
  878.     inc   edx
  879.     mov   eax,[esp+4]
  880.     out   dx,al
  881.     shr   eax,8
  882.     inc   edx
  883.     out   dx,al
  884.     shr   eax,8
  885.     inc   edx
  886.     out   dx,al
  887.     shr   eax,8
  888.     inc   edx
  889.     and   al,1+2+4+8
  890.     add   al,bl
  891.     add   al,128+64+32
  892.     out   dx,al
  893.  
  894.     inc   edx
  895.     mov   al,20h
  896.     out   dx,al
  897.  
  898.     sti
  899.  
  900.     call  wait_for_sector_buffer
  901.     cmp   [hd_error],0
  902.     jne   hd_lba_error
  903.  
  904.     cli
  905.  
  906.     mov   edi,[esp+0]
  907.     mov   ecx,256
  908.     sub   edx,7
  909.     cld
  910.     rep   insw
  911.  
  912.     sti
  913.  
  914.     xor   eax,eax
  915.     xor   ebx,ebx
  916.  
  917.   LBA_read_ret:
  918.     mov [hd_error],0
  919.     mov   [hd1_status],0
  920.     add   esp,2*4
  921.  
  922.     ret
  923.  
  924.  
  925. expand_pathz:
  926. ; IN:
  927. ;   esi = asciiz path & file
  928. ;   edi = buffer for path & file name
  929. ; OUT:
  930. ;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
  931. ;   ebx = /file name - zero terminated
  932. ;   esi = pointer after source
  933.  
  934.     push  eax
  935.     push  ecx
  936.     push  edi ;[esp+0]
  937.  
  938.   pathz_start:
  939.     mov   byte [edi],'/'
  940.     inc   edi
  941.     mov   al,32
  942.     mov   ecx,11
  943.     cld
  944.     rep   stosb                 ; clear filename area
  945.     sub   edi,11
  946.     mov   ebx,edi               ; start of dir/file name
  947.  
  948.   pathz_new_char:
  949.     mov   al,[esi]
  950.     inc   esi
  951.     cmp   al,0
  952.     je    pathz_end
  953.  
  954.     cmp   al,'/'
  955.     jne   pathz_not_path
  956.     cmp   edi,ebx               ; skip first '/'
  957.     jz    pathz_new_char
  958.     lea   edi,[ebx+11]          ; start of next directory
  959.     jmp   pathz_start
  960.  
  961.   pathz_not_path:
  962.     cmp   al,'.'
  963.     jne   pathz_not_ext
  964.     lea   edi,[ebx+8]           ; start of extension
  965.     jmp   pathz_new_char
  966.  
  967.   pathz_not_ext:
  968.     cmp   al,'a'
  969.     jb    pathz_not_low
  970.     cmp   al,'z'
  971.     ja    pathz_not_low
  972.     sub   al,0x20               ; char to uppercase
  973.  
  974.   pathz_not_low:
  975.     mov   [edi],al
  976.     inc   edi
  977.     mov   eax,[esp+0]           ; start_of_dest_path
  978.     add   eax,512               ; keep maximum path under 512 bytes
  979.     cmp   edi,eax
  980.     jb    pathz_new_char
  981.  
  982.   pathz_end:
  983.     cmp   ebx,edi               ; if path end with '/'
  984.     jnz   pathz_put_zero        ; go back 1 level
  985.     sub   ebx,12
  986.  
  987.   pathz_put_zero:
  988.     mov   byte [ebx+11],0
  989.     dec   ebx                   ; include '/' char into file name
  990.     pop   edi
  991.     pop   ecx
  992.     pop   eax
  993.     ret
  994.  
  995. ;*******************************************
  996. ;* string to number
  997. ;* input eax - 4 byte string
  998. ;* output eax - number
  999. ;*******************************************
  1000. StringToNumber:
  1001. ;    ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ
  1002. ;    Âõîä:
  1003. ;        EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh
  1004. ;    Âûõîä:
  1005. ;        CF - èíäèêàòîð îøèáîê:
  1006. ;            0 - îøèáîê íåò;
  1007. ;            1 - îøèáêà
  1008. ;        Åñëè CF=0, òî AX - ÷èñëî.
  1009.  
  1010.     push    bx
  1011.     push    cx
  1012.     push    dx
  1013.     push    edi
  1014.     mov   [partition_string],eax
  1015.     mov    edi,partition_string
  1016.     xor    cx,cx
  1017. i1:
  1018.     mov    al,[edi]
  1019.     cmp    al,32  ;13
  1020.     je    i_exit
  1021. ;    cmp    al,'0'
  1022. ;    jb    err
  1023. ;    cmp    al,'9'
  1024. ;    ja    err
  1025.     sub    al,48
  1026.     shl    cx,1
  1027.     jc    err
  1028.     mov    bx,cx
  1029.     shl    cx,1
  1030.     jc    err
  1031.     shl    cx,1
  1032.     jc    err
  1033.     add    cx,bx
  1034.     jc    err
  1035.     cbw
  1036.     add    cx,ax
  1037.     jc    err
  1038. i3:
  1039.     inc    edi
  1040.     jmp    i1
  1041. i_exit:
  1042.     mov    ax,cx
  1043.     clc
  1044. i4:
  1045.     movzx  eax,ax
  1046.     pop    edi
  1047.     pop    dx
  1048.     pop    cx
  1049.     pop    bx
  1050.     ret
  1051.  
  1052. err:
  1053.     stc
  1054.     jmp    i4
  1055.  
  1056. partition_string: dd 0
  1057.                   db 32
  1058.