Subversion Repositories Kolibri OS

Rev

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