Subversion Repositories Kolibri OS

Rev

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