Subversion Repositories Kolibri OS

Rev

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