; *****************************************************************************
;
; DRV_INIT3.ASM  [ TRDOS Kernel Drive Initialization Procedures ]
; 14/06/2009  SPECIAL Version for DISKINFO utility
; DRV_INIT.ASM
; Copyright (C) 2005 Erdogan TAN  [ 29/01/2005 ]
;
; TRDOS.ASM (include drv_init.asm)
;
; *****************************************************************************

; TRFS

bs_FS_JmpBoot equ 0 ; jmp short bsBootCode
                ; db 0EBh, db 3Fh, db 90h
bs_FS_Identifier equ 3  ; db 'FS', db 0
bs_FS_BytesPerSec equ 6 ; dw 512
bs_FS_MediaAttrib equ 8 ; db 3
bs_FS_PartitionId equ 9 ; db 0A1h
bs_FS_VersionMaj equ 10 ; db 01h
bs_FS_VersionMin equ 11 ; db 0
bs_FS_BeginSector equ 12   ; dd 0 
bs_FS_VolumeSize equ 16 ; dd 2880
bs_FS_StartupFD equ 20 ; dd 0
bs_FS_MATLocation equ 24 ; dd 1
bs_FS_RootDirD equ 28 ; dd 8
bs_FS_SystemConfFD equ 32 ; dd 0
bs_FS_SwapFD equ 36 ; dd 0
bs_FS_UnDelDirD equ 40 ; dd 0
bs_FS_DriveNumber equ 44 ; db 0
bs_FS_LBA_Ready equ 45 ; db 0
bs_FS_MagicWord equ 46 
bs_FS_SecPerTrack equ 46 ; db 0A1h
bs_FS_Heads equ 47 ; db 01h 
bs_FS_OperationSys equ 48 ; db "TR-SINGLIX v1.0b"
bs_FS_Terminator equ 64 ; db 0
bs_FS_BootCode equ 65 

FS_MAT_DATLocation equ 12
FS_MAT_DATScount equ 16
FS_MAT_FreeSectors equ 20
FS_MAT_FirstFreeSector equ 24
FS_RDT_VolumeSerialNo equ 28
FS_RDT_VolumeName equ 64

; FAT12 + FAT16 + FAT32
BS_JmpBoot equ 0
BS_OEMName equ 3
BPB_BytsPerSec equ 11
BPB_SecPerClust equ 13
BPB_RsvdSecCnt equ 14
BPB_NumFATs equ 16
BPB_RootEntCnt equ 17
BPB_TotalSec16 equ 19
BPB_Media equ 21
BPB_FATSz16 equ 22
BPB_SecPerTrk equ 24
BPB_NumHeads equ 26
BPB_HiddSec equ 28
BPB_TotalSec32 equ 32

; FAT12 and FAT16 only
BS_DrvNum equ 36
BS_Reserved1 equ 37
BS_BootSig equ 38
BS_VolID equ 39
BS_VolLab equ 43
BS_FilSysType equ 54 ; 8 bytes
BS_BootCode equ 62

; FAT32 only
BPB_FATSz32 equ 36 ; FAT32, 4 bytes
BPB_ExtFlags equ 40 ; FAT32, 2 bytes
BPB_FSVer equ 42 ; FAT32, 2 bytes
BPB_RootClus equ 44 ; FAT32, 4 bytes
BPB_FSInfo equ 48 ; FAT 32, 2 bytes 
BPB_BkBootSec equ 50 ; FAT32, 2 bytes
BPB_Reserved equ 52 ; FAT32, 12 bytes
BS_FAT32_DrvNum equ 64 ; FAT32, 1 byte
BS_FAT32_Reserved1 equ 65 ; FAT32, 1 byte
BS_FAT32_BootSig equ 66 ; FAT32, 1 byte
BS_FAT32_VolID equ 67 ; FAT32, 4 bytes
BS_FAT32_VolLab equ 71 ; FAT32, 11 bytes
BS_FAT32_FilSysType equ 82 ; FAT32, 8 bytes
BS_FAT32_BootCode equ 90

BS_Validation equ 510

proc_drv_init   proc    near

                xor dl,dl
                mov si, offset DiskParams
dparam_read:
                call proc_dparam
                mov dl, byte ptr [SI][DPDisks]
                add si, 40h
                cmp dl, 2
                jne short pass_floppy1
                dec dl
                call proc_dparam
pass_floppy1:
                mov dl, 80h
                add si, 40h
                call proc_dparam
                jnc short pass_hd_15h_error
                mov word ptr [si][DPNumOfSecs], 0
                mov word ptr [si][DPNumOfSecs]+2,0
pass_hd_15h_error:
                mov ah, byte ptr [SI][DPDisks]
                mov byte ptr [HDCounter], ah
next_hard_disk:
                dec byte ptr [HDCounter]
                cmp byte ptr [HDCounter], 0
                jna short load_hd_partition_tables
                inc dl
                add si, 40h
                call proc_dparam
                jnc short next_hard_disk
                mov word ptr [si][DPNumOfSecs], 0
                mov word ptr [si][DPNumOfSecs]+2,0
                jmp short next_hard_disk
load_hd_partition_tables:
                mov si, offset Disk_hd0
                mov di, offset PTable_hd0
                push ds
                pop es
                mov dl, 80h
                mov cx, 4
load_next_hd_partition_table:
                push cx
                push dx
                push si
                push di
                cmp byte ptr [SI]+1, 03h
                jne short pass_pt_this_hard_disk
                call proc_load_masterboot
                jc short pass_pt_this_hard_disk
                pop di
                push di
                mov si, offset PartitionTable
                mov cx, 32
                rep movsw
pass_pt_this_hard_disk:
                pop di
                pop si
                pop dx
                pop cx
                inc dl
                add si, 40h
                add di, 40h
                loop load_next_hd_partition_table
load_extended_dos_partitions:
                mov si, Offset PTable_hd0
                mov di, Offset PTable_ep0
                mov byte ptr [HDCounter], 80h
next_hd_extd_partition:
                push si
                mov cx, 4
hd_check_fs_id_05h:
                mov al, byte ptr [SI][ptFileSystemName]
                cmp al, 05h ; Is it an extended dos partition ?
                je short pass_hd_check_05h
                cmp al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
                je short pass_hd_check_0Fh 
continue_to_check_ep:
                add si, 10h
                loop hd_check_fs_id_05h
continue_check_ep_next_disk:
                pop si
                add si, 40h
                add di, 40h
                cmp byte ptr [HDCounter], 83h
                jnb logical_drv_init
                inc byte ptr [HDCounter]
                jmp short next_hd_extd_partition
pass_hd_check_05h:
                push cx
                mov ax, word ptr [SI][ptStartSector]
                mov dx, word ptr [SI][ptStartSector]+2
                xor bh,bh
                mov bl, byte ptr [HDCounter]
                push bx
                sub bl, 80h
                shl bl, 1
                shl bl, 1
                mov word ptr [Val_StartSector][BX],ax
                mov word ptr [Val_StartSector][BX]+2,dx
                pop dx
                mov dh, byte ptr [SI][ptBeginHead]
                mov cx, word ptr [SI][ptBeginSector]
                mov ax, 0201h    ; Read 1 sector
                mov bx, offset MasterBootBuff
                push ds
                pop es
                int 13h
                pop cx
                jc short continue_to_check_ep
                push si
                push di
                push cx
                mov si, offset PartitionTable
                mov cx, 32
                rep movsw
                pop cx
                pop di
                pop si
                jmp short continue_check_ep_next_disk
pop_di_check_next_ep:
                pop di
                jmp continue_to_check_ep
pass_hd_check_0Fh:
                mov ax, word ptr [SI][ptStartSector]
                mov dx, word ptr [SI][ptStartSector]+2
                xor bh,bh
                mov bl, byte ptr [HDCounter]
                sub bl, 80h
                push bx
                shl bl, 1
                shl bl, 1
                mov word ptr [Val_StartSector][BX],ax
                mov word ptr [Val_StartSector][BX]+2,dx
                pop ax
                push di
                mov ah, 40h
                mul ah
                mov di, offset Disk_hd0
                add di, ax
ep_mov_dap_parameters:
                push ds
                pop es
                cmp byte ptr [DI][DAP_PacketSize], 10h
                jne short pop_di_check_next_ep
                mov word ptr [DI][DAP_Destination], offset MasterBootBuff
                push ds
                pop word ptr [DI][DAP_Destination]+2
                mov byte ptr [DI][DAP_NumOfBlocks],1
                push si
                push di
                add si, ptStartSector
                add di, DAP_LBA_Address
                movsw
                movsw
                pop si  
                add si, DAP_PacketSize ; DS:SI= DAP Location
                mov ah, 42h  ; Extended Disk Read - LBA Read
                mov dl, byte ptr [HDCounter]
                int 13h
                pop si
                pop di
                jc continue_to_check_ep
                push di
                push si
                push cx
                mov si, offset PartitionTable
                mov cx, 32
                rep movsw
                pop cx
                pop si
                pop di
                jmp continue_check_ep_next_disk
logical_drv_init:
                mov byte ptr [Hard_Disk], 80h
                mov cx, 4
                xor al, al
                mov si, offset PTable_Buffer
                mov di, offset Logical_DOSDisks + 200h
                mov byte ptr [Last_DOS_DiskNo], 1
ldrv_init_next_hdp:
                push si
                push cx
                push ax
                push di
                cmp byte ptr [SI][ptFileSystemName], 06h
                jne short pass_this_is_FAT16_CHS_disk
                mov byte ptr [DI][LD_DiskType], 2
                mov dl, byte ptr [Hard_Disk]
                mov byte ptr [DI][LD_PhyDrvNo], dl
                mov byte ptr [DI][LD_FATType], 2
                mov byte ptr [DI][LD_FSType], 06h
                mov bl, dl
                sub bl, 80h
                xor bh, bh
                mov ah, byte ptr [HD_LBAYes][BX]
                mov byte ptr [DI][LD_LBAYes], ah
                mov byte ptr [DI][LD_PartitionEntry],al
                mov ah, dl
                sub ah, 7Eh
                mov byte ptr [DI][LD_DParamEntry], ah
                mov dh, byte ptr [SI][ptBeginHead]
                mov cx, word ptr [SI][ptBeginSector]
                mov ax, 0201h    ; Read 1 sector
                mov bx, offset DOSBootSectorBuff
                int 13h
                jc pass_this_is_FAT32_LBA_disk
                jmp hdp_boot_validation
pass_this_is_FAT16_CHS_disk:
                cmp byte ptr [SI][ptFileSystemName], 0Eh
                jne pass_this_is_FAT16_LBA_disk
                mov byte ptr [DI][LD_DiskType], 2
                mov dl, byte ptr [Hard_Disk]
                mov byte ptr [DI][LD_PhyDrvNo], dl
                mov byte ptr [DI][LD_FATType], 2
                mov byte ptr [DI][LD_FSType], 0Eh
                mov byte ptr [DI][LD_LBAYes], 1
                mov byte ptr [DI][LD_PartitionEntry],al
                mov ah, dl
                sub ah, 7Eh
                mov byte ptr [DI][LD_DParamEntry], ah
                mov al, 40h
                mul ah
                add ax, offset Disk_fd0
                mov di, ax
                cmp byte ptr [DI][DAP_PacketSize], 10h
                jne pass_this_is_FAT32_LBA_disk
                mov word ptr [DI][DAP_Destination], offset DOSBootSectorBuff
                push ds
                pop word ptr [DI][DAP_Destination]+2
                mov byte ptr [DI][DAP_NumOfBlocks],1
                push di
                add si, ptStartSector
                add di, DAP_LBA_Address
                movsw
                movsw
                pop si  
                add si, DAP_PacketSize ; DS:SI= DAP Location
                mov ah, 42h  ; Extended Disk Read - LBA Read
                mov dl, byte ptr [Hard_Disk]
                int 13h
                jc pass_this_is_FAT32_LBA_disk
hdp_boot_validation:
                mov si, offset DOSBootSectorBuff
                cmp word ptr [SI][BS_Validation], 0AA55h
                jne pass_this_is_FAT32_LBA_disk
                ; Singlix FS Extensions to TR-DOS 7/6/2009 
                cmp word ptr [SI][bs_FS_Identifier], 'SF'
                jne short pass_singlix_fd_hd_validation_check
                ; 'A1h' check is not necessary if 'FS' check is passed as OK/Yes.
                cmp byte ptr [SI][bs_FS_PartitionID], 0A1h
 		jne short pass_singlix_fd_hd_validation_check

                pop di
                mov al, byte ptr [SI][bs_FS_LBA_Ready]
                mov byte ptr [DI][LD_FS_LBAYes], al
                mov ax, word ptr [SI][bs_FS_BytesPerSec]
                mov word ptr [DI][LD_FS_BytesPerSec], ax
                mov ax, word ptr [SI][bs_FS_MediaAttrib]
                mov word ptr [DI][LD_FS_MediaAttrib], ax
		mov ax, word ptr [SI][bs_FS_SecPerTrack]
                mov word ptr [DI][LD_FS_SecPerTrack], ax
                mov ax, word ptr [SI][bs_FS_UnDelDirD]
                mov dx, word ptr [SI][bs_FS_UnDelDirD]+2
                mov word ptr [DI][LD_FS_UnDelDirD], ax
                mov word ptr [DI][LD_FS_UnDelDirD]+2, dx
                mov ax, word ptr [SI][bs_FS_MATLocation]
                mov dx, word ptr [SI][bs_FS_MATLocation]+2
                mov word ptr [DI][LD_FS_MATLocation], ax
                mov word ptr [DI][LD_FS_MATLocation]+2, dx
                mov ax, word ptr [SI][bs_FS_RootDirD]
 		mov dx, word ptr [SI][bs_FS_RootDirD]+2
                mov word ptr [DI][LD_FS_RootDirD], ax
                mov word ptr [DI][LD_FS_RootDirD]+2, dx
 		mov ax, word ptr [SI][bs_FS_BeginSector]
 		mov dx, word ptr [SI][bs_FS_BeginSector]+2
                mov word ptr [DI][LD_FS_BeginSector], ax
                mov word ptr [DI][LD_FS_BeginSector]+2, dx  
                mov ax, word ptr [SI][bs_FS_VolumeSize]
 		mov dx, word ptr [SI][bs_FS_VolumeSize]+2
                mov word ptr [DI][LD_FS_VolumeSize], ax
                mov word ptr [DI][LD_FS_VolumeSize]+2, dx
                mov si, di
                add di, 100h
                push di

 		inc byte ptr [Last_DOS_DiskNo]
                mov al, 'A'
                add al, byte ptr [Last_DOS_DiskNo]
                mov byte ptr [SI][LD_FS_Name], al
     
               ;LD_MediaChanged= 1 is "New Boot, MAT and RDT is not read"
               ;MAT and RDT depended parameters must be loaded next time
                mov byte ptr [SI][LD_FS_MediaChanged],1

                jmp pass_this_is_Singlix_FS_disk

              
pass_singlix_fd_hd_validation_check:
                cmp byte ptr [SI][BPB_Media], 0F8h
                jne pass_this_is_FAT32_LBA_disk
                cmp word ptr [SI][BPB_FATSz16], 0
                ja short pass_FAT32_BPB
                cmp byte ptr [SI][BS_FAT32_BootSig], 29h
                jne pass_this_is_FAT32_LBA_disk
                mov cx, 45
                jmp short loc_move_hd_BPB
pass_FAT32_BPB:
                cmp byte ptr [SI][BS_BootSig], 29h
                jne pass_this_is_FAT32_LBA_disk
                mov cx, 32
loc_move_hd_BPB:
                pop di
                push di
                push di
                add di, LD_BPB
                rep movsw 
                pop si
                pop di
                add di, 100h
                push di
                inc byte ptr [Last_DOS_DiskNo]
                mov al, 'A'
                add al, byte ptr [Last_DOS_DiskNo]
                mov byte ptr [SI][LD_Name], al

                cmp byte ptr [Now_EP_Drives], 0
                jna short ld_StartSector_set1
                cmp byte ptr [SI][LD_FsType], 0Bh
                jne short ld_StartSector_set1
                mov ax, word ptr [SI][LD_StartSector]
                mov dx, word ptr [SI][LD_StartSector]+2
                jmp short ld_StartSector_set2
ld_StartSector_set1:
                mov AX,Word Ptr [SI][LD_BPB][Hidden1]
                mov DX,Word Ptr [SI][LD_BPB][Hidden2]
                mov word ptr [SI][LD_StartSector],AX
                mov word ptr [SI][LD_StartSector]+2,DX
ld_StartSector_set2:
                add AX,Word Ptr [SI][LD_BPB][ResSectors]
                adc DX,0

                mov Word Ptr [SI][LD_FATBegin], AX
                mov Word Ptr [SI][LD_FATBegin]+2, DX
                cmp byte ptr [SI][LD_FATType], 3
                jne short pass_FAT32_RootDirLoc
                mov ax, Word Ptr [SI][LD_BPB][FAT32_FAT_Size]
                mov dx, Word Ptr [SI][LD_BPB][FAT32_FAT_Size]+2
                xor bh,bh
                mov bl,Byte Ptr [SI][LD_BPB][FATs]
                call proc_mul32
                add ax, Word Ptr [SI][LD_FATBegin]
                adc dx, Word Ptr [SI][LD_FATBegin]+2
                mov Word Ptr [SI][LD_DATABegin], AX
                mov Word Ptr [SI][LD_DATABegin]+2, DX
                mov Word Ptr [SI][LD_ROOTBegin], AX
                mov Word Ptr [SI][LD_ROOTBegin]+2, DX
                jmp short pass_FAT_FS_Locations
pass_FAT32_RootDirLoc:
                mov AL,Byte Ptr [SI][LD_BPB][FATs]
                cbw                             
                mul Word Ptr [SI][LD_BPB][FATSecs]
                add AX,Word Ptr [SI][LD_FATBegin]
                adc DX,Word Ptr [SI][LD_FATBegin]+2
                mov Word Ptr [SI][LD_ROOTBegin], AX
                mov Word Ptr [SI][LD_ROOTBegin]+2, DX
                mov Word Ptr [SI][LD_DATABegin], AX 
                mov Word Ptr [SI][LD_DATABegin]+2, DX
                mov AX,20h       ; Size of a directory entry
                mul Word Ptr [SI][LD_BPB][RootDirEnts]
                add AX,511
              ; adc dx, 0
                mov cx, 512
                div cx
                add Word Ptr [SI][LD_DATABegin],AX 
                adc Word Ptr [SI][LD_DATABegin]+2,0
pass_FAT_FS_Locations:
                mov ax,Word Ptr [SI][LD_BPB][HugeSec1]
                mov Word Ptr [SI][LD_TotalSectors], AX
                mov dx,Word Ptr [SI][LD_BPB][HugeSec2]
                mov Word Ptr [SI][LD_TotalSectors]+2, dx
                add ax,Word Ptr [SI][LD_StartSector]
                adc dx,Word Ptr [SI][LD_StartSector]+2
                sub ax,Word Ptr [SI][LD_DATABegin]
                sbb dx,Word Ptr [SI][LD_DATABegin]+2
                xor ch,ch
                mov cl,Byte Ptr [SI][LD_BPB][SecPerClust]
                call Rx_Dos_Div32 
                mov word ptr [SI][LD_Clusters], AX
                mov word ptr [SI][LD_Clusters]+2, DX
                    ; Maximum Valid Cluster Number= DX:AX +1
                    ; with 2 reserved clusters= DX:AX +2
               ;mov word ptr [SI][LD_FreeSectors],0
               ;mov word ptr [SI][LD_FreeSectors]+2,0
               ;BPB has been loaded, yet
               ;LD_MediaChanged= 1 is "New Boot, FAT is not read"
                mov byte ptr [SI][LD_MediaChanged],1

                jmp pass_this_is_FAT32_LBA_disk

pass_this_is_FAT16_LBA_disk:
                cmp byte ptr [SI][ptFileSystemName], 0Bh
                jne short pass_this_is_FAT32_CHS_disk
                mov byte ptr [DI][LD_DiskType], 2
                mov bl, byte ptr [Hard_Disk]
                mov byte ptr [DI][LD_PhyDrvNo], bl
                mov byte ptr [DI][LD_FATType], 3
                mov byte ptr [DI][LD_FSType], 0Bh
                sub bl, 80h
                xor bh, bh
                mov ah, byte ptr [HD_LBAYes][BX]
                mov byte ptr [DI][LD_LBAYes],ah
                mov byte ptr [DI][LD_PartitionEntry],al
                mov ah, bl
                add ah, 2
                mov byte ptr [DI][LD_DParamEntry], ah
                mov ax, word ptr [SI][ptStartSector]
                mov dx, word ptr [SI][ptStartSector]+2
                cmp byte ptr [Now_EP_Drives],0
                jna short pass_0Bh_ext_part_start_fixup
                shl bl, 1
                shl bl, 1
                add ax, word ptr [Val_StartSector][BX]
                adc dx, word ptr [Val_StartSector][BX]+2
                mov word ptr [DI][LD_StartSector], ax
                mov word ptr [DI][LD_StartSector]+2, dx
pass_0Bh_ext_part_start_fixup:
                push ax
                mov ah, byte ptr [Hard_Disk]
                sub ah, 7Eh
                mov al, 40h
                mul ah
                add ax, offset Disk_fd0
                mov di, ax
                pop ax
                cmp byte ptr [DI][DAP_PacketSize], 10h
                jne pass_this_is_FAT32_LBA_disk
                mov word ptr [DI][DAP_LBA_Address], ax
                mov word ptr [DI][DAP_LBA_Address]+2, dx
                jmp short loc_fixup_8GB_CHS_to_LBA
pass_val_startsec_check:
                mov dh, byte ptr [SI][ptBeginHead]
                mov cx, word ptr [SI][ptBeginSector]
                mov ax, 0201h    ; Read 1 sector
                mov bx, offset DOSBootSectorBuff
                int 13h
                jc pass_this_is_FAT32_LBA_disk
                jmp hdp_boot_validation
pass_this_is_FAT32_CHS_disk:
                cmp byte ptr [SI][ptFileSystemName], 0Ch
                jne check_this_is_Singlix_FS_disk
                mov byte ptr [DI][LD_DiskType], 2
                mov ah, byte ptr [Hard_Disk]
                mov byte ptr [DI][LD_PhyDrvNo], ah
                mov byte ptr [DI][LD_FATType], 3
                mov byte ptr [DI][LD_FSType], 0Ch
                mov byte ptr [DI][LD_LBAYes], 1
                mov byte ptr [DI][LD_PartitionEntry],al
                sub ah, 7Eh
                mov byte ptr [DI][LD_DParamEntry], ah
                mov al, 40h
                mul ah
                add ax, offset Disk_fd0
                mov di, ax
                cmp byte ptr [DI][DAP_PacketSize], 10h
                jne pass_this_is_FAT32_LBA_disk
                push word ptr [SI][ptStartSector]
                pop word ptr [DI][DAP_LBA_Address]
                push word ptr [SI][ptStartSector]+2
                pop word ptr [DI][DAP_LBA_Address]+2
loc_fixup_8GB_CHS_to_LBA:
                mov word ptr [DI][DAP_Destination], offset DOSBootSectorBuff
                push ds
                pop word ptr [DI][DAP_Destination]+2
                mov byte ptr [DI][DAP_NumOfBlocks],1
                push di
                pop si  
                add si, DAP_PacketSize ; DS:SI= DAP Location
                mov ah, 42h  ; Extended Disk Read - LBA Read
                mov dl, byte ptr [Hard_Disk]
                int 13h
                jnc hdp_boot_validation
pass_this_is_FAT32_LBA_disk:
; 7/6/2009
pass_this_is_Singlix_FS_disk:
                pop di
                pop ax
                pop cx
                pop si
                add si, 10h
                inc al
                dec cx
                cmp cx, 0
                ja  ldrv_init_next_hdp
                cmp byte ptr [Hard_Disk], 83h
                jnb short pass_init_primary_dos_partitions
                mov cx, 4
                inc byte ptr [Hard_Disk]
                jmp ldrv_init_next_hdp
pass_init_primary_dos_partitions:
                cmp byte ptr [Now_EP_Drives], 0
                ja short loc_drv_init_retn
                mov byte ptr [Now_EP_Drives], 1
                mov si, offset PTable_ep0
                mov byte ptr [Hard_Disk], 80h
                mov ah, byte ptr [Last_DOS_DiskNo]
                inc ah
                xor al,al
                mov di, offset Logical_DOSDisks
                add di, ax
                mov al, 16
                mov cx, 4
                jmp ldrv_init_next_hdp
check_this_is_Singlix_FS_disk:
                ; 7/6/2009 SINGLIX FS Extensions to TR-DOS DRV_INIT
 		cmp byte ptr [SI][ptFileSystemName], 0A1h
                jne short pass_this_is_Singlix_FS_disk
                mov byte ptr [DI][LD_FS_DiskType], 2
                mov ah, byte ptr [Hard_Disk]
                mov byte ptr [DI][LD_FS_PhyDrvNo], ah
               ;mov byte ptr [DI][LD_FS_FATType], 0
                mov byte ptr [DI][LD_FS_FSType], 0A1h
               ;mov byte ptr [DI][LD_FS_LBAYes], 1
                mov byte ptr [DI][LD_PartitionEntry],al
                sub ah, 7Eh
                mov byte ptr [DI][LD_DParamEntry], ah
                mov al, 40h
                mul ah
                add ax, offset Disk_fd0
                mov di, ax
                cmp byte ptr [DI][DAP_PacketSize], 10h
                jne pass_this_is_FAT32_LBA_disk
                push word ptr [SI][ptStartSector]
                pop word ptr [DI][DAP_LBA_Address]
                push word ptr [SI][ptStartSector]+2
                pop word ptr [DI][DAP_LBA_Address]+2
                jmp loc_fixup_8GB_CHS_to_LBA

Now_EP_Drives:  db 0

Val_StartSector: dd 0
                 dd 0
                 dd 0
                 dd 0

loc_drv_init_retn:
                retn

proc_drv_init   endp

proc_dparam   proc near
              ; input
              ; dl = Disk Drive Number
              ; ds:si = Parameters Table Buffer
              ; output
              ; ah = error number (0 = No Error if C flag is ZERO)
              mov byte ptr [si][DPDiskNumber], dl
              mov byte ptr [si][DPDType], 0
              push dx
              mov ah, 08h
              int 13h
              mov byte ptr [si][DPReturn], ah
              jnc short dparam_no_error
              pop dx
              retn
dparam_no_error:
              mov byte ptr [si][DPDType], bl
              mov byte ptr [si][DPDisks], dl
              inc dh
              mov byte ptr [si][DPHeads], dh
              push cx
              and cl, 3Fh
              mov byte ptr [si][DPSecPerTrack], cl
              pop cx
              shr cl,1
              shr cl,1
              shr cl,1
              shr cl,1
              shr cl,1
              shr cl,1
              xchg ch,cl
              inc cx
              mov word ptr [si][DPCylinders], cx
              mov word ptr [si][DPTableOff], di
              push es
              pop word ptr [si][DPTableSeg]

              cmp byte ptr [si][DPDiskNumber], 80h
              jb short dparam_15h_return

              mov dl, byte ptr [si][DPDiskNumber]
              mov byte ptr [Hard_Disk], dl
              mov byte ptr [si][DPDType], 0
              mov ah, 15h
              int 13h
              jc short dparam_15h_return
              mov byte ptr [si][DPDType], ah
              mov word ptr [si][DPNumOfSecs], cx
              mov word ptr [si][DPNumOfSecs]+2, dx
dparam_15h_return:
              pop dx ; dl = Drive Number
              mov byte ptr [SI][DAP_PacketSize], 0 ; Reset (No DAP)
              mov ah, 41h ; Check Extensions Present
              mov bx, 55AAh
              int 13h
              jc short dparam_48h_return
              cmp bx, 0AA55h
              jne short dparam_48h_return
              test cx, 01h ; Fixed Disk Access Subset - is LBA ready ? 
              jz short dparam_48h_return
              xor bh,bh
              mov bl, byte ptr [Hard_Disk]
              sub bl, 80h
              mov byte ptr [HD_LBAYes][BX],1
              mov byte ptr [SI][DAP_PacketSize], 10h
dparam_41h_return:
              push si
              add si, GetDParams_48h
              mov word ptr [SI], 0026 ; GDP Data Lenght - Set
            ; DS:SI= Address of Result Buffer
            ; DL (Drive Number) must be not changed before here...
              mov ah, 48h  ; Get Enhanced Disk Drive Parameters
              int 13h
              pop si
              jc short dparam_48h_return
              mov word ptr [SI][GetDParams_48h], 0 ; GDP Data Lenght - Reset
dparam_48h_return:
              xor ah,ah
              retn
proc_dparam   endp

proc_load_masterboot proc near
                ; input -> dl = drive number
                xor ah,ah
                int 13h
                jnc short pass_reset_error
harddisk_error:
                retn
pass_reset_error:
                mov bx, offset MasterBootBuff
                mov ax,0201h
                mov cx,1
                xor dh,dh
                push ds
                pop es
                int 13h
                jc short harddisk_error

                cmp word ptr [MBIDCode],0AA55h
                jnz short loc_not_masterboot
                retn
loc_not_masterboot:
                stc
                retn

proc_load_masterboot endp

floppy_drv_init proc near
                ; 6-6-2009 
                ; INPUT -> dl = Drive Number (0,1)
                ; OUTPUT -> al = drive name,
                ;           ah = drive number
                mov si, offset Disk_fd0
                mov di, offset Logical_DOSDisks
                xor dh, dh
                cmp dl, 0
                jna short pass_drv_init_fd1
                add si, 40h
                add di, 100h
pass_drv_init_fd1:
                mov byte ptr [DI][LD_MediaChanged],0
                cmp byte ptr [SI][DPDType], 1
                jb short pass_fd_read_boot_sector2
read_fd_boot_sector:
                push ds
                pop es
                push dx
                mov cx, 4 ; Retry Count
read_fd_boot_sector_again:
                push cx
                mov cx, 1
                mov ax, 0201h    ; Read 1 sector
                mov bx, offset DOSBootSectorBuff
                int 13h
                pop cx
                jnc short use_fd_boot_sector_params
                loop read_fd_boot_sector_again
pass_fd_read_boot_sector0:
                stc
pass_fd_read_boot_sector1:
                pop dx
pass_fd_read_boot_sector2:
                retn
use_fd_boot_sector_params:
               ;mov si, offset DOSBootSectorBuff
                mov si, bx

                cmp word ptr [SI][BS_Validation], 0AA55h
                jne short pass_fd_read_boot_sector0
                cmp word ptr [SI][bs_FS_Identifier], 'SF'
                jne pass_use_fsfd_boot_sector_params

                mov al, byte ptr [SI][bs_FS_LBA_Ready]
                mov byte ptr [DI][LD_FS_LBAYes], al
                mov ax, word ptr [SI][bs_FS_BytesPerSec]
                mov word ptr [DI][LD_FS_BytesPerSec], ax
                mov ax, word ptr [SI][bs_FS_MediaAttrib]
                mov word ptr [DI][LD_FS_MediaAttrib], ax
		mov ax, word ptr [SI][bs_FS_SecPerTrack]
                mov word ptr [DI][LD_FS_SecPerTrack], ax
                mov ax, word ptr [SI][bs_FS_UnDelDirD]
                mov dx, word ptr [SI][bs_FS_UnDelDirD]+2
                mov word ptr [DI][LD_FS_UnDelDirD], ax
                mov word ptr [DI][LD_FS_UnDelDirD]+2, dx
                mov ax, word ptr [SI][bs_FS_MATLocation]
                mov dx, word ptr [SI][bs_FS_MATLocation]+2
                mov word ptr [DI][LD_FS_MATLocation], ax
                mov word ptr [DI][LD_FS_MATLocation]+2, dx
                mov ax, word ptr [SI][bs_FS_RootDirD]
 		mov dx, word ptr [SI][bs_FS_RootDirD]+2
                mov word ptr [DI][LD_FS_RootDirD], ax
                mov word ptr [DI][LD_FS_RootDirD]+2, dx
 		mov ax, word ptr [SI][bs_FS_BeginSector]
 		mov dx, word ptr [SI][bs_FS_BeginSector]+2
                mov word ptr [DI][LD_FS_BeginSector], ax
                mov word ptr [DI][LD_FS_BeginSector]+2, dx  
                mov ax, word ptr [SI][bs_FS_VolumeSize]
 		mov dx, word ptr [SI][bs_FS_VolumeSize]+2
                mov word ptr [DI][LD_FS_VolumeSize], ax
                mov word ptr [DI][LD_FS_VolumeSize]+2, dx
  
                mov cx, 4
                pop dx
		push dx 
read_fd_MAT_sector_again:
                push cx
                mov cx, 2
                mov ax, 0201h    ; Read 1 sector
                ;mov bx, offset DOSBootSectorBuff
                int 13h
                pop cx
                jnc short use_fdfs_mat_sector_params
                loop read_fd_mat_sector_again
                jmp pass_fd_read_boot_sector0
use_fdfs_mat_sector_params:
 		mov ax, word ptr [SI][FS_MAT_DATLocation]
                mov dx, word ptr [SI][FS_MAT_DATLocation]+2                                  
 		mov word ptr [DI][LD_FS_DATLocation], ax
                mov word ptr [DI][LD_FS_DATLOcation]+2, dx

		mov ax, word ptr [SI][FS_MAT_DATScount]
                mov dx, word ptr [SI][FS_MAT_DATScount]+2                                  
 		mov word ptr [DI][LD_FS_DATSectors], ax
                mov word ptr [DI][LD_FS_DATSectors]+2, dx

                mov ax, word ptr [SI][FS_MAT_FreeSectors]
                mov dx, word ptr [SI][FS_MAT_FreeSectors]+2                                  
 		mov word ptr [DI][LD_FS_FreeSectors], ax
                mov word ptr [DI][LD_FS_FreeSectors]+2, dx

 		mov ax, word ptr [SI][FS_MAT_FirstFreeSector]
                mov dx, word ptr [SI][FS_MAT_FirstFreeSector]+2                                  
 		mov word ptr [DI][LD_FS_FirstFreeSector], ax
                mov word ptr [DI][LD_FS_FirstFreeSector]+2, dx

                mov cx, 4
                pop dx
                push dx         
read_fd_RDT_sector_again:
                push cx
                mov cx, 9
                mov ax, 0201h    ; Read 1 sector
               ;mov bx, offset DOSBootSectorBuff
                int 13h
                pop cx
                jnc short use_fdfs_RDT_sector_params
                loop read_fd_RDT_sector_again
                jmp pass_fd_read_boot_sector0
use_fdfs_RDT_sector_params:
                mov ax, word ptr [SI][FS_RDT_VolumeSerialNo]
                mov dx, word ptr [SI][FS_RDT_VolumeSerialNo]+2                                  
                mov word ptr [DI][LD_FS_VolumeSerial], ax
                mov word ptr [DI][LD_FS_VolumeSerial]+2, dx

                push di
                push si
                mov cx, 32
                add si, FS_RDT_VolumeName
                add di, LD_FS_VolumeName
                rep movsw
                pop si
                pop di

                jmp loc_cont_use_fd_boot_sector_params

pass_use_fsfd_boot_sector_params:
		cmp byte ptr [SI][BS_BootSig], 29h
                jne pass_fd_read_boot_sector0
                cmp byte ptr [SI][BPB_Media], 0F0h
                jb pass_fd_read_boot_sector1

                push di
                add di, LD_BPB
                mov cx, 32
                rep movsw 
                pop si
                ;xor ax, ax
               ;mov Word Ptr [SI][LD_StartSector], AX
               ;mov Word Ptr [SI][LD_StartSector]+2,0
                add AX,Word Ptr [SI][LD_BPB][BPB_RsvdSecCnt]
                mov Word Ptr [SI][LD_FATBegin], AX
               ;mov Word Ptr [SI][LD_FATBegin]+2, 0
                mov AL,Byte Ptr [SI][LD_BPB][BPB_NumFATs] 
                cbw                             
                mul Word Ptr [SI][LD_BPB][BPB_FATSz16]
                add AX,Word Ptr [SI][LD_FATBegin]
                mov Word Ptr [SI][LD_ROOTBegin], AX
               ;mov Word Ptr [SI][LD_ROOTBegin]+2, 0
                mov Word Ptr [SI][LD_DATABegin], AX 
               ;mov Word Ptr [SI][LD_DATABegin]+2, 0
                mov AX,20h   ; Size of a directory entry
                mul Word Ptr [SI][LD_BPB][BPB_RootEntCnt]
                add AX,511
                mov cx,512
                div cx
                add Word Ptr [SI][LD_DATABegin], AX 
               ;adc Word Ptr [SI][LD_DATABegin]+2, 0 
                mov AX,Word Ptr [SI][LD_BPB][BPB_TotalSec16]
                mov Word Ptr [SI][LD_TotalSectors], AX
               ;mov Word Ptr [SI][LD_TotalSectors]+2,0
                sub ax,Word Ptr [SI][LD_DATABegin]
                xor dx,dx
                xor ch,ch
                mov cl,Byte Ptr [SI][LD_BPB][BPB_SecPerClust]
                div cx 
                mov word ptr [SI][LD_Clusters], AX
                mov word ptr [SI][LD_Clusters]+2, 0
                    ; Maximum Valid Cluster Number= AX +1
                    ; with 2 reserved clusters= AX +2
               
                pop dx
		push dx
                mov bx, offset FAT12_Buffer
                mov es, bx
                xor bx, bx 
read_fd_FAT_sectors_again:
                push cx
		mov cx, word ptr [SI][LD_BPB][BPB_RsvdSecCnt]
                inc cx
                mov al, byte ptr [SI][LD_BPB][BPB_FATSz16]
                mov ah, 02h    ; Read AL sectors <= sec/track
                int 13h
                pop cx
                jnc short use_fd_FAT_sectors
                loop read_fd_FAT_sectors_again
                push ds
                pop es
                jmp pass_fd_read_boot_sector0                
use_fd_FAT_sectors:
                call fd_init_calculate_free_clusters
                jnc short loc_cont_use_fd_boot_sector_params

                cmp ax, 0
                ja pass_fd_read_boot_sector0
 
loc_cont_use_fd_boot_sector_params:
                pop ax

                mov byte ptr [SI][LD_FATType], 1
                mov byte ptr [SI][LD_FSType], 1
                mov byte ptr [SI][LD_DParamEntry], al
                mov byte ptr [SI][LD_PhyDrvNo], al
                mov ah, al
                add al, 'A'
                mov byte ptr [SI][LD_Name], al
                mov byte ptr [SI][LD_DiskType], 1
               ;mov byte ptr [SI][LD_LBAYes], 0
               ;mov byte ptr [SI][LD_PartitionEntry], 0
                mov byte ptr [SI][LD_MediaChanged], 1

                retn

fd_Location: dw 0

fd_init_calculate_free_clusters:

                mov ax, word ptr [SI][LD_BPB][BPB_RsvdSecCnt]
                mov dx, ax
                mov al, byte ptr [SI][LD_BPB][BPB_NumFATs] 
                cbw                             
                mul word ptr [SI][LD_BPB][BPB_FATSz16]
                add dx, ax
                push dx
                mov ax, 20h   ; Size of a directory entry
                mul word ptr [SI][LD_BPB][BPB_RootEntCnt]
                add ax, 511
                mov cx, 512
                div cx
                pop dx
                add dx, ax 
                mov ax, word ptr [SI][LD_BPB][BPB_TotalSec16]
                sub ax, dx
                xor dx, dx
                xor ch, ch
                mov cl, byte ptr [SI][LD_BPB][BPB_SecPerClust]
                div cx 
                mov word ptr [SI][LD_Clusters], ax ; Clusters

                mov ax, 2
                mov dx, 0

fd_init_loop_get_next_cluster:
                push ax
                push dx
                call fd_init_get_next_cluster
                jnc short fd_init_free_fat_clusters
                cmp ax, 0
                jna short fd_init_pass_inc_free_cluster_count
                pop dx
                pop ax

retn_from_fd_init_calculate_free_clusters:

                mov ax, word ptr [SI][LD_FreeSectors]
                xor ch, ch
                mov cl, byte ptr [SI][LD_BPB][BPB_SecPerClust]
                mul cx
                mov word ptr [SI][LD_FreeSectors], ax

                push ds
                pop es

                retn

fd_init_free_fat_clusters:
                cmp ax, 0
                ja short fd_init_pass_inc_free_cluster_count
                inc word ptr [SI][LD_FreeSectors]
            
fd_init_pass_inc_free_cluster_count:
                pop dx
                pop ax
                
                cmp ax, word ptr [SI][LD_Clusters]
                ja short short retn_from_fd_init_calculate_free_clusters

                inc ax
                jmp short fd_init_loop_get_next_cluster

fd_init_get_next_cluster:
                push ax
                mov dx, 3
                mul dx    ; Multiply AX by 3
                shr ax, 1 ; Divide result by 2
                mov bx, ax
                pop ax
                mov cx, ax
                shr cx, 1
                mov ax, word ptr ES:[BX]
                jnc short fd_init_gnc_even
                shr ax, 1
                shr ax, 1
                shr ax, 1
                shr ax, 1

fd_init_gnc_eoc_check:
                cmp al, 0F6h
                jna short fd_init_pass_gnc_eoc_check
                cmp ah, 0Fh
                jb short fd_init_pass_gnc_eoc_check
                xor ax, ax 
                stc
                retn
fd_init_pass_gnc_eoc_check:
                clc
                retn

fd_init_gnc_even:
                and ah,0Fh
                jmp short fd_init_gnc_eoc_check

floppy_drv_init endp

HDCounter:     db 1

MasterBootBuff:
MasterBootCode: db 1BEh dup (?)
PartitionTable: db 64 dup (?)
MBIDCode: dw ?

PTable_Buffer:
PTable_hd0: db 64 dup (0)
PTable_hd1: db 64 dup (0)
PTable_hd2: db 64 dup (0)
PTable_hd3: db 64 dup (0)
PTable_ep0: db 64 dup (0)
PTable_ep1: db 64 dup (0)
PTable_ep2: db 64 dup (0)
PTable_ep3: db 64 dup (0)

DiskParams:
Disk_fd0: db 16 dup (0)
DAP_fd0: db 16 dup(0)
GDP_fd0: db 26 dup(0)
TRDP_fd0: db 6 dup(0)
Disk_fd1: db 16 dup (0)
DAP_fd1: db 16 dup(0)
GDP_fd1: db 26 dup(0)
TRDP_fd1: db 6 dup(0)
Disk_hd0: db 16 dup (0)
DAP_hd0: db 16 dup(0)
GDP_hd0: db 26 dup(0)
TRDP_hd0: db 6 dup(0)
Disk_hd1: db 16 dup (0)
DAP_hd1: db 16 dup(0)
GDP_hd1: db 26 dup(0)
TRDP_hd1: db 6 dup(0)
Disk_hd2: db 16 dup (0)
DAP_hd2: db 16 dup(0)
GDP_hd2: db 26 dup(0)
TRDP_hd2: db 6 dup(0)
Disk_hd3: db 16 dup (0)
DAP_hd3: db 16 dup(0)
GDP_hd3: db 26 dup(0)
TRDP_hd3: db 6 dup(0)
end_of_dparams_buff:

DOSBootSectorBuff:
db 512 dup(0)

Hard_Disk:         db 80h
Last_DOS_DiskNo:   db 0
HD_LBAYes:         dd 0

FAT12_Buffer: db 4608 dup(0) 
