Subversion Repositories Kolibri OS

Rev

Rev 465 | Rev 520 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. $Revision: 488 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. image_of_eax EQU esp+44 ;36
  10. image_of_ebx EQU esp+32 ;24
  11.  
  12. ; System function 70 - files with long names (LFN)
  13. ; diamond, 2006
  14.  
  15. iglobal
  16. ; in this table names must be in lowercase
  17. rootdirs:
  18.         db      2,'rd'
  19.         dd      fs_OnRamdisk
  20.         dd      fs_NextRamdisk
  21.         db      7,'ramdisk'
  22.         dd      fs_OnRamdisk
  23.         dd      fs_NextRamdisk
  24.         db      2,'fd'
  25.         dd      fs_OnFloppy
  26.         dd      fs_NextFloppy
  27.         db      10,'floppydisk'
  28.         dd      fs_OnFloppy
  29.         dd      fs_NextFloppy
  30.         db      3,'hd0'
  31.         dd      fs_OnHd0
  32.         dd      fs_NextHd0
  33.         db      3,'hd1'
  34.         dd      fs_OnHd1
  35.         dd      fs_NextHd1
  36.         db      3,'hd2'
  37.         dd      fs_OnHd2
  38.         dd      fs_NextHd2
  39.         db      3,'hd3'
  40.         dd      fs_OnHd3
  41.         dd      fs_NextHd3
  42. ;**********************************************
  43.         db      3,'cd0'
  44.         dd      fs_OnCd0
  45.         dd      fs_NextCd
  46.         db      3,'cd1'
  47.         dd      fs_OnCd1
  48.         dd      fs_NextCd
  49.         db      3,'cd2'
  50.         dd      fs_OnCd2
  51.         dd      fs_NextCd
  52.         db      3,'cd3'
  53.         dd      fs_OnCd3
  54.         dd      fs_NextCd
  55. ;***********************************************
  56.         db      0
  57.  
  58.  
  59. virtual_root_query:
  60.         dd      fs_HasRamdisk
  61.         db      'rd',0
  62.         dd      fs_HasFloppy
  63.         db      'fd',0
  64.         dd      fs_HasHd0
  65.         db      'hd0',0
  66.         dd      fs_HasHd1
  67.         db      'hd1',0
  68.         dd      fs_HasHd2
  69.         db      'hd2',0
  70.         dd      fs_HasHd3
  71.         db      'hd3',0
  72. ;**********************************************
  73.         dd      fs_HasCd0
  74.         db      'cd0',0
  75.         dd      fs_HasCd1
  76.         db      'cd1',0
  77.         dd      fs_HasCd2
  78.         db      'cd2',0
  79.         dd      fs_HasCd3
  80.         db      'cd3',0
  81. ;**********************************************
  82.         dd      0
  83. endg
  84.  
  85. end_of_file_system_lfn:
  86.                 pop edx
  87.                 stdcall kernel_free, edx
  88.                 ret
  89.  
  90.  
  91. file_system_lfn:
  92. ; in: eax->fileinfo block
  93. ; operation codes:
  94. ; 0 : read file
  95. ; 1 : read folder
  96. ; 2 : create/rewrite file
  97. ; 3 : write/append to file
  98. ; 4 : set end of file
  99. ; 5 : get file/directory attributes structure
  100. ; 6 : set file/directory attributes structure
  101. ; 7 : start application
  102. ; 8 : delete file
  103. ; 9 : create directory
  104.  
  105.                 ; çàìåíà àäðåñà âîçâðàòà
  106.                 push    eax
  107.                 stdcall kernel_alloc, 200
  108.                 mov             edx,eax
  109.                 pop             eax
  110.                 push    edx
  111.                 push    end_of_file_system_lfn
  112.                 mov             ebx,edx
  113.                                
  114.                 mov             ecx, [eax]
  115.         mov             [ebx],ecx
  116.  
  117.                 add             ebx,4
  118.                 mov             ecx, [eax+4]
  119.         mov             [ebx],ecx
  120.  
  121.                 add             ebx,4
  122.                 mov             ecx, [eax+8]
  123.         mov             [ebx],ecx
  124.  
  125.                 add             ebx,4
  126.                 mov             ecx, [eax+12]
  127.         mov             [ebx],ecx
  128.  
  129.                 add             ebx,4
  130.                 mov             ecx, [eax+16]
  131.         mov             [ebx],ecx
  132.  
  133.                 add             ebx,4
  134.                 push    edx       ; !!!!!!!!!!!!!!!!!!!
  135.                 ; eax - yíà÷àëî ñòàðîãî ïàêåòà
  136.                 ; edx - íà÷àëî íîâîãî ïàêåòà
  137.                 ; ebx - êóäà ëîæèòü ñòðîêó                     
  138.                 add             eax,20
  139.                 mov             cl,     [eax]
  140.                 test    cl,cl
  141.                 jnz             @f
  142.                 mov             eax,[eax+1]
  143. @@:
  144.                 stdcall full_file_name,eax,ebx
  145.                 pop             eax
  146.                
  147.                
  148.                
  149.                
  150.  
  151.  
  152.    ;     add     eax, std_application_base_address
  153. ; parse file name
  154.         xchg    ebx, eax
  155.         lea     esi, [ebx+20]
  156.         mov     ebp, esi        ; for 'start app' function full path must be known
  157.         lodsb
  158.         test    al, al
  159.         jnz     @f
  160.         mov     esi, [esi]
  161.   ;      add     esi, std_application_base_address
  162.         mov     ebp, esi
  163.         lodsb
  164. @@:
  165.         cmp dword [ebx], 7
  166.         jne @F
  167.         mov edx, [ebx+4]
  168.         mov ebx, [ebx+8]
  169.         test ebx, ebx
  170.         jz .l1
  171.     ;    add ebx, new_app_base
  172. .l1:
  173.         call fs_execute  ; ebp, ebx, edx
  174.         mov [image_of_eax], eax
  175.         ret
  176. @@:
  177.         cmp     al, '/'
  178.         jz      @f
  179. .notfound:
  180.         mov     dword [image_of_eax], 5       ; file not found
  181.         ret
  182. @@:
  183.         cmp     byte [esi], 0
  184.         jz      .rootdir
  185.         mov     edi, rootdirs-8
  186.         xor     ecx, ecx
  187.         push    esi
  188. .scan1:
  189.         pop     esi
  190.         add     edi, ecx
  191.         scasd
  192.         scasd
  193.         mov     cl, byte [edi]
  194.         jecxz   .notfound
  195.         inc     edi
  196.         push    esi
  197. @@:
  198.         lodsb
  199.         or      al, 20h
  200.         scasb
  201.         loopz   @b
  202.         jnz     .scan1
  203.         lodsb
  204.         cmp     al, '/'
  205.         jz      .found1
  206.         test    al, al
  207.         jnz     .scan1
  208.         pop     eax
  209. ; directory /xxx
  210. .maindir:
  211.         cmp     dword [ebx], 1
  212.         jnz     .access_denied
  213.         xor     eax, eax
  214.         mov     ebp, [ebx+12]
  215.         mov     edx, [ebx+16]
  216.     ;    add     edx, std_application_base_address
  217.         push    dword [ebx+4]   ; first block
  218.         mov     ebx, [ebx+8]    ; flags
  219.         mov     esi, [edi+4]
  220. ; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
  221.         mov     edi, edx
  222.         mov     ecx, 32/4
  223.         rep     stosd
  224.         mov     byte [edx], 1   ; version
  225. .maindir_loop:
  226.         call    esi
  227.         jc      .maindir_done
  228.         inc     dword [edx+8]
  229.         dec     dword [esp]
  230.         jns     .maindir_loop
  231.         dec     ebp
  232.         js      .maindir_loop
  233.         inc     dword [edx+4]
  234.         mov     dword [edi], 0x10       ; attributes: folder
  235.         mov     dword [edi+4], 1        ; name type: UNICODE
  236.         push    eax
  237.         xor     eax, eax
  238.         add     edi, 8
  239.         mov     ecx, 40/4-2
  240.         rep     stosd
  241.         pop     eax
  242.         push    eax edx
  243. ; convert number in eax to decimal UNICODE string
  244.         push    edi
  245.         push    -'0'
  246.         mov     cl, 10
  247. @@:
  248.         xor     edx, edx
  249.         div     ecx
  250.         push    edx
  251.         test    eax, eax
  252.         jnz     @b
  253. @@:
  254.         pop     eax
  255.         add     al, '0'
  256.         stosb
  257.         test    bl, 1           ; UNICODE name?
  258.         jz      .ansi2
  259.         mov     byte [edi], 0
  260.         inc     edi
  261. .ansi2:
  262.         test    al, al
  263.         jnz     @b
  264.         mov     byte [edi-1], 0
  265.         pop     edi
  266. ; UNICODE name length is 520 bytes, ANSI - 264
  267.         add     edi, 520
  268.         test    bl, 1
  269.         jnz     @f
  270.         sub     edi, 520-264
  271. @@:
  272.         pop     edx eax
  273.         jmp     .maindir_loop
  274. .maindir_done:
  275.         pop     eax
  276.         mov     ebx, [edx+4]
  277.         xor     eax, eax
  278.         dec     ebp
  279.         js      @f
  280.         mov     al, ERROR_END_OF_FILE
  281. @@:
  282.         mov     [image_of_eax], eax
  283.         mov     [image_of_ebx], ebx
  284.         ret
  285. ; directory /
  286. .rootdir:
  287.         cmp     dword [ebx], 1  ; read folder?
  288.         jz      .readroot
  289. .access_denied:
  290.         mov     dword [image_of_eax], 10      ; access denied
  291.         ret
  292.  
  293. .readroot:
  294. ; virtual root folder - special handler
  295.         mov     esi, virtual_root_query
  296.         mov     ebp, [ebx+12]
  297.         mov     edx, [ebx+16]
  298.     ;    add     edx, std_application_base_address
  299.         push    dword [ebx+4]   ; first block
  300.         mov     ebx, [ebx+8]    ; flags
  301.         xor     eax, eax
  302. ; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
  303.         mov     edi, edx
  304.         mov     ecx, 32/4
  305.         rep     stosd
  306.         mov     byte [edx], 1   ; version
  307. .readroot_loop:
  308.         cmp     dword [esi], eax
  309.         jz      .readroot_done
  310.         call    dword [esi]
  311.         add     esi, 4
  312.         test    eax, eax
  313.         jnz     @f
  314. .readroot_next:
  315.         or      ecx, -1
  316.         xchg    esi, edi
  317.         repnz   scasb
  318.         xchg    esi, edi
  319.         jmp     .readroot_loop
  320. @@:
  321.         xor     eax, eax
  322.         inc     dword [edx+8]
  323.         dec     dword [esp]
  324.         jns     .readroot_next
  325.         dec     ebp
  326.         js      .readroot_next
  327.         inc     dword [edx+4]
  328.         mov     dword [edi], 0x10       ; attributes: folder
  329.         mov     dword [edi+4], 1        ; name type: UNICODE
  330.         add     edi, 8
  331.         mov     ecx, 40/4-2
  332.         rep     stosd
  333.         push    edi
  334. @@:
  335.         lodsb
  336.         stosb
  337.         test    bl, 1
  338.         jz      .ansi
  339.         mov     byte [edi], 0
  340.         inc     edi
  341. .ansi:
  342.         test    eax, eax
  343.         jnz     @b
  344.         pop     edi
  345.         add     edi, 520
  346.         test    bl, 1
  347.         jnz     .readroot_loop
  348.         sub     edi, 520-264
  349.         jmp     .readroot_loop
  350. .readroot_done:
  351.         pop     eax
  352.         mov     ebx, [edx+4]
  353.         xor     eax, eax
  354.         dec     ebp
  355.         js      @f
  356.         mov     al, ERROR_END_OF_FILE
  357. @@:
  358.         mov     [image_of_eax], eax
  359.         mov     [image_of_ebx], ebx
  360.         ret
  361.  
  362. .found1:
  363.         pop     eax
  364.         cmp     byte [esi], 0
  365.         jz      .maindir
  366. ; read partition number
  367.         xor     ecx, ecx
  368.         xor     eax, eax
  369. @@:
  370.         lodsb
  371.         cmp     al, '/'
  372.         jz      .done1
  373.         test    al, al
  374.         jz      .done1
  375.         sub     al, '0'
  376.         cmp     al, 9
  377.         ja      .notfound
  378.         imul    ecx, 10
  379.         add     ecx, eax
  380.         jmp     @b
  381. .done1:
  382.         test    ecx, ecx
  383.         jz      .notfound
  384.         test    al, al
  385.         jnz     @f
  386.         dec     esi
  387. @@:
  388. ; now [edi] contains handler address, ecx - partition number,
  389. ; esi points to ASCIIZ string - rest of name
  390.         jmp     dword [edi]
  391.  
  392. ; handlers for devices
  393. ; in: ecx = 0 => query virtual directory /xxx
  394. ; in: ecx = partition number
  395. ;     esi -> relative (for device) name
  396. ;     ebx -> fileinfo
  397. ; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
  398.  
  399. fs_OnRamdisk:
  400.         cmp     ecx, 1
  401.         jnz     file_system_lfn.notfound
  402.         mov     eax, [ebx]
  403.         cmp     eax, fs_NumRamdiskServices
  404.         jae     .not_impl
  405.         mov     ecx, [ebx+12]
  406.         mov     edx, [ebx+16]
  407.    ;     add     edx, std_application_base_address
  408.         add     ebx, 4
  409.         call    dword [fs_RamdiskServices + eax*4]
  410.         mov     [image_of_eax], eax
  411.         mov     [image_of_ebx], ebx
  412.         ret
  413. .not_impl:
  414.         mov     dword [image_of_eax], 2       ; not implemented
  415.         ret
  416.  
  417. fs_NotImplemented:
  418.         mov     eax, 2
  419.         ret
  420.  
  421. fs_RamdiskServices:
  422.         dd      fs_RamdiskRead
  423.         dd      fs_RamdiskReadFolder
  424.         dd      fs_RamdiskRewrite
  425.         dd      fs_RamdiskWrite
  426.         dd      fs_RamdiskSetFileEnd
  427.         dd      fs_RamdiskGetFileInfo
  428.         dd      fs_RamdiskSetFileInfo
  429.         dd      0 ;fs_RamdiskExecute
  430.         dd      fs_RamdiskDelete
  431.         dd      fs_RamdiskCreateFolder
  432. fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
  433.  
  434. fs_OnFloppy:
  435.         cmp     ecx, 2
  436.         ja      file_system_lfn.notfound
  437.         mov     eax, [ebx]
  438.         cmp     eax, fs_NumFloppyServices
  439.         jae     fs_OnRamdisk.not_impl
  440.         call    reserve_flp
  441.         mov     [flp_number], cl
  442.         mov     ecx, [ebx+12]
  443.         mov     edx, [ebx+16]
  444.    ;     add     edx, std_application_base_address
  445.         add     ebx, 4
  446.         call    dword [fs_FloppyServices + eax*4]
  447.         and     [flp_status], 0
  448.         mov     [image_of_eax], eax
  449.         mov     [image_of_ebx], ebx
  450.         ret
  451.  
  452. fs_FloppyServices:
  453.         dd      fs_FloppyRead
  454.         dd      fs_FloppyReadFolder
  455.         dd      fs_FloppyRewrite
  456.         dd      fs_FloppyWrite
  457.         dd      fs_FloppySetFileEnd
  458.         dd      fs_FloppyGetFileInfo
  459.         dd      fs_FloppySetFileInfo
  460.         dd      0 ;fs_FloppyExecute
  461.         dd      fs_FloppyDelete
  462.         dd      fs_FloppyCreateFolder
  463. fs_NumFloppyServices = ($ - fs_FloppyServices)/4
  464.  
  465. fs_OnHd0:
  466.         call    reserve_hd1
  467.         mov     [hdbase], 0x1F0
  468.         mov     [hdid], 0
  469.         push    1
  470.         jmp     fs_OnHd
  471. fs_OnHd1:
  472.         call    reserve_hd1
  473.         mov     [hdbase], 0x1F0
  474.         mov     [hdid], 0x10
  475.         push    2
  476.         jmp     fs_OnHd
  477. fs_OnHd2:
  478.         call    reserve_hd1
  479.         mov     [hdbase], 0x170
  480.         mov     [hdid], 0
  481.         push    3
  482.         jmp     fs_OnHd
  483. fs_OnHd3:
  484.         call    reserve_hd1
  485.         mov     [hdbase], 0x170
  486.         mov     [hdid], 0x10
  487.         push    4
  488. fs_OnHd:
  489.         call    reserve_hd_channel
  490.         pop     eax
  491.         mov     [hdpos], eax
  492.         cmp     ecx, 0x100
  493.         jae     .nf
  494.         cmp     cl, [DRIVE_DATA+1+eax]
  495.         jbe     @f
  496. .nf:
  497.         call    free_hd_channel
  498.         and     [hd1_status], 0
  499.         mov     dword [image_of_eax], 5       ; not found
  500.         ret
  501. @@:
  502.         mov     [fat32part], ecx
  503.         push    ebx esi
  504.         call    choice_necessity_partition_1
  505.         pop     esi ebx
  506.         mov     ecx, [ebx+12]
  507.         mov     edx, [ebx+16]
  508.     ;    add     edx, std_application_base_address
  509.         mov     eax, [ebx]
  510.         cmp     eax, fs_NumHdServices
  511.         jae     .not_impl
  512.         add     ebx, 4
  513.         call    dword [fs_HdServices + eax*4]
  514.         call    free_hd_channel
  515.         and     [hd1_status], 0
  516.         mov     [image_of_eax], eax
  517.         mov     [image_of_ebx], ebx
  518.         ret
  519. .not_impl:
  520.         call    free_hd_channel
  521.         and     [hd1_status], 0
  522.         mov     dword [image_of_eax], 2       ; not implemented
  523.         ret
  524.  
  525. fs_HdServices:
  526.         dd      fs_HdRead
  527.         dd      fs_HdReadFolder
  528.         dd      fs_HdRewrite
  529.         dd      fs_HdWrite
  530.         dd      fs_HdSetFileEnd
  531.         dd      fs_HdGetFileInfo
  532.         dd      fs_HdSetFileInfo
  533.         dd      0 ;fs_HdExecute
  534.         dd      fs_HdDelete
  535.         dd      fs_HdCreateFolder
  536. fs_NumHdServices = ($ - fs_HdServices)/4
  537.  
  538. ;*******************************************************
  539. fs_OnCd0:
  540.         call    reserve_cd
  541.         mov  [ChannelNumber],1
  542.         mov  [DiskNumber],0
  543.         push    6
  544.         jmp     fs_OnCd
  545. fs_OnCd1:
  546.         call    reserve_cd
  547.         mov  [ChannelNumber],1
  548.         mov  [DiskNumber],1
  549.         push    4
  550.         jmp     fs_OnCd
  551. fs_OnCd2:
  552.         call    reserve_cd
  553.         mov  [ChannelNumber],2
  554.         mov  [DiskNumber],0
  555.         push    2
  556.         jmp     fs_OnCd
  557. fs_OnCd3:
  558.         call    reserve_cd
  559.         mov  [ChannelNumber],2
  560.         mov  [DiskNumber],1
  561.         push    0
  562. fs_OnCd:
  563.         call    reserve_cd_channel
  564.         pop     eax
  565.         mov     [hdpos], eax
  566.         cmp     ecx, 0x100
  567.         jae     .nf
  568.         push    ecx ebx
  569.         mov     cl,al
  570.         mov     bl,[DRIVE_DATA+1]
  571.         shr     bl,cl
  572.         test    bl,2
  573.         pop     ebx ecx
  574.  
  575.         jnz     @f
  576. .nf:
  577.         call    free_cd_channel
  578.         and    [cd_status], 0
  579.         mov     dword [image_of_eax], 5       ; not found
  580.         ret
  581. @@:
  582.         mov     ecx, [ebx+12]
  583.         mov     edx, [ebx+16]
  584.     ;    add     edx, std_application_base_address
  585.         mov     eax, [ebx]
  586.         cmp     eax,fs_NumCdServices
  587.         jae      .not_impl
  588.         add     ebx, 4
  589.         call    dword [fs_CdServices + eax*4]
  590.         call    free_cd_channel
  591.         and     [cd_status], 0
  592.         mov     [image_of_eax], eax
  593.         mov     [image_of_ebx], ebx
  594.         ret
  595. .not_impl:
  596.         call    free_cd_channel
  597.         and     [cd_status], 0
  598.         mov     dword [image_of_eax], 2       ; not implemented
  599.         ret
  600.  
  601. fs_CdServices:
  602.         dd      fs_CdRead
  603.         dd      fs_CdReadFolder
  604.         dd      fs_NotImplemented
  605.         dd      fs_NotImplemented
  606.         dd      fs_NotImplemented
  607.         dd      fs_CdGetFileInfo
  608.         dd      fs_NotImplemented
  609.         dd      fs_CdExecute
  610. fs_NumCdServices = ($ - fs_CdServices)/4
  611.  
  612. ;*******************************************************
  613.  
  614. fs_HasRamdisk:
  615.         mov     al, 1   ; we always have ramdisk
  616.         ret
  617.  
  618. fs_HasFloppy:
  619.         cmp     byte [DRIVE_DATA], 0
  620.         setnz   al
  621.         ret
  622.  
  623. fs_HasHd0:
  624.         mov     al, [DRIVE_DATA+1]
  625.         and     al, 11000000b
  626.         cmp     al, 01000000b
  627.         setz    al
  628.         ret
  629. fs_HasHd1:
  630.         mov     al, [DRIVE_DATA+1]
  631.         and     al, 00110000b
  632.         cmp     al, 00010000b
  633.         setz    al
  634.         ret
  635. fs_HasHd2:
  636.         mov     al, [DRIVE_DATA+1]
  637.         and     al, 00001100b
  638.         cmp     al, 00000100b
  639.         setz    al
  640.         ret
  641. fs_HasHd3:
  642.         mov     al, [DRIVE_DATA+1]
  643.         and     al, 00000011b
  644.         cmp     al, 00000001b
  645.         setz    al
  646.         ret
  647.  
  648. ;*******************************************************
  649. fs_HasCd0:
  650.         mov     al, [DRIVE_DATA+1]
  651.         and     al, 11000000b
  652.         cmp     al, 10000000b
  653.         setz    al
  654.         ret
  655. fs_HasCd1:
  656.         mov     al, [DRIVE_DATA+1]
  657.         and     al, 00110000b
  658.         cmp     al, 00100000b
  659.         setz    al
  660.         ret
  661. fs_HasCd2:
  662.         mov     al, [DRIVE_DATA+1]
  663.         and     al, 00001100b
  664.         cmp     al, 00001000b
  665.         setz    al
  666.         ret
  667. fs_HasCd3:
  668.         mov     al, [DRIVE_DATA+1]
  669.         and     al, 00000011b
  670.         cmp     al, 00000010b
  671.         setz    al
  672.         ret
  673. ;*******************************************************
  674.  
  675. ; fs_NextXXX functions:
  676. ; in: eax = partition number, from which start to scan
  677. ; out: CF=1 => no more partitions
  678. ;      CF=0 => eax=next partition number
  679.  
  680. fs_NextRamdisk:
  681. ; we always have /rd/1
  682.         test    eax, eax
  683.         stc
  684.         jnz     @f
  685.         mov     al, 1
  686.         clc
  687. @@:
  688.         ret
  689.  
  690. fs_NextFloppy:
  691. ; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
  692.         test    byte [DRIVE_DATA], 0xF0
  693.         jz      .no1
  694.         test    eax, eax
  695.         jnz     .no1
  696.         inc     eax
  697.         ret     ; CF cleared
  698. .no1:
  699.         test    byte [DRIVE_DATA], 0x0F
  700.         jz      .no2
  701.         cmp     al, 2
  702.         jae     .no2
  703.         mov     al, 2
  704.         clc
  705.         ret
  706. .no2:
  707.         stc
  708.         ret
  709.  
  710. ; on hdx, we have partitions from 1 to [0x40002+x]
  711. fs_NextHd0:
  712.         push    0
  713.         jmp     fs_NextHd
  714. fs_NextHd1:
  715.         push    1
  716.         jmp     fs_NextHd
  717. fs_NextHd2:
  718.         push    2
  719.         jmp     fs_NextHd
  720. fs_NextHd3:
  721.         push    3
  722. fs_NextHd:
  723.         pop     ecx
  724.         movzx   ecx, byte [DRIVE_DATA+2+ecx]
  725.         cmp     eax, ecx
  726.         jae     fs_NextFloppy.no2
  727.         inc     eax
  728.         clc
  729.         ret
  730.  
  731. ;*******************************************************
  732. fs_NextCd:
  733. ; we always have /cdX/1
  734.         test    eax, eax
  735.         stc
  736.         jnz     @f
  737.         mov     al, 1
  738.         clc
  739. @@:
  740.         ret
  741. ;*******************************************************
  742.  
  743.