Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 241)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 258)
@@ -63,10 +63,4 @@
 .StoreFlags:
 	mov		[di+DPT.wFlags], ax
-
-%ifdef MODULE_SERIAL
-	cmp		byte [cs:bp+IDEVARS.bDevice], DEVICE_SERIAL_PORT
-	jnz		.StoreAddressing
-	or		byte [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-%endif
 	; Fall to .StoreAddressing
 
@@ -205,4 +199,28 @@
 .StoreDeviceSpecificParameters:
 	call	Device_FinalizeDPT
+
+%ifdef MODULE_SERIAL_FLOPPY
+;
+; These two instructions serve two purposes:
+; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
+; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is 
+;    effectively discarded.  This is more of a safety check then code that should ever normally be hit (see below).
+;    Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT, 
+;    this was necessary.  Now, this situation shouldn't happen in normal operation, for a couple of reasons:
+; 		A. xtidecfg always puts configured serial ports at the end fo the IDEVARS list
+;       B. the auto serial code is always executed last
+;       C. the serial server always returns floppy drives last
+;
+	adc		byte [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
+	jnz		.AllDone	
+%else
+;
+; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
+; could lead to unpredictable results since no MBR will be present, etc.  The server doesn't know that 
+; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
+;
+	jc		.AllDone
+%endif
+
 	; Fall to .StoreDriveNumberAndUpdateDriveCount
 
@@ -230,5 +248,7 @@
 	ja		SHORT .AllDone				;  If so, return
 	mov		[RAMVARS.bFirstDrv], dl		; Store first drive number
+
+.AllDone:
 	clc
-.AllDone:
 	ret
+
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm	(revision 241)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm	(revision 258)
@@ -14,10 +14,14 @@
 ;		DS:DI:	Ptr to first unused DPT
 ;	Corrupts registers:
-;		DL
+;		DX
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 FindDPT_ForNewDriveToDSDI:
-	mov		dl, [RAMVARS.bFirstDrv]
-	add		dl, [RAMVARS.bDrvCnt]
+	mov		ax, [RAMVARS.wDrvCntAndFirst]
+	add		al, ah
+%ifdef MODULE_SERIAL_FLOPPY
+	add		al, [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt]
+%endif
+	xchg	ax, dx		
 	; Fall to FindDPT_ForDriveNumber
 
@@ -41,10 +45,24 @@
 	xchg	di, ax	; Save the contents of AX in DI
 
+%ifdef MODULE_SERIAL_FLOPPY
+	mov		ax, [RAMVARS.wDrvCntAndFirst]
+		
+	test	dl, dl
+	js		.harddisk
+
+	call	RamVars_UnpackFlopCntAndFirstToAL
+	add		dl, ah						; add in end of hard disk DPT list, floppies start immediately after
+.harddisk:
+	sub		dl, al						; subtract off beginning of either hard disk or floppy list (as appropriate)
+%else
+	sub		dl, [RAMVARS.bFirstDrv]		; subtract off beginning of hard disk list
+%endif
+		
 	mov		al, LARGEST_DPT_SIZE
-	sub		dl, [RAMVARS.bFirstDrv]
+		
 	mul		dl
 	add		ax, BYTE RAMVARS_size
 
-	xchg	di, ax	; Restore AX and put result in DI
+	xchg	di, ax						; Restore AX and put result in DI
 	pop		dx
 	ret
@@ -89,9 +107,7 @@
 ; IterateToMasterAtPortCallback
 ;	Parameters:
-;		CH:		Drive number
 ;		DX:		IDE Base Port address
 ;		DS:DI:	Ptr to DPT to examine
 ;	Returns:
-;		DL:		Drive number if correct DPT
 ;		CF:		Set if wanted DPT found
 ;				Cleared if wrong DPT
@@ -116,5 +132,4 @@
 	pop		bx
 	jne		SHORT ReturnWrongDPT
-	mov		dl, ch								; Return drive number in DL
 
 ReturnRightDPT:
@@ -187,4 +202,5 @@
 ;	Returns:
 ;		DS:DI:		Ptr to wanted DPT (if found)
+;					If not found, points to first empty DPT
 ;		CF:			Set if wanted DPT found
 ;					Cleared if DPT not found, or no DPTs present
@@ -195,17 +211,22 @@
 IterateAllDPTs:
 	push	cx
-	mov		cx, [RAMVARS.wDrvCntAndFirst]
+
+	mov		cl, [RAMVARS.bDrvCnt]		
+	mov		ch, 0
+		
+	mov		di, RAMVARS_size			; Point DS:DI to first DPT
+		
 	jcxz	.NotFound					; Return if no drives
-	mov		di, RAMVARS_size			; Point DS:DI to first DPT
+		
 ALIGN JUMP_ALIGN
 .LoopWhileDPTsLeft:
 	call	si							; Is wanted DPT?
 	jc		SHORT .AllDptsIterated		;  If so, return
-	inc		ch							; Increment drive number
 	add		di, BYTE LARGEST_DPT_SIZE	; Point to next DPT
-	dec		cl							; Decrement drives left
-	jnz		SHORT .LoopWhileDPTsLeft
+	loop	.LoopWhileDPTsLeft
+		
 .NotFound:		
 	clc									; Clear CF since DPT not found
+		
 ALIGN JUMP_ALIGN
 .AllDptsIterated:
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/RamVars.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/RamVars.asm	(revision 241)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/RamVars.asm	(revision 258)
@@ -123,6 +123,6 @@
 ;		DS:		RAMVARS segment
 ;	Returns:
-;		CF:		Set if function is handled by this BIOS
-;				Cleared if function belongs to some other BIOS
+;		CF:		Cleared if function is handled by this BIOS
+;				Set if function belongs to some other BIOS
 ;	Corrupts registers:
 ;		Nothing
@@ -131,15 +131,15 @@
 RamVars_IsFunctionHandledByThisBIOS:
 	test	ah, ah			; Reset for all floppy and hard disk drives?
-	jz		SHORT .FunctionIsHandledByOurBIOS
-	cmp		ah, 08h			; Read Disk Drive Parameters?
-	jne		SHORT RamVars_IsDriveHandledByThisBIOS
-	test	dl, dl			; We do not handle floppy drives
-	jns		SHORT .FunctionIsNotHandledByOurBIOS
-ALIGN JUMP_ALIGN
-.FunctionIsHandledByOurBIOS:
-	stc
-.FunctionIsNotHandledByOurBIOS:
-	ret
-
+	jz		SHORT RamVars_IsDriveHandledByThisBIOS.CFAlreadyClear_IsHandledByOurBIOS
+	cmp		ah, 08h
+%ifdef MODULE_SERIAL_FLOPPY
+; we handle all traffic for function 08h, as we need to wrap both hard disk and floppy drive counts
+	je		SHORT RamVars_IsDriveHandledByThisBIOS.CFAlreadyClear_IsHandledByOurBIOS
+%else
+; we handle all *hard disk* traffic for function 08h, as we need to wrap the hard disk drive count
+	je		SHORT RamVars_IsDriveHandledByThisBIOS.IsDriveAHardDisk
+%endif
+;;; fall-through			
+		
 ;--------------------------------------------------------------------
 ; Checks if drive is handled by this BIOS.
@@ -150,6 +150,6 @@
 ;		DS:		RAMVARS segment
 ;	Returns:
-;		CF:		Set if drive is handled by this BIOS
-;				Cleared if drive belongs to some other BIOS
+;		CF:		Cleared if drive is handled by this BIOS
+;				Set if drive belongs to some other BIOS
 ;	Corrupts registers:
 ;		Nothing
@@ -158,56 +158,82 @@
 RamVars_IsDriveHandledByThisBIOS:
 	push	ax
-	mov		ax, [RAMVARS.wDrvCntAndFirst]		; Drive count to AL, First number to AH
-	add		al, ah								; One past last drive to AL
-	cmp		dl, al								; Above last supported?
-	jae		SHORT .DriveNotHandledByThisBIOS
-	cmp		ah, dl								; Below first supported?
-	ja		SHORT .DriveNotHandledByThisBIOS
-	stc
-.DriveNotHandledByThisBIOS:
+
+	mov		ax, [RAMVARS.wDrvCntAndFirst]		; Drive count to AH, First number to AL
+	add		ah, al								; One past last drive to AH
+	cmp		dl, ah								; Above last supported?
+	jae		SHORT .HardDiskIsNotHandledByThisBIOS
+.TestLowLimit:
+	cmp		dl, al								; Below first supported?
+	jae		SHORT .CFAlreadyClear_IsHandledByOurBIOS_PopAX	; note that CF is clear if the branch is taken
+
+.HardDiskIsNotHandledByThisBIOS:
+%ifdef MODULE_SERIAL_FLOPPY
+	call	RamVars_UnpackFlopCntAndFirstToAL
+	cbw											; normally 0h, could be ffh if no drives present
+	adc		ah, al								; if no drives present, still ffh (ffh + ffh + 1 = ffh)
+	js		SHORT .DiskIsNotHandledByThisBIOS
+	cmp		ah, dl
+	jz		SHORT .CFAlreadyClear_IsHandledByOurBIOS_PopAX
+	cmp		al, dl
+	jz		SHORT .CFAlreadyClear_IsHandledByOurBIOS_PopAX
+.DiskIsNotHandledByThisBIOS:			
+%endif
+
+	stc											; Is not supported by our BIOS
+		
+.CFAlreadyClear_IsHandledByOurBIOS_PopAX:				
 	pop		ax
-	ret
-
-
-;--------------------------------------------------------------------
-; RamVars_GetHardDiskCountFromBDAtoCX
-;	Parameters:
-;		DS:		RAMVARS segment
-;	Returns:
-;		CX:		Total hard disk count
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-RamVars_GetHardDiskCountFromBDAtoCX:
+.CFAlreadyClear_IsHandledByOurBIOS:	
+	ret
+
+%ifndef MODULE_SERIAL_FLOPPY		
+;
+; Note that we could have just checked for the high order bit in dl, but with the needed STC and jumps, 
+; leveraging the code above resulted in space savings.
+;
+.IsDriveAHardDisk:		
+	push	ax									; match stack at the top of routine
+	mov		al, 80h								; to catch all hard disks, lower limit is 80h vs. bFirstDrv
+	jmp		.TestLowLimit						; and there is no need to test a high limit
+%endif
+
+;--------------------------------------------------------------------
+; RamVars_GetHardDiskCountFromBDAtoAX
+;	Parameters:
+;		DS:		RAMVARS segment
+;	Returns:
+;		AX:		Total hard disk count
+;	Corrupts registers:
+;		CX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RamVars_GetHardDiskCountFromBDAtoAX:
 	push	es
-	push	dx
-
-	LOAD_BDA_SEGMENT_TO	es, cx, !		; Zero CX
-	call	RamVars_GetCountOfKnownDrivesToDL
+
+	LOAD_BDA_SEGMENT_TO	es, ax
+	call	RamVars_GetCountOfKnownDrivesToAX
 	mov		cl, [es:BDA.bHDCount]
-	MAX_U	cl, dl
-
-	pop		dx
+	MAX_U	al, cl
+		
 	pop		es
 	ret
 
 ;--------------------------------------------------------------------
-; RamVars_GetCountOfKnownDrivesToDL
-;	Parameters:
-;		DS:		RAMVARS segment
-;	Returns:
-;		DL:		Total hard disk count
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-RamVars_GetCountOfKnownDrivesToDL:
-	mov		dl, [RAMVARS.bFirstDrv]		; Number for our first drive
-	add		dl, [RAMVARS.bDrvCnt]		; Our drives
-	and		dl, 7Fh						; Clear HD bit for drive count
-	ret
-
-
+; RamVars_GetCountOfKnownDrivesToAX
+;	Parameters:
+;		DS:		RAMVARS segment
+;	Returns:
+;		AX:		Total hard disk count
+;	Corrupts registers:
+;		None
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RamVars_GetCountOfKnownDrivesToAX:
+	mov		ax, [RAMVARS.wDrvCntAndFirst]
+	add		al, ah
+	and		al, 7fh
+	cbw
+	ret
+	
 ;--------------------------------------------------------------------
 ; RamVars_GetIdeControllerCountToCX
@@ -219,5 +245,24 @@
 ;		Nothing
 ;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
 RamVars_GetIdeControllerCountToCX:
 	eMOVZX	cx, BYTE [cs:ROMVARS.bIdeCnt]
 	ret
+
+%ifdef MODULE_SERIAL_FLOPPY
+;--------------------------------------------------------------------
+; RamVars_UnpackFlopCntAndFirstToAL
+;	Parameters:
+;		Nothing
+;	Returns:
+;		AL:		First floppy drive number supported
+;       CF:		Number of floppy drives supported (clear = 1, set = 2)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------		
+ALIGN JUMP_ALIGN
+RamVars_UnpackFlopCntAndFirstToAL:
+	mov		al, [RAMVARS.xlateVars+XLATEVARS.bFlopCntAndFirst]
+	sar		al, 1		
+	ret
+%endif
