; *****************************************************************************
; DRVINFO5.ASM  - PHYSICAL DRIVE INFO [Standalone program]
; Copyright (c) 2014  Erdogan TAN  [ 21/11/2014 ]  
; *****************************************************************************

Present segment Para 'code'

                assume CS:Present, DS:Present, ES:Present, SS:Present

;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;±              PROCEDURE proc_start
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±

start:
		org	100h
		xor 	dl, dl
		;mov	byte ptr [drv], dl ; 0
rfdp:
		mov 	ah, 08h	; Return drive parameters (conventional)	
              	int 	13h
		jc	short rfdp_ok
		;cmp	bl, 6		   ; 3=720kB, 4=1.44MB, 6=2.88MB 		
		;ja	rfdp_ok
                                           ; floppy disk drive type
				           ; (1=360K, 2=1.2M, 3=720K, 4=1.44M)

                add	bl, 30h	; '0'
                mov     byte ptr [flpdtype], bl
		call	clear_screen
		call	print_flpdpt
		xor	ah, ah
		int	16h
		cmp 	byte ptr [drv], 0
		ja	short rfdp_ok
		dec	dl		   ; floppy drive count - 1
		jz	short rfdp_ok	   ; only 1 floppy drive
		inc	byte ptr [drv]
		mov	dl, 1
		jmp	short rfdp
rfdp_ok:
		mov	dl, 7Fh
		mov	byte ptr [drv], dl ; previous disk number (7Fh=none)
rhdp:
		inc	dl ; current disk number
		mov 	ah, 08h	; Return drive parameters (conventional)	
              	int 	13h
                jc      short rhdp_fails
		mov	byte ptr [hdc], dl ; number of drives
		inc	byte ptr [drv]     ; points to current disk number
		mov	dl, byte ptr [drv]
		mov	bx, 65*4	   ; hd0 parameters table (INT 41h)	
		cmp	dl, 80h
		jna	short rhdps
		add	bx, 5*4		   ; hd1 parameters table (INT 46h)
rhdps:				   
		mov	ax, cs
		mov	es, ax
		xor	ax, ax
		mov	ds, ax
		mov	si, word ptr [BX]
		mov	ax, word ptr [BX+2]	
		mov	ds, ax
                call    clear_screen
		cmp	byte ptr [SI]+3, 0A0h
		je	short wtfdpt
wsfdpt:
		call	print_sfdpt
		jmp	short wfdpt_next
wtfdpt:
		call	print_tfdpt
wfdpt_next:
		xor	ah, ah
		int 	16h
		dec	byte ptr [hdc]
		jz	short chk_ext
		;mov	dl, byte ptr [drv] ; previous disk number
		cmp	dl, 80h	; hd0 (INT 41h), hd1 (INT 46h) only!
		ja	short chk_ext
		jmp	short rhdp
rhdp_fails:
		cmp 	byte ptr [drv], 80h
                jnb     short chk_ext
end_of_prog:
		;al, 	byte ptr [drv]
		;sub	al, 7Fh
		;mov	byte ptr [hdc], al ; count of hard (fixed) disks
		;	
		call	clear_screen
		mov	si, offset version_msg
		call	print_msg
		xor	ah, ah
		int 	16h
	 	;
		int	20h	; Terminate
haltsys:
		hlt
		jmp	short haltsys
		;
chk_ext:
		mov	dl, 80h
chke_l:
		mov	ah, 41h ; Check extensions present
				; Phoenix EDD v1.1
		mov	bx, 55AAh
		int 	13h
		jc	short end_of_prog
		cmp	bx, 0AA55h
		jne	short end_of_prog
		;
		mov	byte ptr [drv], dl
		;
		mov	si, offset last_byte ; 30 bytes temp buff addr 	
			 	             ; after the last byte.
		mov	word ptr [SI], 30
		;
		mov	ah, 48h	 ; Get drive parameters (EDD function)
		int	13h
		jc	short chke_n
		add	si, 26   ; (BIOS) DPTE address pointer
		lodsw
		push	ax	 ; (BIOS) DPTE offset
		lodsw
		mov	ds, ax	 ; (BIOS) DPTE segment
		pop	si	 ; (BIOS) DPTE offset
		;
		call 	clear_screen
		call    print_fdpte
chke_n:
		xor	ah, ah
		int 	16h
		cmp	dl, 83h
		jnb	short end_of_prog
		inc	dl
		jmp	short chke_l	
		;
print_flpdpt:
		; Writing the Diskette Parameter Table on screen
		mov	si, di
		mov	ax, es
		mov	ds, ax
		mov	ax, cs
		mov	es, ax
		lodsb 	; bits 0-3: SRT step rate time
			; bits 4-7: head unload time
		mov	di, rSrtHdUnld
		call	write_hex
		lodsb 	; bit 0: 1=use DMA
			; bits 2-7: head load time
		mov	di, rDmaHdLd
		call	write_hex
		lodsb 	; 55-ms increments 
			; before turning disk motor off
		mov	di, bMotorOff
		call	write_hex
		lodsb 	; sector size
			; (0=128, 1=256, 2=512, 3=1024)
		mov	di, bSectSize
		call	write_hex
		lodsb 	; EOT (last sector on a track)
		mov	di, bLastTrack
		call	write_hex
		lodsb 	; gap length 
			; for read/write operations
		mov	di, bGapLen
		call	write_hex
		lodsb 	; DTL (Data Transfer Length)
			; max transfer when length not set	
		mov	di, bDTL
		call	write_hex
		lodsb 	; gap length for format operation
		mov	di, bGapFmt
		call	write_hex
		lodsb 	; fill character for format 
			; (normally F6H)
		mov	di, bFillChar
		call	write_hex
		lodsb 	; head-settle time
			; (in milliseconds)
		mov	di, bHdSettle
		call	write_hex
		lodsb 	; motor-startup time
			; (in 1/8th-second intervals)
		mov	di, bMotorOn
		call	write_hex
		mov	ax, cs
		mov	ds, ax
		mov	al, byte ptr [drv]
		add	al, 30h ; '0'
		mov	byte ptr [flpdnum], al
		mov	si, offset FLPDPT
		call	print_msg
		retn
		;
print_sfdpt:
		; Writing the Standard FDPT on screen
		; (PHOENIX - EDD specification v1.1)
		lodsw 	; Physical Numbers of Cylinders
		mov	di, pcylnum
		call	write_dhex
		lodsb	; Physical Numbers of Heads
		mov	di, pheadnum
		call	write_hex
		lodsb	; Reserved
		mov	di, rsvd3
		call	write_hex
		lodsb	; Reserved
		mov	di, rsvd4
		call	write_hex
		lodsw	; Precompensation (Obsolete)
		mov	di, pcompnum
		call	write_dhex
		lodsb	; Reserved
		mov	di, Rsvd7
		call	write_hex
		lodsb	; Drive Control Byte
		mov	di, dcbnum
		call	write_hex
		lodsw	; Reserved
		mov	di, rsvd9
		call	write_dhex
		lodsb	; Reserved
		mov	di, rsvd11
		call	write_hex
		lodsw	; Landing Zone (Obsolete)
		mov	di, lzonenum
		call	write_dhex
		lodsb	; Sectors per Track
		mov	di, psptnum
		call	write_hex
		lodsb	; Reserved
		mov	di, rsvd15
		call	write_hex
		mov	ax, cs
		mov	ds, ax
		mov	dl, byte ptr [drv]
		mov	si, offset dsknum
		call	put_drvnum
		mov	si, offset SFDPT
		call	print_msg
		retn
print_tfdpt:
		; Writing the Translated FDPT on screen
		; (PHOENIX - EDD specification v1.1)
		lodsw 	; Logical Numbers of Cylinders, Limit 1024
		mov	di, lcylnum
		call	write_dhex
		lodsb	; Logical Numbers of Heads, Limit 256
		mov	di, lheadnum
		call	write_hex
		lodsb	; A0h signature, indicates translated table
		mov	di, tsignum
		call	write_hex
		lodsb	; Physical Sectors per Track
		mov	di, tpsptnum
		call	write_hex
		lodsw	; Precompensation (Obsolete)
		mov	di, tpcompnum
		call	write_dhex
		lodsb	; Reserved
		mov	di, trsvd7
		call	write_hex
		lodsb	; Drive Control Byte
		mov	di, tdcbnum
		call	write_hex
		lodsw	; Physical Cylinders, limit 65536
		mov	di, tpcylnum
		call	write_dhex
		lodsb	; Physical Heads, limit 16
		mov	di, tpheadnum
		call	write_hex
		lodsw	; Landing Zone (Obsolete)
		mov	di, tlzonenum
		call	write_dhex
		lodsb	; Logical Sectors per Track, Limit 63
		mov	di, lsptnum
		call	write_hex
		lodsb	; Checksum for translated FDPT 
		mov	di, checksum
		call	write_hex
		mov	ax, cs
		mov	ds, ax
		mov	dl, byte ptr [drv]
		mov	si, offset tdsknum
		call	put_drvnum
		mov	si, offset TFDPT
		call	print_msg
		retn
put_drvnum:
		mov	bl, dl
		xor	bh, bh
                shr     bl, 1
                shr     bl, 1
                shr     bl, 1
                shr     bl, 1
                add     bx, offset hex_digits
		mov	al, byte ptr [BX]
		mov	bl, dl
		xor	bh, bh
		and	bl, 0Fh
		add	bx, offset hex_digits
		mov	ah, byte ptr [BX]
		mov	word ptr [SI], ax
		retn
write_dhex:
		mov	bl, ah
                shr     bl, 1
                shr     bl, 1
                shr     bl, 1
                shr     bl, 1
                call    dhgd
		mov	bl, ah
		call	dhgd
write_hex:
		mov	bl, al
                shr     bl, 1
                shr     bl, 1
                shr     bl, 1
                shr     bl, 1        
		call	dhgd
		mov	bl, al
		call	dhgd
		retn
dhgd:
		push	ax
		xor	bh, bh
		and	bl, 0Fh
		add	bx, offset hex_digits
		mov	al, byte ptr CS:[BX]
		stosb
		pop	ax
		retn
print_fdpte:
		; Writing the FDPT Extension on screen
		; (PHOENIX - EDD specification v1.1)
		mov	ax, cs
		mov	es, ax
		lodsw 	; I/O port base address
		mov	di, ioport
		call	write_dhex
		lodsw	; Control port address
		mov	di, ctrlport
		call	write_dhex
		lodsb	; Head register upper nibble
		mov	di, hregun
		call	write_hex
		lodsb	; Internal Use Only.
		mov	di, einternal
		call	write_hex
		lodsb	; IRQ Information
		mov	di, irqinf
		call	write_hex
		lodsb	; Sector count for multisector transfers
		mov	di, scmst
		call	write_hex
		lodsb	; DMA information
		mov	di, dmainf
		call	write_hex
		lodsb	; PIO Information
		mov	di, pioinf
		call	write_hex
		lodsw	; Hardware specific option flags
		mov	di, hsoflgs
		call	write_dhex
		lodsw	; Reserved, must me 0
		mov	di, ersvd
		call	write_dhex
		lodsb	; Revision level of this extension (11h)
		mov	di, extrl
		call	write_hex
		lodsb	; Checksum, 
			; 2's complement of the sum of bytes 0-14
		mov	di, echecksum
		call	write_hex
		mov	ax, cs
		mov	ds, ax
		mov	si, offset edsknum
		call	put_drvnum
		mov	si, offset FDPTE
		call	print_msg
		retn
hex_digits:
		db '0123456789ABCDEF'			
print_msg:
                mov	bx, 7
pmsg_next:
                lodsb                           ; Load byte at DS:SI to AL
                and     AL,AL            
                je      short pmsg_retn		; If AL = 00h then return
                mov     AH,0Eh                  
                int     10h                     ; BIOS Service func ( ah ) = 0Eh
                                                ; Write char as TTY
                                                ; AL-char BH-page BL-color
                jmp     short pmsg_next          
pmsg_retn:
                retn
clear_screen:
                mov ah, 0Fh ; get video mode
                int 10h
		; al = video mode
                mov ah, 0   ; set video mode (clears screen)
                int 10h
                retn

drv: db 0
hdc: db 0

FLPDPT:
db 07h
db 0Dh, 0Ah	
db 'Disk '
flpdnum:
db 'X - '
db 'DISKETTE PARAMETER TABLE'
db 0Dh, 0Ah, 0DH, 0Ah
db 'Type                 : '
flpdtype:
db 'X   '
db '[ 1 = 360K, 2 = 1.2M, 3 = 720K, 4 = 1.44M ]'
db 0Dh, 0Ah, 0DH, 0Ah 
db 'SRT - Head Unld Time : '
rSrtHdUnld:
db 'XXh (bits 0-3: SRT, bits 4-7: head unload time)'
db 0Dh, 0Ah
db 'DMA - Head Load Time : '
rDmaHdLd:
db 'XXh (bit 0: 1 = DMA, bits 2-7: head load time)'
db 0Dh, 0Ah
db 'Motor Off Count      : '
bMotorOff:
db 'XXh (with 55ms icrements before turning off)'
db 0Dh, 0Ah
db 'Sector Size          : '
bSectSize:
db 'XXh (2 = 512 bytes)'
db 0Dh, 0Ah	
db 'Last Sect on a Track : '
bLastTrack:
db 'XXh'
db 0Dh, 0Ah
db 'Gap Length  (R/W)    : '
bGapLen:
db 'XXh'
db 0Dh, 0Ah
db 'Data Transfer Length : '
bDTL:
db 'XXh'
db 0Dh, 0Ah		
db 'Gap Length (Format)  : '
bGapFmt:
db 'XXh'
db 0Dh, 0Ah
db 'Fill Char for format : '
bFillChar:
db 'XXh (normally F6h)'
db 0Dh, 0Ah
db 'Head Settle Time     : '
bHdSettle:
db 'XXh milliseconds'
db 0Dh, 0Ah
db 'Motor Startup Time   : '
bMotorOn:
db 'XXh (in 1/8th second intervals)'
db 0Dh, 0Ah
db 0Dh, 0Ah, 0	

SFDPT:
db 07h
db 0Dh, 0Ah
db 'Disk '
dsknum:
db 'XXh - '	
db 'STANDARD FIXED DISK PARAMETER TABLE'
db 0Dh, 0Ah, 0DH, 0Ah 
db 'Physical Cylinders : '
pcylnum:
db 'XXXXh'
db 0Dh, 0Ah
db 'Physical Heads     : '
pheadnum:
db 'XXh'
db 0Dh, 0Ah
db 'Reserved           : '
rsvd3:
db 'XXh'
db 0Dh, 0Ah
db 'Reserved           : '
rsvd4:
db 'XXh'
db 0Dh, 0Ah	
db 'Precompensation    : '
pcompnum:
db 'XXXXh'
db 0Dh, 0Ah
db 'Reserved           : '
rsvd7:
db 'XXh'
db 0Dh, 0Ah
db 'Drive Control Byte : '
dcbnum:
db 'XXh'
db 0Dh, 0Ah		
db 'Reserved           : '
rsvd9:
db 'XXXXh'
db 0Dh, 0Ah
db 'Reserved           : '
rsvd11:
db 'XXh'
db 0Dh, 0Ah
db 'Landing Zone       : '
lzonenum:
db 'XXXXh'
db 0Dh, 0Ah
db 'Sectors per Track  : '
psptnum:
db 'XXh'
db 0Dh, 0Ah
db 'Reserved           : '
rsvd15:
db 'XXh'
db 0Dh, 0Ah
db 0Dh, 0Ah, 0	

TFDPT:
db 07h
db 0Dh, 0Ah
db 'Disk '
tdsknum:
db 'XXh - '	
db 'TRANSLATED FIXED DISK PARAMETER TABLE'
db 0Dh, 0Ah, 0DH, 0Ah 
db 'Logical Cylinders  : '
lcylnum:
db 'XXXXh'
db 0Dh, 0Ah
db 'Logical Heads      : '
lheadnum:
db 'XXh'
db 0Dh, 0Ah
db 'Signature          : '
tsignum:
db 'XXh'
db 0Dh, 0Ah
db 'Phy Sec per Track  : '
tpsptnum:
db 'XXh'
db 0Dh, 0Ah	
db 'Precompensation    : '
tpcompnum:
db 'XXXXh  (Obsolete)'
db 0Dh, 0Ah
db 'Reserved           : '
trsvd7:
db 'XXh'
db 0Dh, 0Ah
db 'Drive Control Byte : '
tdcbnum:
db 'XXh'
db 0Dh, 0Ah		
db 'Physical Cylinders : '
tpcylnum:
db 'XXXXh'
db 0Dh, 0Ah
db 'Physical Heads     : '
tpheadnum:
db 'XXh'
db 0Dh, 0Ah
db 'Landing Zone       : '
tlzonenum:
db 'XXXXh  (Obsolete)'
db 0Dh, 0Ah
db 'Logic Sec per Trk  : '
lsptnum:
db 'XXh'
db 0Dh, 0Ah
db 'Checksum           : '
checksum:
db 'XXh'
db 0Dh, 0Ah
db 0Dh, 0Ah, 0

FDPTE:
db 07h
db 0Dh, 0Ah
db 'Disk '
edsknum:
db 'XXh - '	
db 'FIXED DISK PARAMETER TABLE EXTENSION'
db 0Dh, 0Ah, 0DH, 0Ah 
db 'I/O Port Base Addr  : '
ioport:
db 'XXXXh'
db 0Dh, 0Ah
db 'Ctrl Port Base Addr : '
ctrlport:
db 'XXXXh'
db 0Dh, 0Ah
db 'Head Reg Upp Nibble : '
hregun:
db 'XXh'
db 0Dh, 0Ah
db '(Internal Use only) : '
einternal:
db 'XXh'
db 0Dh, 0Ah
db 'IRQ Information     : '
irqinf:
db 'XXh'
db 0Dh, 0Ah
db 'Multi sector count  : '
scmst:
db 'XXh'
db 0Dh, 0Ah	
db 'DMA Information     : '
dmainf:
db 'XXh'
db 0Dh, 0Ah	
db 'PIO Information     : '
pioinf:
db 'XXh'
db 0Dh, 0Ah
db 'Hardware Ops Flgs   : '
hsoflgs:
db 'XXXXh'
db 0Dh, 0Ah
db 'Reserved            : '
ersvd:
db 'XXXXh'
db 0Dh, 0Ah		
db 'Rev Level of Ext    : '
extrl:
db 'XXh'
db 0Dh, 0Ah
db 'Checksum            : '
echecksum:
db 'XXh'
db 0Dh, 0Ah
db 0Dh, 0Ah, 0		

version_msg:
db 07h
db 0Dh, 0Ah
db 'Physical Drive Info - v1.0 (DRVINFO5)'
db 0Dh, 0Ah
db 'by Erdogan Tan [21/11/2014]'
db 0Dh, 0Ah
db 0Dh, 0Ah, 0

last_byte:
	db 0		
 
Present            ends

		   end 	start	
