Subversion Repositories Kolibri OS

Rev

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

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