stc
     ret
 
+;******************************************************************************
+; @function         _strstart
+;******************************************************************************
+_strstart:
+
+    push    bp
+    mov     bp,     sp
+    
+    push    bx
+    push    si
+    push    di
+    
+    mov     si,     word ptr [bp + 4]
+    mov     di,     word ptr [bp + 6]
+    
+    xor     ah,     ah
+    xor     bh,     bh
+
+_strstart.loop:
+
+    mov     al,     cs:[di]
+    
+    and     al,     al
+    jz      _strstart.done
+    
+    push    ax
+    
+    call    _tolower
+    add     sp,     2
+    
+    mov     bl,     al
+    
+    mov     al,     [si]
+    push    ax
+    
+    call    _tolower
+    add     sp,     2
+    
+    cmp     al,     bl
+    jne     _strstart.error
+    
+    inc     si
+    inc     di
+    
+    jmp     _strstart.loop
+
+_strstart.error:
+
+    xor     ax,     ax
+    
+    pop     di
+    pop     si
+    pop     bx
+    
+    pop     bp
+    stc
+    
+    ret
+
+_strstart.done:
+
+    mov     ax,     si
+    
+    pop     di
+    pop     si
+    pop     bx
+    
+    pop     bp
+    clc
+    
+    ret
+
 ;******************************************************************************
 ; @function         _skip_whitespace
 ;******************************************************************************
     call    _error
     db      "duplicate entry name found",       HEX (0D),   HEX (0A),   HEX (00)
 
+;******************************************************************************
+; @function         _pc_root
+;******************************************************************************
+_pc_root:
+
+    push    ax
+    push    bx
+    push    cx
+    push    dx
+    push    di
+    
+    mov     bx,     si
+    
+    call    _is_name_beginner
+    jc      _pc_root.error
+
+_pc_root.loop:
+
+    call    _is_name_part
+    jc      _pc_root.check
+    
+    lodsb
+    jmp     _pc_root.loop
+
+_pc_root.check:
+
+    mov     ax,     si
+    sub     ax,     bx
+    
+    cmp     ax,     2
+    jb      _pc_root.error
+    
+    mov     ax,     offset _pc_root.fd_check
+    push    ax
+    
+    push    bx
+    
+    call    _strstart
+    add     sp,     4
+    
+    and     ax,     ax
+    jz      _pc_root.check2
+    
+    xor     bx,     bx
+    jmp     _pc_root.got_disk
+
+_pc_root.check2:
+
+    mov     ax,     offset _pc_root.hd_check
+    push    ax
+    
+    push    bx
+    
+    call    _strstart
+    add     sp,     4
+    
+    and     ax,     ax
+    jz      _pc_root.error
+    
+    mov     bx,     2
+
+_pc_root.got_disk:
+
+    mov     si,     ax
+    
+    xor     ax,     ax
+    xor     dx,     dx
+    
+    mov     cx,     10
+    xor     di,     di
+
+_pc_root.convert:
+
+    call    _is_digit
+    jc      _pc_root.check3
+    
+    lodsb
+    push    ax
+    
+    mov     ax,     di
+    mul     cx
+    mov     di,     ax
+    
+    pop     ax
+    
+    test    dx,     dx
+    jnz     _pc_root.error
+    
+    sub     al,     '0'
+    add     di,     ax
+    
+    jmp     _pc_root.convert
+
+_pc_root.check3:
+
+    cmp     word ptr cs:[_curr_entry],      0
+    jne     _pc_root.set
+    
+    push    ax
+    push    bx
+    push    dx
+    push    ds
+    
+    mov     bx,     cs
+    mov     ds,     bx
+    
+    mov     bx,     cs:[_filename]
+    call    _writestr
+    
+    mov     al,     ':'
+    call    _writechr
+    
+    mov     ax,     cs:[_line_number]
+    xor     dx,     dx
+    
+    call    _writedec
+    
+    mov     al,     ':'
+    call    _writechr
+    
+    mov     al,     ' '
+    call    _writechr
+    
+    mov     bx,     offset _error_root_without_label
+    call    _writestr
+    
+    pop     ds
+    pop     dx
+    pop     bx
+    pop     ax
+    jmp     _pc_root.done
+
+_pc_root.set:
+
+    and     di,     di
+    jz      _pc_root.error
+    
+    cmp     bx,     2
+    je      _pc_root.ok
+    
+    cmp     di,     2
+    ja      _pc_root.error
+
+_pc_root.ok:
+
+    add     bx,     di
+    
+    push    di
+    push    es
+    
+    mov     di,     cs:[_curr_entry]
+    mov     es,     di
+    xor     di,     di
+    
+    mov     es:[di + 6],    bx
+    pop     es
+    pop     di
+
+_pc_root.done:
+
+    pop     di
+    pop     dx
+    pop     cx
+    pop     bx
+    pop     ax
+    
+    ret
+
+_pc_root.error:
+
+    mov     bx,     cs
+    mov     ds,     bx
+    
+    mov     bx,     cs:[_filename]
+    call    _writestr
+    
+    mov     al,     ':'
+    call    _writechr
+    
+    mov     ax,     cs:[_line_number]
+    xor     dx,     dx
+    
+    call    _writedec
+    
+    mov     al,     ':'
+    call    _writechr
+    
+    mov     al,     ' '
+    call    _writechr
+    
+    call    _error
+    db      "invalid root provided",        HEX (0D),   HEX (0A),   HEX (00)
+
+_pc_root.fd_check:              db      "fd",       HEX (00)
+_pc_root.hd_check:              db      "hd",       HEX (00)
+
 ;******************************************************************************
 ; @function         _pc_timeout
 ;******************************************************************************
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 _error_kernel_without_label:    db      "kernel specified outside label",                   HEX (0D),   HEX (0A),   HEX (00)
 _error_title_without_label:     db      "title specified outside label",                    HEX (0D),   HEX (0A),   HEX (00)
+_error_root_without_label:      db      "root specified outside label",                    HEX (0D),   HEX (0A),   HEX (00)
 
 _error_noparam:                 db      "missing parameter",                                HEX (0D),   HEX (0A),   HEX (00)
 _error_badcfg:                  db      "unknown keyword",                                  HEX (0D),   HEX (0A),   HEX (00)
     dw      0
     dw      _pc_label
     
+    dw      hash_root
+    dw      0
+    dw      _pc_root
+    
     dw      hash_timeout
     dw      0
     dw      _pc_timeout
 
 
 .L7:
 
+    inc     byte ptr cs:[_last_drive]
+    
     mov     ax,     es
     jmp     .L19
     
     
     add     sp,     4
     
-    and     ax,     ax
-    jz      .L15
-    
     mov     es,     ax
     xor     bx,     bx
     
 .L17:
 
     add     sp,     4
+    
+    and     ax,     ax
+    jz      .L15
 
 .L16:
 
     
     call    _vec_push
     add     sp,     4
-    
-    jmp     .L15
 
 .L15:
 
 global      _drive_no
 _drive_no:                      db      HEX (00)
 
+global      _last_drive
+_last_drive:                    db      HEX (00)
+
 global      _edd_available
 _edd_available:                 dw      HEX (0000)
 
 
     mov     es,     ax
     xor     bx,     bx
     
+    mov     dx,     es:[bx + 6]
+    
+    and     dx,     dx
+    jz      .L18
+    
+    dec     dx
+    
+    mov     ah,     HEX (0E)
+    int     HEX (21)
+    
+    mov     ah,     HEX (19)
+    int     HEX (21)
+    
+    cmp     al,     dl
+    je      .L18
+    
+    call    _error
+    db      "panic: the root for the selected kernel is not ready",     HEX (0D),   HEX (0A),   HEX (00)
+
+.L18:
+
     mov     ax,     es:[bx + 4]
     mov     ds,     ax
     xor     di,     di
     mov     es,     bx
     push    es
     
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Check if we're FAT32.
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    mov     di,     cs:[_sectors_per_fat32]
+    or      di,     cs:[_sectors_per_fat32 + 2]
+    
+    and     di,     di
+    jnz     .L16
+    
+    mov     byte ptr cs:[_fat_jump + 1],    HEX (3C)
+    jmp     .L17
+
+.L16:
+
+    mov     byte ptr cs:[_fat_jump + 1],    HEX (58)
+
+.L17:
+
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;; Zero out the di register.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;; If we're not FAT32 then jump passed the next couple of copies.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    cmp     byte ptr [_fat_jump + 1],   HEX (58)
+    cmp     byte ptr cs:[_fat_jump + 1],        HEX (58)
     jne     .L13
     
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
     mov     ax,     cs:[_selected_disk]
     mov     word ptr [bp - 2],      ax
 
-_get_disk_info.check:
+_get_disk_info.got_disk:
 
-    push    si
-    
-    call    _strlen
-    add     sp,     2
-    
-    cmp     ax,     2
-    jb      _get_disk_info.got_disk
-    
-    cmp     byte ptr [si + 1],      ':'
-    jne     _get_disk_info.got_disk
-    
-    xor     ah,     ah
-    mov     al,     [si]
-    
-    push    ax
-    
-    call    _isalpha
-    mov     cx,     ax
-    
-    pop     ax
-    
-    and     cx,     cx
-    jz      _get_disk_info.got_disk
-    
-    add     si,     2
-    push    ax
-    
-    call    _toupper
-    add     sp,     2
-    
-    sub     al,     HEX (41)
-    
-    cmp     ax,     cs:[_selected_disk]
-    je      _get_disk_info.got_disk
-    
-    mov     word ptr [bp - 2],      ax
-    inc     ax
-    
-    cmp     cs:[_vec_parts + 4],    ax
-    jb      _get_disk_info.error
-    
-    dec     ax
+    mov     ax,     word ptr [bp - 2]
     
     cmp     ax,     2
-    jae     _get_disk_info.got_disk
+    jae     _get_disk_info.ok
     
     call    _probe_disk
     jc      _get_disk_info.error
 
-_get_disk_info.got_disk:
+_get_disk_info.ok:
 
-    mov     ax,     word ptr [bp - 2]
     xor     dx,     dx
     
     mov     cx,     2
 
 _int21_dispatch.list:
 
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Select Disk.
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    db      HEX (0E)
+    dw      _int21_0E
+    
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Get Current Default Drive.
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    db      HEX (19)
+    dw      _int21_19
+    
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;; Open File Using Handle.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     iret
 
 
+;******************************************************************************
+; @function         _int21_OE
+; @brief            Select Disk
+;******************************************************************************
+_int21_0E:
+
+    push    ax
+    push    bx
+    push    cx
+    push    dx
+    push    si
+    push    di
+    push    es
+    push    ds
+    
+    mov     cx,     cs:[_selected_disk] 
+
+_int21_0E.check:
+
+    xor     dh,     dh
+    
+    cmp     dx,     cs:[_selected_disk]
+    je      _int21_0E.get_info
+    
+    inc     dx
+    
+    cmp     cs:[_vec_parts + 4],    dx
+    jb      _int21_0E.done
+    
+    mov     cs:[_selected_disk],    dx
+    dec     word ptr cs:[_selected_disk]
+
+_int21_0E.get_info:
+
+    call    _get_disk_info
+    
+    jnc     _int21_0E.done
+    mov     cs:[_selected_disk],    cx
+
+_int21_0E.done:
+
+    pop     ds
+    pop     es
+    pop     di
+    pop     si
+    pop     dx
+    pop     cx
+    pop     bx
+    pop     ax
+    
+    mov     al,     cs:[_last_drive]
+    
+    cmp     al,     5
+    jae     _int21_0E.ret
+    
+    mov     al,     5
+
+_int21_0E.ret:
+
+    iret
+
+;******************************************************************************
+; @function         _int21_19
+; @brief            Get Current Default Drive
+;
+; @out              AL -> Current default drive.
+;******************************************************************************
+_int21_19:
+
+    mov     al,     cs:[_selected_disk]
+    iret
+
 ;******************************************************************************
 ; @function         _int21_3D
 ; @brief            Open File Using Handle
 
 default     chimaera
-timeout     10
+#timeout     10
+timeout     0
 
 label chimaera
+
     title   Chimaera OS
+
+#    root    hd2                         # Second parition that's found for hard disks.
     kernel  /kernel.sys
 
     mov     dl,     [_drive_no]
     
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    ;; Zero out the bx register.
+    ;; Move the hidden sectors into BX:CX.
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    mov     bx,     [_hidden_sectors]
+    mov     cx,     [_hidden_sectors + 2]
+    
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Clear the carry flag.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    xor     bx,     bx
     clc
     
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     mov     dl,     [_drive_no]
     
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    ;; Zero out the bx register.
+    ;; Move the hidden sectors into BX:CX.
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    mov     bx,     [_hidden_sectors]
+    mov     cx,     [_hidden_sectors + 2]
+    
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Clear the carry flag.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    xor     bx,     bx
     clc
     
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
     cmp     word ptr [bp + 4],      cx
     jne     .L23
     
-    cmp     byte ptr es:[si],       128
+    mov     bx,     es:[si + 10]
+    
+    cmp     bx,     cs:[_part_start + 2]
+    jne     .L23
+    
+    mov     bx,     es:[si + 8]
+    
+    cmp     bx,     cs:[_part_start]
     jne     .L23
     
     mov     word ptr [bp - 2],      1
     
     add     sp,     4
     
-    and     ax,     ax
-    jz      .L15
-    
     mov     es,     ax
     xor     bx,     bx
     
 .L20:
 
     add     sp,     4
+    
+    and     ax,     ax
+    jz      .L15
 
 .L16:
 
 
     dw      HEX (0000)
     dw      HEX (0000)
+
+global      _part_start
+_part_start:
+
+    dw      HEX (0000)
+    dw      HEX (0000)
 
     cli
     cld
     
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Save the hidden sectors.
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    mov     cs:[_part_start],       bx
+    mov     cs:[_part_start + 2],   cx
+    
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;; Save the value that's in the extra segment.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;