Index: trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenu.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenu.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenu.asm	(revision 258)
@@ -37,5 +37,5 @@
 ;               Clear: There is no selected menu item, DL is not valid
 ;	Corrupts registers:
-;		CX, DI
+;		AX, DI
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
@@ -50,11 +50,11 @@
 
 	mov		dl, cl							; Copy menuitem index to DX
-	call	FloppyDrive_GetCountToCX
-	cmp		dl, cl							; Floppy drive?
+	call	FloppyDrive_GetCountToAX
+	cmp		dl, al							; Floppy drive?
 	jb		SHORT .ReturnFloppyDriveInDX	; Set CF if branch taken
-	or		cl, 80h							; Or 80h into CL before the sub
+	or		al, 80h							; Or 80h into AL before the sub
 											; to cause CF to be set after
 											; and result has high order bit set
-	sub		dl, cl							; Remove floppy drives from index
+	sub		dl, al							; Remove floppy drives from index
 
 .ReturnFloppyDriveInDX:
@@ -94,7 +94,7 @@
 ALIGN JUMP_ALIGN
 BootMenu_GetMenuitemCountToAX:
-	call	RamVars_GetHardDiskCountFromBDAtoCX
+	call	RamVars_GetHardDiskCountFromBDAtoAX
 	xchg	ax, cx
-	call	FloppyDrive_GetCountToCX
+	call	FloppyDrive_GetCountToAX
 	add		ax, cx
 	ret
@@ -136,15 +136,18 @@
 BootMenu_GetMenuitemToAXforAsciiHotkeyInAL:
 	call	Char_ALtoUpperCaseLetter
-	call	BootMenu_GetLetterForFirstHardDiskToCL
 	xor		ah, ah
-	cmp		al, cl						; Letter is for Hard Disk?
+	xchg	ax, cx
+	call	BootMenu_GetLetterForFirstHardDiskToAL
+	cmp		cl, al						; Letter is for Hard Disk?
 	jae		SHORT .StartFromHardDiskLetter
+	xchg	ax, cx
 	sub		al, 'A'						; Letter to Floppy Drive menuitem
 	ret
 ALIGN JUMP_ALIGN
 .StartFromHardDiskLetter:
-	sub		al, cl						; Hard Disk index
-	call	FloppyDrive_GetCountToCX
+	sub		cl, al						; Hard Disk index
+	call	FloppyDrive_GetCountToAX
 	add		ax, cx						; Menuitem index
+										; Note: no need to xchg ax, cx as above, since adding with result to ax
 	ret
 
@@ -160,13 +163,13 @@
 ;		CL:		Upper case letter for first hard disk
 ;	Corrupts registers:
-;		CH
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-BootMenu_GetLetterForFirstHardDiskToCL:
-	call	FloppyDrive_GetCountToCX
-	add		cl, 'A'
-	cmp		cl, 'C'
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+BootMenu_GetLetterForFirstHardDiskToAL:
+	call	FloppyDrive_GetCountToAX
+	add		al, 'A'
+	cmp		al, 'C'
 	ja		.Return
-	mov		cl, 'C'
+	mov		al, 'C'
 ALIGN JUMP_ALIGN, ret
 .Return:
@@ -181,5 +184,5 @@
 ;		DX:		Menuitem index (assuming drive is available)
 ;	Corrupts registers:
-;		Nothing
+;		AX
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
@@ -188,7 +191,7 @@
 	test	dl, dl
 	jns		SHORT .ReturnItemIndexInDX	; Return if floppy drive (HD bit not set)
-	call	FloppyDrive_GetCountToCX
+	call	FloppyDrive_GetCountToAX
 	and		dl, ~80h					; Clear HD bit
-	add		dx, cx
+	add		dx, ax
 .ReturnItemIndexInDX:
 	ret
@@ -212,10 +215,10 @@
 	test	dl, dl								; Floppy drive?
 	jns		SHORT .IsFloppyDriveInSystem
-	call	RamVars_GetHardDiskCountFromBDAtoCX	; Hard Disk count to CX
-	or		cl, 80h								; Set Hard Disk bit to CX
+	call	RamVars_GetHardDiskCountFromBDAtoAX	; Hard Disk count to AX
+	or		al, 80h								; Set Hard Disk bit to AX
 	jmp		SHORT .CompareDriveNumberToDriveCount
 .IsFloppyDriveInSystem:
-	call	FloppyDrive_GetCountToCX
+	call	FloppyDrive_GetCountToAX
 .CompareDriveNumberToDriveCount:
-	cmp		dl, cl								; Set CF when DL is smaller
-	ret
+	cmp		dl, al								; Set CF when DL is smaller
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuEvent.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuEvent.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuEvent.asm	(revision 258)
@@ -21,15 +21,15 @@
 %ifdef MENUEVENT_INLINE_OFFSETS
 
-	add		bx, BootMenuEvent_Handler
+	add		bx, BootMenuEvent_Handler.FirstEvent
 	jmp		bx
 
-MENUEVENT_InitializeMenuinitFromDSSI equ  (BootMenuEvent_Handler.InitializeMenuinitFromDSSI - BootMenuEvent_Handler)
-MENUEVENT_ExitMenu equ  (BootMenuEvent_EventCompleted - BootMenuEvent_Handler)
-MENUEVENT_ItemHighlightedFromCX equ (BootMenuEvent_Handler.ItemHighlightedFromCX - BootMenuEvent_Handler)
-MENUEVENT_ItemSelectedFromCX equ (BootMenuEvent_Handler.ItemSelectedFromCX - BootMenuEvent_Handler)
-MENUEVENT_KeyStrokeInAX equ (BootMenuEvent_Handler.KeyStrokeInAX - BootMenuEvent_Handler)
-MENUEVENT_RefreshTitle equ (BootMenuPrint_TitleStrings - BootMenuEvent_Handler)
-MENUEVENT_RefreshInformation equ (BootMenuPrint_RefreshInformation - BootMenuEvent_Handler)
-MENUEVENT_RefreshItemFromCX equ (BootMenuPrint_RefreshItem - BootMenuEvent_Handler)
+MENUEVENT_InitializeMenuinitFromDSSI equ  (BootMenuEvent_Handler.InitializeMenuinitFromDSSI - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_ExitMenu equ  (BootMenuEvent_EventCompleted - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_ItemHighlightedFromCX equ (BootMenuEvent_Handler.ItemHighlightedFromCX - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_ItemSelectedFromCX equ (BootMenuEvent_Handler.ItemSelectedFromCX - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_KeyStrokeInAX equ (BootMenuEvent_Handler.KeyStrokeInAX - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_RefreshTitle equ (BootMenuPrint_TitleStrings - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_RefreshInformation equ (BootMenuPrint_RefreshInformation - BootMenuEvent_Handler.FirstEvent)
+MENUEVENT_RefreshItemFromCX equ (BootMenuPrint_RefreshItem - BootMenuEvent_Handler.FirstEvent)
 ;
 ; Note that there is no entry for MENUEVENT_IdleProcessing.  If MENUEVENT_IDLEPROCESSING_ENABLE is not %defined,
@@ -67,4 +67,5 @@
 ;	DS:SI:		Ptr to initialized MENUINIT struct
 ALIGN JUMP_ALIGN
+.FirstEvent:	
 .InitializeMenuinitFromDSSI:
 	push	ds
Index: trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuPrint.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuPrint.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuPrint.asm	(revision 258)
@@ -24,5 +24,5 @@
 
 	call	RamVars_IsDriveHandledByThisBIOS				
-	jnc		.notOurs
+	jc		.notOurs
 
 	call	FindDPT_ForDriveNumber					; if it is one of ours, print the string in bootnfo
@@ -47,5 +47,5 @@
 	push	ax										; the hard disks don't ever use it, but it does no harm)
 		
-	jmp		short BootMenuPrint_FormatCSSIfromParamsInSSBP
+	jmp		short BootMenuPrint_RefreshInformation.FormatRelay
 
 ;--------------------------------------------------------------------
@@ -87,5 +87,5 @@
 	push	bp
 	mov		bp,sp
-	jmp		short BootMenuPrint_FormatCSSIfromParamsInSSBP
+	jmp		short BootMenuPrint_RefreshInformation.FormatRelay
 
 		
@@ -110,11 +110,25 @@
 	mov		bp, sp
 
+	mov		si, g_szCapacity							; Setup print string now, carries through to print call
+
+	xor		di, di
+	call	RamVars_IsDriveHandledByThisBIOS
+	jc		SHORT .notours
+	call	FindDPT_ForDriveNumber						; DS:DI to point DPT
+.notours:		
+		
 	test	dl, dl										; are we a hard disk?
 	js		BootMenuPrint_HardDiskRefreshInformation		
-		
+
+	test	di,di
+	jnz		.ours
 	call	FloppyDrive_GetType							; Get Floppy Drive type to BX
+	jmp		.around
+.ours:
+	call	AH8h_GetDriveParameters
+.around:				
 
 	mov		ax, g_szFddSizeOr	        				; .PrintXTFloppyType
-	test	bx, bx										; Two possibilities? (FLOPPY_TYPE_525_OR_35_DD)		
+	test	bl, bl										; Two possibilities? (FLOPPY_TYPE_525_OR_35_DD)		
 	jz		SHORT .PushAXAndOutput
 
@@ -158,4 +172,5 @@
 
 	mov		al,FloppyTypes.rgbCapacityMultiplier
+	mov		bh, 0
 	mul		byte [cs:bx+FloppyTypes.rgbCapacity - 1]    ; -1 since 0 is handled above and not in the table
 
@@ -163,5 +178,6 @@
 	push	ax
 
-	jmp		short BootMenuPrint_HardDiskRefreshInformation.output
+.FormatRelay:
+	jmp		short BootMenuPrint_FormatCSSIfromParamsInSSBP
 
 
@@ -180,19 +196,7 @@
 ALIGN JUMP_ALIGN
 BootMenuPrint_HardDiskRefreshInformation:		
-	call	RamVars_IsDriveHandledByThisBIOS
-	jnc		SHORT .HardDiskMenuitemInfoForForeignDrive
-	call	FindDPT_ForDriveNumber						; DS:DI to point DPT
-	; Fall to .HardDiskMenuitemInfoForOurDrive
-
-;--------------------------------------------------------------------
-; .HardDiskMenuitemInfoForOurDrive
-;	Parameters:
-;		DL:		Untranslated Hard Disk number
-;		DS:DI:	Ptr to DPT
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AX, BX, CX, DX, SI, DI, ES
-;--------------------------------------------------------------------
+	test	di,di
+	jz		.HardDiskMenuitemInfoForForeignDrive		
+
 .HardDiskMenuitemInfoForOurDrive:
 	ePUSH_T	ax, g_szInformation
@@ -200,27 +204,26 @@
 	; Get and push total LBA size
 	call	BootMenuInfo_GetTotalSectorCount
-	call	ConvertSectorCountInBXDXAXtoSizeAndPushForFormat		
-	jmp		BootMenuPrintCfg_ForOurDrive
-
-;--------------------------------------------------------------------
-; .HardDiskMenuitemInfoForForeignDrive
-;	Parameters:
-;		DL:		Untranslated Hard Disk number
-;		DS:		RAMVARS segment
-;	Returns:
-;		CF:		Set since menu event was handled successfully
-;	Corrupts registers:
-;		AX, BX, CX, DX, SI, DI
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
+	jmp		.ConvertSectorCountInBXDXAXtoSizeAndPushForFormat
+		
 .HardDiskMenuitemInfoForForeignDrive:
 	call	DriveXlate_ToOrBack
 	call	AH15h_GetSectorCountFromForeignDriveToDXAX
-	call	ConvertSectorCountInBXDXAXtoSizeAndPushForFormat
-
-ALIGN JUMP_ALIGN		
-.output:
-	mov		si, g_szCapacity
-;;; fall-through
+
+.ConvertSectorCountInBXDXAXtoSizeAndPushForFormat:
+	ePUSH_T	cx, g_szCapacityNum		; Push format substring
+	call	Size_ConvertSectorCountInBXDXAXtoKiB
+	mov		cx, BYTE_MULTIPLES.kiB
+	call	Size_GetSizeToAXAndCharToDLfromBXDXAXwithMagnitudeInCX
+	push	ax						; Size in magnitude
+	push	cx						; Tenths
+	push	dx						; Magnitude character		
+				
+	test	di,di
+	jz		short BootMenuPrint_FormatCSSIfromParamsInSSBP
+
+%include "BootMenuPrintCfg.asm"			; inline of code to fill out remainder of information string
+
+;;; fall-through to BootMenuPrint_FormatCSSIfromParamsInSSBP
+
 
 ;--------------------------------------------------------------------
@@ -273,8 +276,8 @@
 ALIGN JUMP_ALIGN
 BootMenuPrint_TheBottomOfScreen:
-	call	FloppyDrive_GetCountToCX
-	mov		bl, cl					; Floppy Drive count to BL
-	call	RamVars_GetHardDiskCountFromBDAtoCX
-	mov		bh, cl					; Hard Disk count to BH
+	call	FloppyDrive_GetCountToAX
+	xchg	bx, ax					; Floppy Drive count to BL
+	call	RamVars_GetHardDiskCountFromBDAtoAX
+	mov		bh, al					; Hard Disk count to BH
 	; Fall to .MoveCursorToHotkeyStrings
 
@@ -321,8 +324,6 @@
 	test	bh, bh		; Any Hard Drives?
 	jz		SHORT .SkipHardDriveHotkeys
-	xchg	ax, cx		; Store Key Attribute
-	call	BootMenu_GetLetterForFirstHardDiskToCL
-	mov		ch, ANGLE_QUOTE_RIGHT
-	xchg	ax, cx
+	call	BootMenu_GetLetterForFirstHardDiskToAL
+	mov		ah, ANGLE_QUOTE_RIGHT
 	mov		si, g_szHDD
 	call	PushHotkeyParamsAndFormat
@@ -390,26 +391,4 @@
 	CALL_DISPLAY_LIBRARY InitializeDisplayContext
 	ret
-
-
-;--------------------------------------------------------------------
-; ConvertSectorCountInBXDXAXtoSizeAndPushForFormat
-;	Parameters:
-;		BX:DX:AX:	Sector count
-;	Returns:
-;		Size in stack
-;	Corrupts registers:
-;		AX, BX, CX, DX, SI
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-ConvertSectorCountInBXDXAXtoSizeAndPushForFormat:
-	pop		si						; Pop return address
-	ePUSH_T	cx, g_szCapacityNum		; Push format substring
-	call	Size_ConvertSectorCountInBXDXAXtoKiB
-	mov		cx, BYTE_MULTIPLES.kiB
-	call	Size_GetSizeToAXAndCharToDLfromBXDXAXwithMagnitudeInCX
-	push	ax						; Size in magnitude
-	push	cx						; Tenths
-	push	dx						; Magnitude character
-	jmp		si
 
 
Index: trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuPrintCfg.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuPrintCfg.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuPrintCfg.asm	(revision 258)
@@ -2,7 +2,12 @@
 ; Description	:	Functions for printing drive configuration
 ;					information on Boot Menu.
-
+;
+; Included by BootMenuPrint.asm, this routine is to be inserted into
+; BootMenuPrint_HardDiskRefreshInformation.
+;
 ; Section containing code
 SECTION .text
+
+;;; fall-into from BootMenuPrint_HardDiskRefreshInformation.
 
 ;--------------------------------------------------------------------
@@ -16,10 +21,9 @@
 ;		Nothing
 ;	Corrupts registers:
-;		AX, BX, CX, DX, SI, DI
+;		AX, BX, CX, DX
 ;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-BootMenuPrintCfg_ForOurDrive:
+.BootMenuPrintCfg_ForOurDrive:
 	eMOVZX	ax, BYTE [di+DPT.bIdevarsOffset]
-	xchg	si, ax						; CS:SI now points to IDEVARS
+	xchg	bx, ax						; CS:BX now points to IDEVARS
 	; Fall to .PushAndFormatCfgString
 
@@ -28,9 +32,9 @@
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
-;		CS:SI:	Ptr to IDEVARS
+;		CS:BX:	Ptr to IDEVARS
 ;	Returns:
 ;		Nothing (jumps to next push below)
 ;	Corrupts registers:
-;		AX, BX
+;		AX, CX
 ;--------------------------------------------------------------------
 .PushAddressingMode:
@@ -41,6 +45,6 @@
 	;; with AL clear, and so we exchange AL and AH after the multiply for the final result.
 	;; 
-	mov		bl,(1<<(8-ADDRESSING_MODE_FIELD_POSITION)) * g_szAddressingModes_Displacement
-	mul		bl
+	mov		cl,(1<<(8-ADDRESSING_MODE_FIELD_POSITION)) * g_szAddressingModes_Displacement
+	mul		cl
 	xchg	al,ah
 	add		ax,g_szAddressingModes
@@ -51,5 +55,5 @@
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
-;		CS:SI:	Ptr to IDEVARS
+;		CS:BX:	Ptr to IDEVARS
 ;	Returns:
 ;		Nothing (falls to next push below)
@@ -69,5 +73,5 @@
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
-;		CS:SI:	Ptr to IDEVARS
+;		CS:BX:	Ptr to IDEVARS
 ;	Returns:
 ;		Nothing (jumps to next push below)
@@ -77,5 +81,5 @@
 .PushBusType:
 	mov		al,g_szBusTypeValues_Displacement
-	mul		BYTE [cs:si+IDEVARS.bDevice]
+	mul		BYTE [cs:bx+IDEVARS.bDevice]
 		
 	shr		ax,1			; divide by 2 since IDEVARS.bDevice is multiplied by 2
@@ -88,5 +92,5 @@
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
-;		CS:SI:	Ptr to IDEVARS
+;		CS:BX:	Ptr to IDEVARS
 ;	Returns:
 ;		Nothing (falls to next push below)
@@ -95,5 +99,5 @@
 ;--------------------------------------------------------------------
 .PushIRQ:
-	mov		al, BYTE [cs:si+IDEVARS.bIRQ]
+	mov		al, BYTE [cs:bx+IDEVARS.bIRQ]
 	cbw
 	push	ax
@@ -103,5 +107,5 @@
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
-;		CS:SI:	Ptr to IDEVARS
+;		CS:BX:	Ptr to IDEVARS
 ;	Returns:
 ;		Nothing (falls to next push below)
@@ -114,14 +118,3 @@
 	push	ax
 
-;--------------------------------------------------------------------
-; PrintValuesFromStack
-;	Parameters:
-;		Stack:	All formatting parameters
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AX, SI, DI
-;--------------------------------------------------------------------
-.PrintValuesFromStack:
-	jmp		BootMenuPrint_HardDiskRefreshInformation.output
-
+;;; fall-out to BootMenuPrint_HardDiskRefreshInformation.
Index: trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 258)
@@ -37,7 +37,8 @@
 %ifdef MODULE_SERIAL
 Device_FinalizeDPT:
-	TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE .FinalizeDptForSerialPortDevice
+	; needs to check IDEVARS vs. checking the DPT as the serial bit in the DPT is set in the Finalize routine
+	CMP_USING_IDEVARS_IN_CSBP_AND_JUMP_IF DEVICE_SERIAL_PORT, .FinalizeDptForSerialPortDevice
 	jmp		IdeDPT_Finalize
-.FinalizeDptForSerialPortDevice:
+.FinalizeDptForSerialPortDevice: 
 	jmp		SerialDPT_Finalize
 
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 258)
@@ -12,5 +12,5 @@
 ;		CS:BP:	Ptr to IDEVARS for the controller
 ;	Returns:
-;		Nothing
+;		CF:		Clear, IDE interface only supports hard disks
 ;	Corrupts registers:
 ;		AX
@@ -42,5 +42,5 @@
 ;		CS:BP:	Ptr to IDEVARS for the controller
 ;	Returns:
-;		Nothing
+;		CF:		Always clear, we don't support floppies on the IDE inteface
 ;	Corrupts registers:
 ;		Nothing
@@ -52,3 +52,4 @@
 
 .EndDPT:
+	clc
 	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm	(revision 258)
@@ -56,4 +56,5 @@
 ;	Returns:
 ;		AH:		INT 13h Error Code
+;		CX:		Number of successfully transferred sectors (for transfer commands)
 ;		CF:		Cleared if success, Set if error
 ;	Corrupts registers:
@@ -309,5 +310,5 @@
 		dec		al				; decrement sector count
 		push	ax				; save
-		jz		SerialCommand_OutputWithParameters_ReturnCodeInALCF    ; CF=0 from "cmp ax,bp" returning Zero above
+		jz		SerialCommand_OutputWithParameters_ReturnCodeInAL
 
 		cli						; interrupts back off for ACK byte to host
@@ -409,19 +410,24 @@
 
 .clearBufferComplete:
-		stc
-		mov		al,1
-
-ALIGN JUMP_ALIGN
-SerialCommand_OutputWithParameters_ReturnCodeInALCF:
+		mov		al, 3			;  error return code and CF (low order bit)
+
+ALIGN JUMP_ALIGN
+SerialCommand_OutputWithParameters_ReturnCodeInAL:
 %if 0
 		sti						;  all paths here will already have interrupts turned back on
 %endif
-		mov		ah,al
-
-		pop		bp				;  recover ax (command and count) from stack, throw away
+		mov		ah, al			;  for success, AL will already be zero
+
+		pop		bx				;  recover "ax" (command and count) from stack
 
 		pop		bp
 		pop		di
 		pop		si
+
+		mov		ch, 0
+		mov		cl,[bp+IDEPACK.bSectorCount]
+		sub		cl, bl			; subtract off the number of sectors that remained
+		
+		shr		ah, 1			; shift down return code and CF
 
 		ret
@@ -632,5 +638,15 @@
 		call	FindDPT_ToDSDIforSerialDevice
 		pop		si
+%ifdef MODULE_SERIAL_FLOPPY
+		jc		.founddpt
+;
+; If not found above with FindDPT_ToDSDIforSerialDevice, DI will point to the DPT after the last hard disk DPT
+;
+		cmp		byte [RAMVARS.xlateVars+XLATEVARS.bFlopCntAndFirst], 0
+		jz		.notfounddpt
+.founddpt:
+%else
 		jnc		.notfounddpt
+%endif
 		mov		ax, [di+DPT_SERIAL.wSerialPortAndBaud]
 .notfounddpt:
@@ -678,5 +694,5 @@
 ; which is read by FinalizeDPT and DetectDrives
 ;
-		mov		[es:si+ATA6.wVendor],dx
+		mov		[es:si+ATA6.wSerialPortAndBaud],dx
 
 .notFound:
Index: trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm	(revision 258)
@@ -11,12 +11,27 @@
 ;		ES:SI:	Ptr to 512-byte ATA information read from the drive
 ;	Returns:
-;		Nothing
+;		CF:		Set, indicates that this is a floppy disk
+;               Clear, indicates that this is a hard disk
 ;	Corrupts registers:
 ;		AX
 ;--------------------------------------------------------------------
 SerialDPT_Finalize:
-		or		byte [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-		mov		ax, [es:si+ATA6.wVendor]
+		mov		ax, [es:si+ATA6.wSerialPortAndBaud]
 		mov		[di+DPT_SERIAL.wSerialPortAndBaud], ax
+
+;
+; Note that this section is not under %ifdef MODULE_SERIAL_FLOPPY.  It is important to 
+; detect floppy disks presented by the server and not treat them like hard disks, even
+; if the floppy support is disabled.
+;
+		mov		al, [es:si+ATA6.wSerialFloppyFlagAndType]
+		or		al, FLGH_DPT_SERIAL_DEVICE
+		or		byte [di+DPT.bFlagsHigh], al
+
+		test	al, FLGH_DPT_SERIAL_FLOPPY           ; clears CF
+		jz		.notfloppy
+		stc		
+.notfloppy:		
+		
 		ret
 
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 258)
@@ -29,5 +29,6 @@
 	mov		[RAMVARS.xlateVars+XLATEVARS.bXlatedDrv], dl
 	call	RamVars_IsFunctionHandledByThisBIOS
-	jnc		SHORT Int13h_DirectCallToAnotherBios
+	jc		SHORT Int13h_DirectCallToAnotherBios
+
 	call	FindDPT_ForDriveNumber		; DS:DI now points to DPT
 
@@ -139,5 +140,11 @@
 ALIGN JUMP_ALIGN
 Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH:
+%ifdef MODULE_SERIAL_FLOPPY
+	mov		al, [bp+IDEPACK.intpack+INTPACK.dl]
+Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH_ALHasDriveNumber:	
+	call	Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH_ALHasDriveNumber
+%else
 	call	Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH
+%endif
 Int13h_ReturnFromHandlerWithoutStoringErrorCode:
 	or		WORD [bp+IDEPACK.intpack+INTPACK.flags], FLG_FLAGS_IF	; Return with interrupts enabled
@@ -154,16 +161,14 @@
 ;	Returns:
 ;		Depends on function
+;       NOTE: ES:DI needs to be returned from the previous interrupt 
+;		      handler, for floppy DPT in function 08h
 ;	Corrupts registers:
-;		BX, DI, ES
+;		None
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 Int13h_CallPreviousInt13hHandler:
-	push	di
 	call	ExchangeCurrentInt13hHandlerWithOldInt13hHandler
 	int		BIOS_DISK_INTERRUPT_13h
-	call	ExchangeCurrentInt13hHandlerWithOldInt13hHandler
-	pop		di
-	ret
-
+;;;  fall-through to ExchangeCurrentInt13hHandlerWithOldInt13hHandler
 
 ;--------------------------------------------------------------------
@@ -174,18 +179,21 @@
 ;		Nothing
 ;	Corrupts registers:
-;		DI
+;       Nothing
+;       Note: Flags are preserved
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 ExchangeCurrentInt13hHandlerWithOldInt13hHandler:
 	push	es
-	LOAD_BDA_SEGMENT_TO	es, di
-	mov		di, [RAMVARS.fpOldI13h]
+	push	si
+	LOAD_BDA_SEGMENT_PRESERVE_FLAGS_TO	es, si
+	mov		si, [RAMVARS.fpOldI13h]
 	cli
-	xchg	di, [es:BIOS_DISK_INTERRUPT_13h*4]
-	mov		[RAMVARS.fpOldI13h], di
-	mov		di, [RAMVARS.fpOldI13h+2]
-	xchg	di, [es:BIOS_DISK_INTERRUPT_13h*4+2]
+	xchg	si, [es:BIOS_DISK_INTERRUPT_13h*4]
+	mov		[RAMVARS.fpOldI13h], si
+	mov		si, [RAMVARS.fpOldI13h+2]
+	xchg	si, [es:BIOS_DISK_INTERRUPT_13h*4+2]
 	sti
-	mov		[RAMVARS.fpOldI13h+2], di
+	mov		[RAMVARS.fpOldI13h+2], si
+	pop		si
 	pop		es
 	ret
@@ -204,8 +212,20 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
+%ifdef MODULE_SERIAL_FLOPPY
+Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH_ALHasDriveNumber:
+	; Store error code to BDA
+	mov		bx, BDA.bHDLastSt
+	test	al, al
+	js		.HardDisk
+	mov		bl, BDA.bFDRetST & 0xff
+.HardDisk:
+	LOAD_BDA_SEGMENT_TO	ds, di
+	mov		[bx], ah		
+%else
 Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH:
 	; Store error code to BDA
-	LOAD_BDA_SEGMENT_TO	ds, di
+	LOAD_BDA_SEGMENT_TO	ds, di		
 	mov		[BDA.bHDLastSt], ah
+%endif
 
 	; Store error code to INTPACK
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm	(revision 258)
@@ -22,6 +22,4 @@
 	eMOVZX	bx, dl						; Copy requested drive to BL, zero BH to assume no errors
 	call	ResetFloppyDrivesWithInt40h
-	test	bl, bl
-	jns		SHORT .SkipHardDiskReset
 	call	ResetForeignHardDisks
 	call	AH0h_ResetHardDisksHandledByOurBIOS
@@ -64,6 +62,24 @@
 	xor		ah, ah						; Disk Controller Reset
 	call	Int13h_CallPreviousInt13hHandler
-	jmp		SHORT BackupErrorCodeFromTheRequestedDriveToBH
-
+;;; fall-through to BackupErrorCodeFromTheRequestedDriveToBH
+
+
+;--------------------------------------------------------------------
+; BackupErrorCodeFromTheRequestedDriveToBH
+;	Parameters:
+;		AH:		Error code from the last resetted drive
+;		DL:		Drive last resetted
+;		BL:		Requested drive (DL when entering AH=00h)
+;	Returns:
+;		BH:		Backuped error code
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+BackupErrorCodeFromTheRequestedDriveToBH:
+	cmp		dl, bl				; Requested drive?
+	eCMOVE	bh, ah
+	ret
+		
 
 ;--------------------------------------------------------------------
@@ -82,5 +98,5 @@
 	mov		dl, bl
 	call	RamVars_IsDriveHandledByThisBIOS
-	jnc		SHORT .Return				; Return what was in BL unmodified
+	jc		SHORT .Return				; Return what was in BL unmodified
 	mov		dl, 80h
 .Return:
@@ -101,8 +117,7 @@
 ALIGN JUMP_ALIGN
 AH0h_ResetHardDisksHandledByOurBIOS:
-	mov		dh, [RAMVARS.bDrvCnt]		; Load drive count to DH
+	mov		dx, [RAMVARS.wDrvCntAndFirst]	; DL = drive number, DH = drive count
 	test	dh, dh
 	jz		SHORT .AllDrivesReset		; Return if no drives
-	mov		dl, [RAMVARS.bFirstDrv]		; Load number of our first drive
 	add		dh, dl						; DH = one past last drive to reset
 ALIGN JUMP_ALIGN
@@ -114,6 +129,27 @@
 	jb		SHORT .DriveResetLoop		;  If not, reset next drive
 .AllDrivesReset:
-	ret
-
+%ifdef MODULE_SERIAL_FLOPPY
+;
+; "Reset" emulatd serial floppy drives, if any.  There is nothing to actually do for this reset,
+; but record the proper error return code if one of these floppy drives is the drive requested.
+;
+	call	RamVars_UnpackFlopCntAndFirstToAL
+
+	cbw													; Clears AH (there are flop drives) or ffh (there are not)
+														; Either AH has success code (flop drives are present)
+														; or it doesn't matter because we won't match drive ffh
+
+	cwd													; clears DX (there are flop drives) or ffffh (there are not)
+
+	adc		dl, al										; second drive (CF set) if present
+														; If no drive is present, this will result in ffh which 
+														; won't match a drive
+	call	BackupErrorCodeFromTheRequestedDriveToBH
+	mov		dl, al										; We may end up doing the first drive twice (if there is
+	jmp		BackupErrorCodeFromTheRequestedDriveToBH	; only one drive), but doing it again is not harmful.
+%else
+	ret
+%endif
+		
 ;--------------------------------------------------------------------
 ; .BackupErrorCodeFromMasterOrSlaveToBH
@@ -144,4 +180,5 @@
 	ret
 
+		
 ;--------------------------------------------------------------------
 ; GetBasePortToCX
@@ -167,18 +204,2 @@
 
 
-;--------------------------------------------------------------------
-; BackupErrorCodeFromTheRequestedDriveToBH
-;	Parameters:
-;		AH:		Error code from the last resetted drive
-;		DL:		Drive last resetted
-;		BL:		Requested drive (DL when entering AH=00h)
-;	Returns:
-;		BH:		Backuped error code
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-BackupErrorCodeFromTheRequestedDriveToBH:
-	cmp		dl, bl				; Requested drive?
-	eCMOVE	bh, ah
-	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH15h_HSize.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH15h_HSize.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH15h_HSize.asm	(revision 258)
@@ -15,5 +15,6 @@
 ;	Returns with INTPACK:
 ;		If succesfull:
-;			AH:		3 (Hard disk accessible)
+;			AH:		Hard Disk: 3 (Hard disk accessible)
+;                   Floppy:    1 (Floppy disk, without change detection)
 ;			CX:DX:	Total number of sectors
 ;			CF:		0
@@ -25,11 +26,28 @@
 ALIGN JUMP_ALIGN
 AH15h_HandlerForReadDiskDriveSize:
+%ifdef MODULE_SERIAL_FLOPPY
+	mov		cl, 1										; 1 = floppy disk, no change detection
+				
+	test	dl,dl										; DO NOT store the sector count if this is a 
+	jns		.FloppyDrive								; floppy disk, some OS's depend on this not 
+														; happening for floppies in order to boot.
+%endif
+		
 	call	AH15h_GetSectorCountToBXDXAX
-	mov		[bp+IDEPACK.intpack+INTPACK.cx], dx	; HIWORD to CX
-	mov		[bp+IDEPACK.intpack+INTPACK.dx], ax	; LOWORD to DX
+	mov		[bp+IDEPACK.intpack+INTPACK.cx], dx			; HIWORD to CX
+	xchg	[bp+IDEPACK.intpack+INTPACK.dx], ax			; LOWORD to DX, AL gets drive number
 
-	xor		ah, ah
-	call	Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH	; Store success to BDA and CF
-	mov		BYTE [bp+IDEPACK.intpack+INTPACK.ah], 3				; Type code = Hard disk
+	xor		ah, ah		
+%ifdef MODULE_SERIAL_FLOPPY				
+	mov		cl, 3										; 3 = Hard Disk Accessible
+.FloppyDrive:
+		
+	call	Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH_ALHasDriveNumber	; Store success to BDA and CF		
+	mov		BYTE [bp+IDEPACK.intpack+INTPACK.ah], cl
+%else
+	call	Int13h_SetErrorCodeToBdaAndToIntpackInSSBPfromAH	; Store success to BDA and CF		
+	mov		BYTE [bp+IDEPACK.intpack+INTPACK.ah], 3
+%endif		
+		
 	jmp		Int13h_ReturnFromHandlerWithoutStoringErrorCode
 
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1h_HStatus.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1h_HStatus.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1h_HStatus.asm	(revision 258)
@@ -20,5 +20,17 @@
 AH1h_HandlerForReadDiskStatus:
 	LOAD_BDA_SEGMENT_TO	ds, ax, !
+
+%ifdef MODULE_SERIAL_FLOPPY
+	test	dl, dl
+	jns		.HardDisk
+	mov		ah, [BDA.bFDRetST]		; Unlike for hard disks below, floppy version does not clear the status
+	jmp		.done
+.HardDisk:	
+%endif
+		
 	xchg	ah, [BDA.bHDLastSt]		; Load and clear last error
+									; Note that AH is cleared with the LOAD_BDA_SEGMENT above
+				
+.done:
 	call	Int13h_SetErrorCodeToIntpackInSSBPfromAH
 	jmp		Int13h_ReturnFromHandlerWithoutStoringErrorCode
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm	(revision 258)
@@ -40,2 +40,3 @@
 	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAHandTransferredSectorsFromCL
 %endif
+
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 258)
@@ -14,4 +14,5 @@
 ;		SS:BP:	Ptr to IDEPACK
 ;	Returns with INTPACK:
+;       BL:     Drive Type (for floppies only)
 ;		CH:		Maximum cylinder number, bits 7...0
 ;		CL:		Bits 7...6: Cylinder number bits 9...8
@@ -19,23 +20,52 @@
 ;		DH:		Maximum head number (0...255)
 ;		DL:		Number of drives
+;       ES:DI:  Floppy DPT (for floppies only)
 ;		AH:		Int 13h/40h floppy return status
 ;		CF:		0 if successfull, 1 if error
 ;--------------------------------------------------------------------
 AH8h_HandlerForReadDiskDriveParameters:
+
 	call	RamVars_IsDriveHandledByThisBIOS
-	jnc		SHORT .GetDriveParametersForForeignHardDiskInDL
+	jnc		SHORT .OurDrive
+
+	call	Int13h_CallPreviousInt13hHandler
+	jnc		SHORT .MidGame
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+		
+.OurDrive:		
 	call	AH8h_GetDriveParameters
-	jmp		SHORT .ReturnAfterStoringValuesToIntpack
 
-.GetDriveParametersForForeignHardDiskInDL:
-	call	Int13h_CallPreviousInt13hHandler
-	jc		SHORT .ReturnErrorFromPreviousInt13hHandler
-	call	RamVars_GetCountOfKnownDrivesToDL
-.ReturnAfterStoringValuesToIntpack:
+%ifdef MODULE_SERIAL_FLOPPY
+	push	cs							; setup registers if we are a floppy drive, in all cases
+	pop		es							; if it is not a floppy drive, these values will not be put in INTPACK
+	mov		di, AH8h_FloppyDPT
+%endif
+	;; fall-through
+		
+.MidGame:		
+	call	RamVars_GetCountOfKnownDrivesToAX		; assume hard disk for now, will discard if for floppies
+
+	test	byte [bp+IDEPACK.intpack+INTPACK.dl], 080h
+	jnz		.Done
+		
+	mov		[bp+IDEPACK.intpack+INTPACK.bl], bl
+
+	mov		[bp+IDEPACK.intpack+INTPACK.es], es
+	mov		[bp+IDEPACK.intpack+INTPACK.di], di		
+
+	call	FloppyDrive_GetCountToAX
+
+.Done:	
+	mov		ah, dh
+		
 	mov		[bp+IDEPACK.intpack+INTPACK.cx], cx
-	mov		[bp+IDEPACK.intpack+INTPACK.dx], dx
+	xchg	[bp+IDEPACK.intpack+INTPACK.dx], ax		; recover DL for BDA last status byte determination
+
 	xor		ah, ah
-.ReturnErrorFromPreviousInt13hHandler:
+%ifdef MODULE_SERIAL_FLOPPY
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH_ALHasDriveNumber			
+%else
 	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+%endif
 
 
@@ -51,5 +81,4 @@
 ;				Bits 5...0:	Maximum sector number (1...63)
 ;		DH:		Maximum head number (0...255)
-;		DL:		Number of drives
 ;	Corrupts registers:
 ;		AX, BX
@@ -73,5 +102,4 @@
 ;				Bits 5...0:	Maximum sector number (1...63)
 ;		DH:		Maximum head number (0...255)
-;		DL:		Number of drives
 ;	Corrupts registers:
 ;		AX, BX
@@ -85,3 +113,61 @@
 	or		cl, bh					; CL bits 0...5 = Sectors per track
 	mov		dh, bl					; DH = Maximum head number
-	jmp		RamVars_GetCountOfKnownDrivesToDL
+		
+%ifdef MODULE_SERIAL_FLOPPY
+	mov		bl,[di+DPT.bFlagsHigh]
+	eSHR_IM	bl,FLGH_DPT_SERIAL_FLOPPY_TYPE_FIELD_POSITION
+%endif		
+	ret
+
+%ifdef MODULE_SERIAL_FLOPPY
+;
+; Floppy Disk Parameter Table.  There is no way to specify more than one of these
+; for any given system, so no way to make this drive or media specific.
+; So we return fixed values out of the ROM for callers might be expecting this information.
+;
+; On AT systems, we return the information for a 1.44 MB disk, 
+; and on XT systems, we return the information for a 360 KB disk.
+;
+AH8h_FloppyDPT:
+%ifdef USE_AT
+	db		0ah << 4 | 0fh			; Offset 0: Drive timings, 1.44MB values
+%else
+	db		0dh << 4 | 0fh			; Offset 0: Drive timings, 360KB values
+%endif
+
+	db		1h << 1 | 0				; Offset 1: Typical values of 1 for head load time
+									;           DMA used (although it actually is not, but is more restrctive)
+	db		25h						; Offset 2: Inactiviy motor turn-off delay, 
+									; 			Typical value of 25h for 2 second delay
+	db		02h						; Offset 3: Sector size, always 512
+
+%ifdef USE_AT
+	db		12h						; Offset 4: Sectors per track, 1.44MB value
+	db		1bh						; Offset 5: Sector gap, 1.44MB value
+%else
+	db		09h						; Offset 4: Sectors per track, 360KB value
+	db		2ah						; Offset 5: Sector gap, 360KB value
+%endif
+
+	db		0ffh					; Offset 6: Data length
+
+%ifdef USE_AT
+	db		6ch						; Offset 7: Format gap length, 1.44MB value
+%else
+	db		50h						; Offset 7: Format gap length, 360KB value
+%endif
+
+	db		0f6h					; Offset 8: Fill byte for format
+	db		0fh						; Offset 9: Head setting time
+	db		08h						; Offset A: Wait for motor startpu time
+
+%ifdef USE_AT
+	db		79						; Offset B: Maximum track number, 1.44MB value
+	db		0						; Offset C: Data transfer rate, 1.44MB value
+	db		4						; Offset D: Diskette CMOS drive type, 1.44MB value
+%else
+	db		39						; Offset B: Maximum track number, 360KB value
+	db		80h						; Offset C: Data transfer rate, 360KB value
+	db		1						; Offset D: Diskette CMOS drive type, 360KB value
+%endif
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 258)
@@ -43,4 +43,14 @@
 	push	cx
 
+%ifdef MODULE_SERIAL
+	; 
+	; no need to do this for serial deveices, and we use the DPT_RESET flag bits
+	; to store the drive type for serial floppy drives (MODULE_SERIAL_FLOPPY)
+	;
+	xor		ah, ah
+	test	byte [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE	; Clears CF
+	jnz		.ReturnNotSuccessfull
+%endif
+		
 	; Try to select drive and wait until ready
 	or		BYTE [di+DPT.bFlagsHigh], MASKH_DPT_RESET		; Everything uninitialized
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm	(revision 258)
@@ -31,7 +31,7 @@
 	; Install INT 19h handler for proper reboot
 	LOAD_BDA_SEGMENT_TO	es, ax
-	mov		bx, BIOS_BOOT_LOADER_INTERRUPT_19h	; INT 19h interrupt vector offset
+	mov		al, BIOS_BOOT_LOADER_INTERRUPT_19h	; INT 19h interrupt vector offset
 	mov		si, Int19h_ResetHandler				; INT 19h handler to reboot the system
-	call	Interrupts_InstallHandlerToVectorInBXFromCSSI
+	call	Interrupts_InstallHandlerToVectorInALFromCSSI
 	call	Initialize_AndDetectDrives			; Installs new boot menu loader
 	; Fall to .PrepareStackAndSelectDriveFromBootMenu
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm	(revision 258)
@@ -43,4 +43,5 @@
 
 %ifdef MODULE_SERIAL
+;----------------------------------------------------------------------
 ;
 ; if serial drive detected, do not scan (avoids duplicate drives and isn't needed - we already have a connection)
@@ -57,5 +58,44 @@
 %endif
 
-.done:
+.done:	
+%ifdef MODULE_SERIAL_FLOPPY
+;----------------------------------------------------------------------
+;
+; Add in any emulated serial floppy drives.
+;
+	mov		al, [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt]
+	dec		al
+	mov		cl, al
+	js		.NoFloppies						; if no drives are present, we store 0ffh
+
+	call	FloppyDrive_GetCountFromBIOS_or_BDA
+
+	push	ax
+
+	add		al, cl							; Add our drives to existing drive count
+	cmp		al, 3							; For BDA, max out at 4 drives (ours is zero based)
+	jl		.MaxBDAFloppiesExceeded
+	mov		al, 3							
+.MaxBDAFloppiesExceeded:
+	eROR_IM	al, 2							; move to bits 6-7
+	inc		ax								; low order bit, indicating floppy drive exists
+
+	mov		ah, [es:BDA.wEquipment]			; Load Equipment WORD low byte	
+	and		ah, 03eh						; Mask off drive number and drives present bit
+	or		al, ah							; Or in new values
+	mov		[es:BDA.wEquipment], al			; and store
+
+	mov		al, 1eh							; BDA pointer to Floppy DPT
+	mov		si, AH8h_FloppyDPT
+	call	Interrupts_InstallHandlerToVectorInALFromCSSI
+
+	pop		ax
+
+	shr		cl, 1							; number of drives, 1 or 2 only, to CF flag (clear=1, set=2)
+	rcl		al, 1							; starting drive number in upper 7 bits, number of drives in low bit
+.NoFloppies:	
+	mov		[RAMVARS.xlateVars+XLATEVARS.bFlopCntAndFirst], al
+%endif
+		
 	ret
 
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/FloppyDrive.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/FloppyDrive.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/FloppyDrive.asm	(revision 258)
@@ -120,26 +120,31 @@
 ; Returns number of Floppy Drives in system.
 ;
-; FloppyDrive_GetCountToCX
-;	Parameters:
-;		Nothing
-;	Returns:
-;		CX:		Number of Floppy Drives
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-FloppyDrive_GetCountToCX:
+; FloppyDrive_GetCountToAX
+;	Parameters:
+;		DS:		RAMVARS Segment
+;	Returns:
+;		AX:		Number of Floppy Drives
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FloppyDrive_GetCountToAX:		
+%ifdef MODULE_SERIAL_FLOPPY
+	call	RamVars_UnpackFlopCntAndFirstToAL
+	adc		al,1						; adds in the drive count bit, and adds 1 for count vs. 0-index, 
+										; but still won't impact SF
+	jns		.UseInternalNumber			; need to clear CH on the way out, and add in additional drive numbers
+
+%endif
+	call	FloppyDrive_GetCountFromBIOS_or_BDA
+		
+.UseInternalNumber:	
+	mov		ah, [cs:ROMVARS.bMinFddCnt]
+	MAX_U	al, ah
+	cbw
+		
+	ret
+
+ALIGN JUMP_ALIGN		
+FloppyDrive_GetCountFromBIOS_or_BDA:
 	push	es
-%ifdef USE_AT
-	call	GetCountFromBIOS
-%else
-	call	GetCountFromBDA
-%endif
-	mov		ch, [cs:ROMVARS.bMinFddCnt]
-	MAX_U	cl, ch
-	pop		es
-	xor		ch, ch
-	ret
-
 
 ;--------------------------------------------------------------------
@@ -160,22 +165,18 @@
 %ifdef USE_AT
 ALIGN JUMP_ALIGN
-GetCountFromBIOS:
+.GetCountFromBIOS:
 	push	di
 	push	dx
 	push	bx
-	push	ax
 
 	mov		ah, 08h					; Get Drive Parameters
 	cwd								; Floppy Drive 00h
 	int		BIOS_DISKETTE_INTERRUPT_40h
-	mov		cl, dl					; Number of Floppy Drives to CL
-
-	pop		ax
+	mov		al, dl					; Number of Floppy Drives to AL
+
 	pop		bx
 	pop		dx
 	pop		di
-	ret
-%endif
-
+%endif
 
 ;--------------------------------------------------------------------
@@ -193,11 +194,14 @@
 %ifndef USE_AT
 ALIGN JUMP_ALIGN
-GetCountFromBDA:
-	LOAD_BDA_SEGMENT_TO	es, cx
-	mov		cl, [es:BDA.wEquipment]			; Load Equipment WORD low byte
-	mov		ch, cl							; Copy it to CH
-	and		cx, 0C001h						; Leave bits 15..14 and 0
-	eROL_IM	ch, 2							; EW low byte bits 7..6 to 1..0
-	add		cl, ch							; CL = Floppy Drive count
-	ret
-%endif
+.GetCountFromBDA:
+	LOAD_BDA_SEGMENT_TO	es, ax
+	mov		al, [es:BDA.wEquipment]			; Load Equipment WORD low byte
+	mov		ah, al							; Copy it to CH
+	and		ax, 0C001h						; Leave bits 15..14 and 0
+	eROL_IM	ah, 2							; EW low byte bits 7..6 to 1..0
+	add		al, ah							; CL = Floppy Drive count
+%endif
+
+	pop		es
+	ret
+		
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm	(revision 258)
@@ -29,7 +29,7 @@
 
 	; Install INT 19h handler (boot loader) where drives are detected
-	mov		bx, BIOS_BOOT_LOADER_INTERRUPT_19h
+	mov		al, BIOS_BOOT_LOADER_INTERRUPT_19h
 	mov		si, Int19h_BootLoaderHandler
-	call	Interrupts_InstallHandlerToVectorInBXFromCSSI
+	call	Interrupts_InstallHandlerToVectorInALFromCSSI
 
 .SkipRomInitialization:
@@ -73,5 +73,5 @@
 	mov		dl, 80h
 	call	RamVars_IsDriveHandledByThisBIOS
-	jnc		SHORT .FindForDrive81h	; Store nothing if not our drive
+	jc		SHORT .FindForDrive81h	; Store nothing if not our drive
 	call	FindDPT_ForDriveNumber	; DPT to DS:DI
 	mov		[es:HD0_DPT_POINTER_41h*4], di
@@ -80,5 +80,5 @@
 	inc		dx
 	call	RamVars_IsDriveHandledByThisBIOS
-	jnc		SHORT .ResetDetectedDrives
+	jc		SHORT .ResetDetectedDrives
 	call	FindDPT_ForDriveNumber
 	mov		[es:HD1_DPT_POINTER_46h*4], di
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/Interrupts.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/Interrupts.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/Interrupts.asm	(revision 258)
@@ -34,8 +34,4 @@
 	mov		ax, [es:BIOS_DISK_INTERRUPT_13h*4]	; Load old INT 13h offset
 	mov		[RAMVARS.fpOldI13h], ax				; Store old INT 13h offset
-
-	mov		bx, BIOS_DISK_INTERRUPT_13h			; INT 13h interrupt vector offset
-	mov		si, Int13h_DiskFunctionsHandler		; Interrupt handler offset
-	call	Interrupts_InstallHandlerToVectorInBXFromCSSI
 
 	; Only store INT 13h handler to 40h if 40h is not already installed.
@@ -47,4 +43,8 @@
 	mov		[es:BIOS_DISKETTE_INTERRUPT_40h*4+2], dx	; Store old INT 13h segment
 .Int40hAlreadyInstalled:
+
+	mov		al, BIOS_DISK_INTERRUPT_13h			; INT 13h interrupt vector offset
+	mov		si, Int13h_DiskFunctionsHandler		; Interrupt handler offset
+	call	Interrupts_InstallHandlerToVectorInALFromCSSI
 	; Fall to .InitializeHardwareIrqHandlers
 
@@ -56,5 +56,5 @@
 ;		Nothing
 ;	Corrupts registers:
-;		BX, CX, DX, SI, DI
+;		BX, CX, DX, SI, DI, AX
 ;--------------------------------------------------------------------
 .InitializeHardwareIrqHandlers:
@@ -62,5 +62,5 @@
 	mov		di, ROMVARS.ideVars0			; CS:SI points to first IDEVARS
 .IdeControllerLoop:
-	eMOVZX	bx, BYTE [cs:di+IDEVARS.bIRQ]
+	mov		al, BYTE [cs:di+IDEVARS.bIRQ]
 	add		di, BYTE IDEVARS_size			; Increment to next controller
 	call	.InstallLowOrHighIrqHandler
@@ -72,5 +72,5 @@
 ; .InstallLowOrHighIrqHandler
 ;	Parameters:
-;		BX:		IRQ number, 0 if IRQ disabled
+;		AL:		IRQ number, 0 if IRQ disabled
 ;		ES:		BDA and Interrupt Vector segment (zero)
 ;	Returns:
@@ -80,7 +80,7 @@
 ;--------------------------------------------------------------------
 .InstallLowOrHighIrqHandler:
-	test	bl, bl
+	test	al, al
 	jz		SHORT .Return	; IRQ not used
-	cmp		bl, 8
+	cmp		al, 8
 	jb		SHORT .InstallLowIrqHandler
 	; Fall to .InstallHighIrqHandler
@@ -94,31 +94,31 @@
 ;		Nothing
 ;	Corrupts registers:
-;		BX, SI
+;		AL, BX, SI
 ;--------------------------------------------------------------------
 .InstallHighIrqHandler:
-	add		bx, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8	; Interrupt vector number
+	add		al, BYTE HARDWARE_IRQ_8_INTERRUPT_70h - 8	; Interrupt vector number
 	mov		si, IdeIrq_InterruptServiceRoutineForIrqs8to15
-	jmp		SHORT Interrupts_InstallHandlerToVectorInBXFromCSSI
+	jmp		SHORT Interrupts_InstallHandlerToVectorInALFromCSSI
 
 ;--------------------------------------------------------------------
 ; .InstallLowIrqHandler
 ;	Parameters:
-;		BX:		IRQ number (0...7)
-;		ES:		BDA and Interrupt Vector segment (zero)
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		BX, SI
+;		AL:		IRQ number (0...7)
+;		ES:		BDA and Interrupt Vector segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL, BX, SI
 ;--------------------------------------------------------------------
 .InstallLowIrqHandler:
-	add		bx, BYTE HARDWARE_IRQ_0_INTERRUPT_08h		; Interrupt vector number
+	add		al, BYTE HARDWARE_IRQ_0_INTERRUPT_08h		; Interrupt vector number
 	mov		si, IdeIrq_InterruptServiceRoutineForIrqs2to7
-	; Fall to Interrupts_InstallHandlerToVectorInBXFromCSSI
-
-
-;--------------------------------------------------------------------
-; Interrupts_InstallHandlerToVectorInBXFromCSSI
-;	Parameters:
-;		BX:		Interrupt vector number (for example 13h)
+	; Fall to Interrupts_InstallHandlerToVectorInALFromCSSI
+
+
+;--------------------------------------------------------------------
+; Interrupts_InstallHandlerToVectorInALFromCSSI
+;	Parameters:
+;		AL:		Interrupt vector number (for example 13h)
 ;		ES:		BDA and Interrupt Vector segment (zero)
 ;		CS:SI:	Ptr to interrupt handler
@@ -126,8 +126,10 @@
 ;		Nothing
 ;	Corrupts registers:
-;		BX
-;--------------------------------------------------------------------
-Interrupts_InstallHandlerToVectorInBXFromCSSI:
-	eSHL_IM	bx, 2					; Shift for DWORD offset
+;		AX, BX
+;--------------------------------------------------------------------
+Interrupts_InstallHandlerToVectorInALFromCSSI:
+	mov		bl, 4					; Shift for DWORD offset, MUL smaller than other alternatives
+	mul		bl
+	xchg	ax, bx
 	mov		[es:bx], si				; Store offset
 	mov		[es:bx+2], cs			; Store segment
Index: trunk/XTIDE_Universal_BIOS/Src/Main.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 257)
+++ trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 258)
@@ -176,7 +176,7 @@
 	%include "BootMenuEvent.asm"	; For menu library event handling
 									; NOTE: BootMenuPrint needs to come immediately after BootMenuEvent
-	%include "BootMenuPrint.asm"	; For printing Boot Menu strings 
+									;       so that jump table entries in BootMenuEvent stay within 8-bits
+	%include "BootMenuPrint.asm"	; For printing Boot Menu strings, also includes "BootMenuPrintCfg.asm"
 	%include "BootPrint.asm"		; For printing boot information
-	%include "BootMenuPrintCfg.asm"	; For printing hard disk configuration
 	%include "FloppyDrive.asm"		; Floppy Drive related functions
 	%include "BootSector.asm"		; For loading boot sector
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 257)
+++ 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 257)
+++ 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 257)
+++ 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
