Subversion Repositories Kolibri OS

Rev

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