Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 533)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 535)
@@ -59,7 +59,6 @@
 ; BIOS that does just that.
 ;
-; Since I don't have any better knowledge, I decided that when RESERVE_DIAGNOSTIC_CYLINDER
-; is defined, we do what the Award BIOS does. When it is not defined, we multiply
-; P-CHS values together and use that as total sector count.
+; I decided that we multiply P-CHS values and do not waste space like the
+; Award BIOS does.
 ;
 ;
@@ -78,33 +77,63 @@
 ;--------------------------------------------------------------------
 AH48h_HandlerForGetExtendedDriveParameters:
+	mov		si, di
+	push	ds
+	pop		es		; ES = RAMVARS segment
+	xor		bx, bx
+	dec		bx		; Set to FFFFh to assume we do not return DPTE
+
+	; Create DPTE (hardware information for device drivers)
+%ifdef RETURN_DPTE_ON_AH48H
+	call	AH41h_GetSupportBitsToCX
+	test	cl, ENHANCED_DISK_DRIVE_SUPPORT
+	jz		SHORT .DoNotCreateDPTE
+	call	CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI
+.DoNotCreateDPTE:
+%endif
+
+	; Point DS:DI to Extended Drive Information Table to fill
+	mov		di, [bp+IDEPACK.intpack+INTPACK.si]
+	mov		ds, [bp+IDEPACK.intpack+INTPACK.ds]
+
+	; Check and adjust Extended Drive Information Table size
+	; to MINIMUM_EDRIVEINFO_SIZE or EDRIVEINFO_SIZE_WITH_DPTE
+	mov		ax, MINIMUM_EDRIVEINFO_SIZE
+	mov		cx, [di+EDRIVE_INFO.wSize]
+	cmp		cx, ax
+	jb		Prepare_ReturnFromInt13hWithInvalidFunctionError
+	mov		[di+EDRIVE_INFO.wSize], ax
+	add		al, EDRIVEINFO_SIZE_WITH_DPTE - MINIMUM_EDRIVEINFO_SIZE
+	cmp		cx, ax
+	jb		SHORT .SkipEddConfigurationParameters
+	mov		[di+EDRIVE_INFO.wSize], ax
+
+	; Store DPTE for standard controllers only,
+	; FFFF:FFFF for non standard controllers
+%ifdef RETURN_DPTE_ON_AH48H
+	mov		[di+EDRIVE_INFO.fpDPTE], bx
+	mov		[di+EDRIVE_INFO.fpDPTE+2], es
+	inc		bx
+	jnz		SHORT .SkipEddConfigurationParameters	; Already stored
+	dec		bx
+	mov		[di+EDRIVE_INFO.fpDPTE+2], bx	; Segment = FFFFh
+%else
+	mov		[di+EDRIVE_INFO.fpDPTE], bx
+	mov		[di+EDRIVE_INFO.fpDPTE+2], bx
+%endif
+
+	; Fill Extended Drive Information Table in DS:DI from DPT in ES:SI
+.SkipEddConfigurationParameters:
+	mov		WORD [di+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
+
+	; Store total sector count
+	call	Registers_ExchangeDSSIwithESDI
 	call	AccessDPT_GetLbaSectorCountToBXDXAX
-
-	; Point DS:SI to Extended Drive Information Table to fill
-	push	ds
-	pop		es			; DPT now in ES:DI
-	mov		ds, [bp+IDEPACK.intpack+INTPACK.ds]
-	mov		cx, MINIMUM_EDRIVEINFO_SIZE
-	cmp		[si+EDRIVE_INFO.wSize], cx
-	jb		Prepare_ReturnFromInt13hWithInvalidFunctionError
-	je		SHORT .SkipEddConfigurationParameters
-
-	; We do not support EDD Configuration Parameters so set to FFFF:FFFFh
-	sub		cx, BYTE MINIMUM_EDRIVEINFO_SIZE+1	; CX => FFFFh
-	mov		[si+EDRIVE_INFO.fpEDDparams], cx
-	mov		[si+EDRIVE_INFO.fpEDDparams+2], cx
-	mov		cx, EDRIVE_INFO_size
-
-	; Fill Extended Drive Information Table in DS:SI
-.SkipEddConfigurationParameters:
-	mov		[si+EDRIVE_INFO.wSize], cx
-	mov		WORD [si+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
-
-	; Store total sector count
-	mov		[si+EDRIVE_INFO.qwTotalSectors], ax
-	mov		[si+EDRIVE_INFO.qwTotalSectors+2], dx
-	mov		[si+EDRIVE_INFO.qwTotalSectors+4], bx
+	call	Registers_ExchangeDSSIwithESDI
+	mov		[di+EDRIVE_INFO.qwTotalSectors], ax
+	mov		[di+EDRIVE_INFO.qwTotalSectors+2], dx
+	mov		[di+EDRIVE_INFO.qwTotalSectors+4], bx
 	xor		cx, cx
-	mov		[si+EDRIVE_INFO.qwTotalSectors+6], cx	; Always zero
-	mov		WORD [si+EDRIVE_INFO.wSectorSize], 512
+	mov		[di+EDRIVE_INFO.qwTotalSectors+6], cx	; Always zero
+	mov		WORD [di+EDRIVE_INFO.wSectorSize], 512
 
 	; Store P-CHS. Based on phoenix specification this is returned only if
@@ -114,17 +143,17 @@
 	sbb		bx, cx		; Zero
 	jnc		SHORT .ReturnWithSuccess	; More than EC4000h
-	or		WORD [si+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
-
-	eMOVZX	dx, BYTE [es:di+DPT.bPchsHeads]
-	mov		[si+EDRIVE_INFO.dwHeads], dx
-	mov		[si+EDRIVE_INFO.dwHeads+2], cx
-
-	mov		dl, [es:di+DPT.bPchsSectorsPerTrack]
-	mov		[si+EDRIVE_INFO.dwSectorsPerTrack], dx
-	mov		[si+EDRIVE_INFO.dwSectorsPerTrack+2], cx
-
-	mov		dx, [es:di+DPT.wPchsCylinders]
-	mov		[si+EDRIVE_INFO.dwCylinders], dx
-	mov		[si+EDRIVE_INFO.dwCylinders+2], cx
+	or		WORD [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
+
+	eMOVZX	dx, BYTE [es:si+DPT.bPchsHeads]
+	mov		[di+EDRIVE_INFO.dwHeads], dx
+	mov		[di+EDRIVE_INFO.dwHeads+2], cx
+
+	mov		dl, [es:si+DPT.bPchsSectorsPerTrack]
+	mov		[di+EDRIVE_INFO.dwSectorsPerTrack], dx
+	mov		[di+EDRIVE_INFO.dwSectorsPerTrack+2], cx
+
+	mov		dx, [es:si+DPT.wPchsCylinders]
+	mov		[di+EDRIVE_INFO.dwCylinders], dx
+	mov		[di+EDRIVE_INFO.dwCylinders+2], cx
 
 .ReturnWithSuccess:
@@ -132,2 +161,107 @@
 .ReturnWithError:
 	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+
+
+%ifdef RETURN_DPTE_ON_AH48H
+;--------------------------------------------------------------------
+; CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DPT (in RAMVARS segment)
+;		ES:		RAMVARS segment
+;	Returns:
+;		ES:BX:	Ptr to Device Parameter Table Extension (DPTE)
+;	Corrupts registers:
+;		AX, CX, DX, DI
+;--------------------------------------------------------------------
+CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI:
+	; Point ES:DI to DPTE buffer (valid until next AH=48h call)
+	mov		di, [cs:ROMVARS.bStealSize]
+	eSHL_IM	di, 10							; DI = RAMVARS size in bytes
+	sub		di, BYTE DPTE_size				; DI = Offset to DPTE
+	xor		dx, dx							; Clear for checksum
+
+	; Set 32-bit flag for 32-bit controllers
+	mov		cx, FLG_LBA_TRANSLATION_ENABLED	; DPTE.wFlags
+	cmp		BYTE [si+DPT_ATA.bDevice], DEVICE_32BIT_ATA
+	eCMOVE	cl, FLG_LBA_TRANSLATION_ENABLED | FLG_32BIT_XFER_MODE
+
+	; DPTE.wBasePort
+	mov		ax, [si+DPT.wBasePort]
+	call	StoswThenAddALandAHtoDL			; Bytes 0 and 1
+
+	; DPTE.wControlBlockPort
+	eMOVZX	bx, BYTE [si+DPT.bIdevarsOffset]
+	mov		ax, [cs:bx+IDEVARS.wControlBlockPort]
+	call	StoswThenAddALandAHtoDL			; Bytes 2 and 3
+
+	; DPTE.bDrvnhead and DPTE.bBiosVendor
+	xchg	di, si
+	call	AccessDPT_GetDriveSelectByteForEbiosToAL
+	xchg	si, di
+	call	StoswThenAddALandAHtoDL			; Bytes 4 and 5
+
+	; DPTE.bIRQ and DPTE.bBlockSize
+	mov		al, [cs:bx+IDEVARS.bIRQ]		; No way to define that we might not use IRQ
+	mov		ah, [si+DPT_ATA.bBlockSize]
+	cmp		ah, 1
+	jbe		SHORT .DoNotSetBlockModeFlag
+	or		cl, FLG_BLOCK_MODE_ENABLED
+.DoNotSetBlockModeFlag:
+	call	StoswThenAddALandAHtoDL			; Bytes 6 and 7
+
+	; DPTE.bDmaChannelAndType and DPTE.bPioMode
+	xor		ax, ax
+%ifdef MODULE_ADVANCED_ATA
+	or		ah, [si+DPT_ADVANCED_ATA.bPioMode]
+	jz		SHORT .NoDotSetFastPioFlag
+	cmp		WORD [si+DPT_ADVANCED_ATA.wControllerID], BYTE 0
+	je		SHORT .NoDotSetFastPioFlag
+	inc		cx		; FLG_FAST_PIO_ENABLED
+.NoDotSetFastPioFlag:
+%endif
+	call	StoswThenAddALandAHtoDL			; Bytes 8 and 9
+
+	; Set CHS translation flags and store DPTE.wFlags
+	mov		al, [si+DPT.bFlagsLow]
+	and		al, MASKL_DPT_TRANSLATEMODE
+	jz		SHORT .NoChsTranslationOrBitShiftTranslationSet
+	or		cl, FLG_CHS_TRANSLATION_ENABLED
+	test	al, FLGL_DPT_ASSISTED_LBA
+	jz		SHORT .NoChsTranslationOrBitShiftTranslationSet
+	or		cx, LBA_ASSISTED_TRANSLATION << TRANSLATION_TYPE_FIELD_POSITION
+.NoChsTranslationOrBitShiftTranslationSet:
+	xchg	ax, cx
+	call	StoswThenAddALandAHtoDL			; Bytes 10 and 11
+
+	; DPTE.wReserved (must be zero)
+	xor		ax, ax
+	call	StoswThenAddALandAHtoDL			; Bytes 12 and 13
+
+	; DPTE.bRevision and DPTE.bChecksum
+	mov		ax, DPTE_REVISION | (DPTE_REVISION<<8)
+	add		ah, dl
+	neg		ah
+	stosw
+	lea		bx, [di-DPTE_size]
+	ret
+
+
+;--------------------------------------------------------------------
+; StoswThenAddALandAHtoDL
+;	Parameters:
+;		AX:		WORD to store
+;		ES:DI:	Ptr to where to store AX
+;		DL:		Checksum byte
+;	Returns:
+;		DL:		Checksum byte
+;		DI:		Incremented by 2
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+StoswThenAddALandAHtoDL:
+	stosw
+	add		dl, al
+	add		dl, ah
+	ret
+
+%endif ; RETURN_DPTE_ON_AH48H
