Index: /trunk/Serial_Server/library/Image.cpp
===================================================================
--- /trunk/Serial_Server/library/Image.cpp	(revision 232)
+++ /trunk/Serial_Server/library/Image.cpp	(revision 233)
@@ -137,5 +137,5 @@
 #define ATA_dwLBACnt 60
 
-#define ATA_VendorSpecific_ReturnPortBaud 158
+#define ATA_wVendor 159
 
 #define ATA_wCaps_LBA 0x200
@@ -164,24 +164,27 @@
 };
 
-void Image::respondInquire( unsigned short *buff, struct baudRate *baudRate, unsigned char portAndBaud )
-{
-	unsigned short comPort = 0;
-	struct comPorts *cp;
-
-	if( portAndBaud )
-	{
-		for( cp = supportedComPorts; cp->port && cp->port != ((portAndBaud << 3) + 0x260); cp++ ) ;
-		if( cp->port )
-			comPort = cp->com;
-	}
-	  
+void Image::respondInquire( unsigned short *buff, struct baudRate *baudRate, unsigned short port, unsigned char scan )
+{
 	memset( &buff[0], 0, 514 );
 
-	if( comPort )
-		sprintf( (char *) &buff[ATA_strModel], "%.20s (COM%d/%s)", shortFileName, comPort, baudRate->display );
-	else
-		sprintf( (char *) &buff[ATA_strModel], "%.30s (%s baud)", shortFileName, baudRate->display );
-
-	// strncpy( (char *) &buff[ATA_strModel], img->shortFileName, 40 );
+	if( scan )
+	{
+		unsigned short comPort = 0;
+		struct comPorts *cp;
+
+		if( port )
+		{
+			for( cp = supportedComPorts; cp->port && cp->port != port; cp++ ) ;
+			if( cp->port )
+				comPort = cp->com;
+		}
+
+		if( comPort )
+			sprintf( (char *) &buff[ATA_strModel], "%.15s (COM%c/%s)", shortFileName, comPort, baudRate->display );
+		else
+			sprintf( (char *) &buff[ATA_strModel], "%.25s (%s baud)", shortFileName, baudRate->display );
+	}
+	else
+		sprintf( (char *) &buff[ATA_strModel], "%.30s", shortFileName );
 
 	strncpy( (char *) &buff[ATA_strSerial], "serial", 20 );
Index: /trunk/Serial_Server/library/Library.h
===================================================================
--- /trunk/Serial_Server/library/Library.h	(revision 232)
+++ /trunk/Serial_Server/library/Library.h	(revision 233)
@@ -42,5 +42,5 @@
 	static int parseGeometry( char *str, unsigned long *p_cyl, unsigned long *p_head, unsigned long *p_sect );
 
-	void respondInquire( unsigned short *buff, struct baudRate *baudRate, unsigned char portAndBaud );
+	void respondInquire( unsigned short *buff, struct baudRate *baudRate, unsigned short port, unsigned char scan );
 
 	void init( char *name, int p_readOnly, int p_drive, unsigned long p_cyl, unsigned long p_head, unsigned long p_sect, int p_useCHS );
Index: /trunk/Serial_Server/library/Process.cpp
===================================================================
--- /trunk/Serial_Server/library/Process.cpp	(revision 232)
+++ /trunk/Serial_Server/library/Process.cpp	(revision 233)
@@ -31,7 +31,7 @@
 		unsigned char driveAndHead;
 		unsigned char count;
-		unsigned char undefined1;
-		unsigned char portAndBaud;
-		unsigned char undefined2;
+		unsigned char scan;
+		unsigned char port;
+		unsigned char baud;
 	} inquire;
 	unsigned char b[514];
@@ -48,10 +48,4 @@
 #define SERIAL_COMMAND_MASK 0xe3
 #define SERIAL_COMMAND_HEADERMASK 0xe0
-
-#define SERIAL_INQUIRE_PORTANDBAUD_BAUDMASK 3
-#define SERIAL_INQUIRE_PORTANDBAUD_PORTMASK 0xfc
-#define SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT 0x240
-
-#define SERIAL_INQUIRE_PORTANDBAUD_PORTTRANSLATE( a ) ( ((a) & SERIAL_INQUIRE_PORTANDBAUD_PORT) << 1 | SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT )
 
 #define ATA_COMMAND_LBA 0x40
@@ -96,4 +90,5 @@
 	unsigned long cyl, sect, head;
 	unsigned long perfTimer;
+	unsigned char lastScan;
 
 	GetTime_Timeout_Local = GetTime_Timeout();
@@ -102,4 +97,5 @@
 	readto = 0;
 	workCount = workOffset = workCommand = 0;
+	lastScan = 0;
 
 	lasttick = GetTime();
@@ -282,7 +278,6 @@
 					if( workCommand == SERIAL_COMMAND_INQUIRE )
 						log( 1, "Inquire %d: Client Port=0x%x, Client Baud=%s", img == image0 ? 0 : 1,
-							 ((buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_PORTMASK) << 1) 
-							 + SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT,
-							 baudRateMatchDivisor( buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_BAUDMASK )->display );
+							 ((unsigned short) buff.inquire.port) << 2,
+							 baudRateMatchDivisor( buff.inquire.baud )->display );
 					else if( buff.chs.driveAndHead & ATA_COMMAND_LBA )
 						log( 1, "%s %d: LBA=%u, Count=%u", comStr, img == image0 ? 0 : 1,
@@ -325,6 +320,8 @@
 				if( workCommand == SERIAL_COMMAND_INQUIRE )
 				{
+					unsigned char localScan;
+
 					if( serial->speedEmulation && 
-						(buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_BAUDMASK) != serial->baudRate->divisor )
+						buff.inquire.baud != serial->baudRate->divisor )
 					{
 						log( 1, "    Ignoring Inquire with wrong baud rate" );
@@ -333,5 +330,10 @@
 					}
 
-					img->respondInquire( &buff.w[0], serial->baudRate, buff.inquire.portAndBaud );
+					localScan = buff.inquire.scan;         // need to do this before the call to 
+					                                       // img->respondInquire, as it will clear the buff
+					img->respondInquire( &buff.w[0], serial->baudRate, 
+										 ((unsigned short) buff.inquire.port) << 2, 
+										 (img == image1 && lastScan) || buff.inquire.scan );
+					lastScan = localScan;
 				}
 				//
@@ -342,4 +344,5 @@
 					img->seekSector( mylba + workOffset );
 					img->readSector( &buff.w[0] );
+					lastScan = 0;
 				}
 
Index: /trunk/Serial_Server/library/Serial.cpp
===================================================================
--- /trunk/Serial_Server/library/Serial.cpp	(revision 232)
+++ /trunk/Serial_Server/library/Serial.cpp	(revision 233)
@@ -12,15 +12,17 @@
 struct baudRate supportedBaudRates[] = 
 { 
-	{   2400,  0x0,   "2400" },
-	{   4800, 0xff,   "4800" },
-	{   9600,  0x1,   "9600" },
-	{  19200, 0xff,  "19.2K" },
-	{  38400,  0x2,  "38.4K" },
-	{  76800, 0xff,  "76.8K" },
-	{ 115200,  0x3, "115.2K" },
-	{ 153600, 0xff, "153.6K" },
-	{ 230400, 0xff, "230.4K" },
-	{ 460800, 0xff, "460.8K" },
-	{      0,    0,     NULL }
+	{   2400,  0x30,    "2400" },
+	{   4800,  0x18,    "4800" },
+	{   9600,   0xc,    "9600" },
+	{  19200,  0xff,   "19.2K" },
+	{  28800,   0x4,   "28.8K" },
+	{  38400,  0xff,   "38.4K" },
+	{  57600,   0x2,   "57.6K" },
+	{  76800,  0xff,   "76.8K" },
+	{ 115200,   0x1,  "115.2K" },
+	{ 153600,  0xff,  "153.6K" },
+	{ 230400,  0xff,  "230.4K" },
+	{ 460800,  0xff,  "460.8K" },
+	{      0,     0, "Unknown" },
 };
 
@@ -37,5 +39,5 @@
 	}
 
-	return( NULL );
+	return( b );
 }
 
@@ -47,5 +49,5 @@
 		;
 
-	return( b->rate ? b : NULL );
+	return( b );
 }
 
Index: /trunk/Serial_Server/win32/Win32.cpp
===================================================================
--- /trunk/Serial_Server/win32/Win32.cpp	(revision 232)
+++ /trunk/Serial_Server/win32/Win32.cpp	(revision 233)
@@ -32,14 +32,15 @@
 		"                      (default is a 32 MB disk, with CHS geometry 65:63:16)",
 		"",
-		"  -p                  Named Pipe mode for emulators (pipe is '" PIPENAME "')",
+		"  -p                  Named Pipe mode for emulators (pipe is \"" PIPENAME "\")",
 		"",
 		"  -c COMPortNumber    COM Port to use (default is first found)",
 		"",
-		"  -b BaudRate         Baud rate to use on the COM port ",
-		"                      Without a rate multiplier: 2400, 9600, 38400, 115200",
-		"                      With a 2x rate multiplier: 4800, 19200, 76800, 230400",
-		"                      With a 4x rate multiplier: 9600, 38400, 153600, 460800",
-		"                      Abbreviations also accepted (ie, '460K', '38.4K', etc)",
-		"                      (default is 38400, 115200 in named pipe mode)",
+		"  -b BaudRate         Baud rate to use on the COM port, with client machine",
+		"                      rate multiplier in effect:",
+		"                          None:  2400,  4800,  9600,  28.8K,  57.6K, 115.2K",
+		"                          2x:    4800,  9600, 19200,  57.6K, 115.2K, 230.4K",
+		"                          4x:    9600, 19200, 38400, 115.2K, 230.4K, 460.8K",
+		"                          and for completeness:               76.8K, 153.6K",
+		"                      (default is 9600, 115.2K when in named pipe mode)",
 		"",
 		"  -t                  Disable timeout, useful for long delays when debugging",
@@ -148,13 +149,9 @@
 				break;
 			case 'b': case 'B':
-				if( !(baudRate = baudRateMatchString( argv[++t] )) )
-				{
-					fprintf( stderr, "Unknown Baud Rate %s\n\n", argv[t] );
-					usage();
-				}
+				if( !(baudRate = baudRateMatchString( argv[++t] )) || !baudRate->rate )
+					log( -2, "Unknown Baud Rate \"%s\"", argv[t] );
 				break;
 			default:
-				fprintf( stderr, "Unknown Option: %s\n\n", argv[t] );
-				usage();
+				log( -2, "Unknown Option: \"%s\"", argv[t] );
 			}
 		}
@@ -179,5 +176,5 @@
 
 	if( !baudRate )
-		baudRate = baudRateMatchString( "38400" );
+		baudRate = baudRateMatchString( "9600" );
 
 	do
@@ -206,4 +203,9 @@
 		vfprintf( stderr, message, args );
 		fprintf( stderr, "\n" );
+		if( level < -1 )
+		{
+			fprintf( stderr, "\n" );
+			usage();
+		}
 		exit( 1 );
 	}
Index: /trunk/Serial_Server/win32/Win32Serial.h
===================================================================
--- /trunk/Serial_Server/win32/Win32Serial.h	(revision 232)
+++ /trunk/Serial_Server/win32/Win32Serial.h	(revision 233)
@@ -37,5 +37,5 @@
 		if( !strcmp( name, "PIPE" ) )
 		{
-			log( 0, "Opening named pipe %s (simulating %lu baud)", PIPENAME, baudRate->rate );
+			log( 0, "Opening named pipe %s (simulating %s baud)", PIPENAME, baudRate->display );
 		
 			pipe = CreateNamedPipeA( PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
Index: /trunk/XTIDE_Universal_BIOS/Inc/ATA_ID.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Inc/ATA_ID.inc	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Inc/ATA_ID.inc	(revision 233)
@@ -254,5 +254,6 @@
 	.wRMSN		resw 1	; 127F, Removable Media Status Notification feature set support
 	.wSecurity	resw 1	; 128FV, Security Status
-				resw 160-129	; 129...159X
+				resw 159-129	; 129...158X, Vendor Specific
+	.wVendor    resw 1  ; 159X, Vendor Specific - picking one word for use by the Serial Port code
 	.wCFAPower	resw 1	; 160FV, CFA Power Mode 1
 				resw 176-161	; 161...175R, Reserved for assignment by the CompactFlash Association
Index: /trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc	(revision 233)
@@ -28,5 +28,6 @@
 	.dpt						resb	DPT_size
 
-	; Block size is specified in sectors (1, 2, 4, 8, 16, 32, 64 or 128)
+	; Block size is specified in sectors (1, 2, 4, 8, 16, 32 or 64).
+	; 128 is not allowed to prevent offset overflow during data transfer.
 	.wSetAndMaxBlock:
 	.bSetBlock					resb	1	; Current block size (at least 1)
@@ -39,6 +40,7 @@
 	.dpt						resb	DPT_size
 
-	.bSerialPortAndBaud			resb	1	; Packed I/O port and baud rate for serial drives
-								resb 	1	; unused alignment
+	.wSerialPortAndBaud:
+	.bSerialPort				resb	1	; Serial connection I/O port address, divided by 4
+	.bSerialBaud				resb 	1	; Serial connection baud rate divisor
 endstruc
 %endif
Index: /trunk/XTIDE_Universal_BIOS/Inc/RamVars.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Inc/RamVars.inc	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Inc/RamVars.inc	(revision 233)
@@ -13,11 +13,5 @@
 	.bHDSwap		resb	1	; Hard Drive to swap to 80h and vice versa
 	.bXlatedDrv		resb	1	; Drive number after translation
-%ifdef MODULE_SERIAL
-	.bLastSerial	resb	1	; Packed Port and Baud for last serial drive detected
-								; (using space of an alignment byte, 
-								; used during and after boot (int13/25h case))
-%else
 					resb	1	; alignment
-%endif
 endstruc
 
Index: /trunk/XTIDE_Universal_BIOS/Inc/RomVars.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Inc/RomVars.inc	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Inc/RomVars.inc	(revision 233)
@@ -48,16 +48,30 @@
 ; Controller specific variables
 struc IDEVARS
+;;; Word 0
+	.wSerialPortAndBaud:					; Serial connection port (low, divided by 4) and baud rate divisor (high)
 	.wPort:									; IDE Base Port for Command Block (usual) Registers
-	.bSerialCOMDigit			resb	1	; Serial Device COM Port digit 
-	.bSerialPackedPortAndBaud 	resb	1	; Serial Device packed port and baud
+	.bSerialPort				resb	1
+	.bSerialBaud				resb	1
 
-	.wPortCtrl:								; IDE Base Port for Control Block Registers
-	.wSerialPackedPrintBaud		resb	2	; Serial Device packed baud rate for printing
+;;; Word 1
+	.wPortCtrl:
+	.bSerialUnused				resb	1	; IDE Base Port for Control Block Registers
 
+	.wSerialCOMPortCharAndDevice:			; In DetectPrint, we grab the COM Port char and Device at the same time
+	.bSerialCOMPortChar			resb	1	; Serial connection COM port number/letter
+
+;;; Word 2
 	.bDevice					resb	1	; Device type
+
 	.bIRQ						resb	1	; Interrupt Request Number
+
+;;; And more...
 	.drvParamsMaster			resb	DRVPARAMS_size
 	.drvParamsSlave				resb	DRVPARAMS_size
 endstruc
+
+%if IDEVARS.bSerialCOMPortChar+1 != IDEVARS.bDevice 
+%erorr "IDEVARS.bSerialCOMPortChar needs to come immediately before IDEVARS.bDevice so that both bytes can be fetched at the same time inside DetectPrint.asm"
+%endif
 
 ; Default values for Port and PortCtrl, shared with the configurator
@@ -67,6 +81,4 @@
 DEVICE_ATA_DEFAULT_PORT					EQU		1F0h
 DEVICE_ATA_DEFAULT_PORTCTRL				EQU		3F0h
-DEVICE_SERIAL_DEFAULT_COM				EQU		0		; COM1
-DEVICE_SERIAL_DEFAULT_BAUD				EQU		1		; 9600
 
 ; Device types for IDEVARS.bDevice
@@ -77,5 +89,5 @@
 DEVICE_16BIT_ATA						EQU	(3<<1)
 DEVICE_32BIT_ATA						EQU	(4<<1)
-DEVICE_SERIAL_PORT						EQU	(5<<1)
+DEVICE_SERIAL_PORT						EQU	(5<<1)		; must be last entry, or remove optimization in DetectPrint
 
 
@@ -94,47 +106,4 @@
 FLG_DRVPARAMS_BLOCKMODE	EQU	(1<<1)	; Enable Block mode transfers
 FLG_DRVPARAMS_USERLBA	EQU	(1<<2)	; User specified LBA values
-
-
-; Defines for IDEVARS.bSerialPackedPortAndBaud (same format used by DPT.bSerialPortAndBaud)
-;
-; pppp ppbb
-;   i/o port address = p * 2 + 240h
-;   baud rate = b, where 00 = 2400, 01 = 9600, 10 = 38.4K, 11 = 115.2K
-;
-; 240h/2400baud corresponds to 0 for a PackedPortAndBaud value, which triggers auto detect code.
-; Which means 240h is not usable, and is why ..._MINPORT is 248h.  A value is reserved at the upper
-; end of the spectrum in case it is needed (whcih is why it is 430h instead of 438h).
-;
-DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTMASK			EQU		0fch
-DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTBITS			EQU		03fh
-DEVICE_SERIAL_PACKEDPORTANDBAUD_PORT_FIELD_POSITION	EQU		2
-DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT		EQU		240h
-DEVICE_SERIAL_PACKEDPORTANDBAUD_MINPORT				EQU		248h	; minimum port value that the user can set
-DEVICE_SERIAL_PACKEDPORTANDBAUD_MAXPORT				EQU		430h	; or ((..._PORTMASK-1) << 1) + ..._STARTINGPORT
-
-DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDMASK			EQU		3h
-DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDBITS			EQU		3h
-DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUD_FIELD_POSITION	EQU		0
-
-; Defines for IDEVARS.wSerialPrintBaud
-;
-; pppp ppnn nnnn nnnn
-;   unsigned number to output = n
-;   postfix character = p + '0' (designed for '0' and 'K', although other values are possible)
-;
-; Note that the contents of this word is only used for printing by the BIOS when a drive is detected.  
-; It is not used for any other purpose, and so long as it conforms to the structure, any values can be used.
-;
-DEVICE_SERIAL_PRINTBAUD_NUMBERMASK		EQU		003ffh
-DEVICE_SERIAL_PRINTBAUD_POSTCHARMASK	EQU		0fc00h
-DEVICE_SERIAL_PRINTBAUD_POSTCHARADD		EQU		'0'
-;
-; These are defined here (instead of in the configurator) for consistency since they could also be used 
-; in main.asm as a default for an IDEVARS structure.
-;
-DEVICE_SERIAL_PRINTBAUD_2400  EQU ((('0'-DEVICE_SERIAL_PRINTBAUD_POSTCHARADD)<<10) | 240)		; Prints "2400"
-DEVICE_SERIAL_PRINTBAUD_9600  EQU ((('0'-DEVICE_SERIAL_PRINTBAUD_POSTCHARADD)<<10) | 960)		; Prints "9600"
-DEVICE_SERIAL_PRINTBAUD_38_4  EQU ((('K'-DEVICE_SERIAL_PRINTBAUD_POSTCHARADD)<<10) | 38)		; Prints "38K"
-DEVICE_SERIAL_PRINTBAUD_115_2 EQU ((('K'-DEVICE_SERIAL_PRINTBAUD_POSTCHARADD)<<10) | 115)		; Prints "115K"
 
 ;
Index: /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIrq.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIrq.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIrq.asm	(revision 233)
@@ -109,5 +109,6 @@
 	; Reading Status Register acknowledges IDE interrupt
 	call	RamVars_GetSegmentToDS
-	call	FindDPT_ToDSDIforInterruptInService
+	mov		bl, FLGH_DPT_INTERRUPT_IN_SERVICE
+	call	FindDPT_ToDSDIforFlagsHighInBL
 	mov		dl, STATUS_REGISTER_in
 	call	IdeIO_InputToALfromIdeRegisterInDL
Index: /trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm	(revision 233)
@@ -17,16 +17,7 @@
 ;
 ; Values for UART_divisorLow:
-; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 3 = 38400, 2 = 57600, 1 = 115200
+; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 4 = 28800, 3 = 38400, 2 = 57600, 1 = 115200
 ;
 SerialCommand_UART_divisorLow					EQU		0
-
-;
-; We support 4 baud rates, starting here going higher and skipping every other baud rate
-; Starting with 30h, that means 30h (1200 baud), 0ch (9600 baud), 3 (38400 baud), and 1 (115200 baud)
-; Note: hardware baud multipliers (2x, 4x) will impact the final baud rate and are not known at this level
-;
-SerialCommand_UART_divisorLow_startingBaud		EQU   030h
-
-SerialCommand_UART_interruptEnable				EQU		1
 
 ;
@@ -91,13 +82,13 @@
 		mov		[bp+IDEPACK.bFeatures],ah		; store protocol command
 
-		mov		dl, byte [di+DPT_SERIAL.bSerialPortAndBaud]
+		mov		dx, [di+DPT_SERIAL.wSerialPortAndBaud]
 
 ; fall-through
 
 ;--------------------------------------------------------------------
-; SerialCommand_OutputWithParameters_DeviceInDL
+; SerialCommand_OutputWithParameters_DeviceInDX
 ;	Parameters:
 ;       AH:		Protocol Command
-;       DL:		Packed I/O port and baud rate
+;       DX:		Packed I/O port and baud rate
 ;		ES:SI:	Ptr to buffer (for data transfer commands)
 ;		SS:BP:	Ptr to IDEREGS_AND_INTPACK
@@ -108,5 +99,5 @@
 ;		AL, BX, CX, DX, (ES:SI for data transfer commands)
 ;--------------------------------------------------------------------
-SerialCommand_OutputWithParameters_DeviceInDL:
+SerialCommand_OutputWithParameters_DeviceInDX:
 
 		push	si
@@ -116,19 +107,11 @@
 ;
 ; Unpack I/O port and baud from DPT
-;		Port to DX more or less for the remainder of the routine
+;		Port to DX for the remainder of the routine (+/- different register offsets)
 ;		Baud in CH until UART initialization is complete
 ;
-		mov		dh, ((DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT & 0f00h) >> (8+1))
-		shl		dx, 1		; port offset already x4, needs one more shift to be x8
-		mov		cl, dl
-
-		and		cl, (DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDMASK << 1)
-		mov		ch, SerialCommand_UART_divisorLow_startingBaud
-		shr		ch, cl
-		adc		ch, 0
-
-		and		dl, ((DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTMASK << 1) & 0ffh)
-		add		dx, byte (DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT & 0ffh)
-
+		mov		ch,dh
+		xor		dh,dh
+		eSHL_IM	dx, 2			; shift from one byte to two		
+		
 		mov		al,[bp+IDEPACK.bSectorCount]
 
@@ -414,4 +397,5 @@
 ; taken care of this, but I have seen cases where this is not true.
 ;
+		xor		cx,cx					; timeout this clearing routine, in case the UART isn't there
 .clearBuffer:
 		mov		dl,bh
@@ -420,7 +404,7 @@
 		test	al,08fh
 		jz		.clearBufferComplete
-		shr		al,1
+		test	al,1
 		in		al,dx
-		jc		.clearBuffer	; note CF from shr above
+		loopnz	.clearBuffer			; note ZF from test above
 
 .clearBufferComplete:
@@ -641,23 +625,30 @@
 ;     master scan.
 ;
-		mov		dl,[cs:bp+IDEVARS.bSerialPackedPortAndBaud]
-		mov		al,	byte [RAMVARS.xlateVars+XLATEVARS.bLastSerial]
+		mov		cx,1			; 1 sector to move, 0 for non-scan
+		mov		dx,[cs:bp+IDEVARS.wSerialPortAndBaud]
+		xor		ax,ax
+		push	si
+		call	FindDPT_ToDSDIforSerialDevice
+		pop		si
+		jnc		.notfounddpt
+		mov		ax,[ds:di+DPT_SERIAL.wSerialPortAndBaud]
+.notfounddpt:	
 
 		test	bh, FLG_DRVNHEAD_DRV
 		jz		.master
 
-		test	al,al			; Take care of the case that is different between master and slave.
+		test	ax,ax			; Take care of the case that is different between master and slave.
 		jz		.error			; Because we do this here, the jz after the "or" below will not be taken
 
 ; fall-through
 .master:
-		test	dl,dl
-		jnz		.identifyDeviceInDL
-
-		or		dl,al			; Move bLast into position in dl, as well as test for zero
+		test	dx,dx
+		jnz		.identifyDeviceInDX
+
+		or		dx,ax			; Move bLast into position in dl, as well as test for zero
 		jz		.scanSerial
 
 ; fall-through
-.identifyDeviceInDL:
+.identifyDeviceInDX:
 
 		push	bp				; setup fake IDEREGS_AND_INTPACK
@@ -665,5 +656,4 @@
 		push	dx
 
-		mov		cl,1			; 1 sector to move
 		push	cx
 
@@ -674,5 +664,5 @@
 
 		mov		bp,sp
-		call	SerialCommand_OutputWithParameters_DeviceInDL
+		call	SerialCommand_OutputWithParameters_DeviceInDX
 
 		pop		bx
@@ -680,15 +670,10 @@
 		pop		cx
 		pop		dx
-
+		
 		pop		bp
 ;
 ; place packed port/baud in RAMVARS, read by FinalizeDPT and DetectDrives
 ;
-; Note that this will be set during an int13h/25h call as well.  Which is OK since it is only used (at the
-; top of this routine) for drives found during a COM scan, and we only COM scan if there were no other
-; COM drives found.  So we will only reaffirm the port/baud for the one COM port/baud that has a drive.
-;
-		jc		.notFound											; only store bLastSerial if success
-		mov		byte [RAMVARS.xlateVars+XLATEVARS.bLastSerial], dl
+		mov		[es:si+ATA6.wVendor],dx
 
 .notFound:
@@ -714,4 +699,5 @@
 .scanSerial:
 		mov		di,.scanPortAddresses-1
+		mov		ch,1			;  tell server that we are scanning
 
 .nextPort:
@@ -741,22 +727,27 @@
 
 ;
-; Pack into dl, baud rate starts at 0
-;
-		add		dx,-(DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT)
-		shr		dx,1			; dh is zero at this point, and will be sent to the server,
-								; so we know this is an auto detect
-
-		jmp		.testFirstBaud
-
-;
-; Walk through 4 possible baud rates
-;
+; Begin baud rate scan on this port...
+;
+; On a scan, we support 6 baud rates, starting here and going higher by a factor of two each step, with a 
+; small jump between 9600 and 38800.  These 6 were selected since we wanted to support 9600 baud and 115200,
+; *on the server side* if the client side had a 4x clock multiplier, a 2x clock multiplier, or no clock multiplier. 
+;
+; Starting with 30h, that means 30h (2400 baud), 18h (4800 baud), 0ch (9600 baud), and
+;					            04h (28800 baud), 02h (57600 baud), 01h (115200 baud)
+;
+; Note: hardware baud multipliers (2x, 4x) will impact the final baud rate and are not known at this level
+;
+		mov		dh,030h * 2	    ; multiply by 2 since we are about to divide by 2
+		mov		dl,[cs:di]		; restore single byte port address for scan
+
 .nextBaud:
-		inc		dx
-		test	dl,3
+		shr		dh,1
 		jz		.nextPort
-
-.testFirstBaud:
-		call	.identifyDeviceInDL
+		cmp		dh,6			; skip from 6 to 4, to move from the top of the 9600 baud range 
+		jnz		.testBaud		; to the bottom of the 115200 baud range
+		mov		dh,4
+
+.testBaud:
+		call	.identifyDeviceInDX
 		jc		.nextBaud
 
Index: /trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm	(revision 233)
@@ -17,6 +17,6 @@
 SerialDPT_Finalize:
 		or		byte [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-		mov		al, [RAMVARS.xlateVars+XLATEVARS.bLastSerial]
-		mov		byte [di+DPT_SERIAL.bSerialPortAndBaud], al
+		mov		ax, [es:si+ATA6.wVendor]
+		mov		word [di+DPT_SERIAL.wSerialPortAndBaud], ax
 		ret
 
Index: /trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm	(revision 233)
@@ -22,37 +22,41 @@
 
 .DriveDetectLoop:							; Loop through IDEVARS
-	mov		si, g_szDetect					; Setup standard print string
+	push	cx
+
+	mov		cx, g_szDetectMaster
+	mov		bh, MASK_DRVNHEAD_SET								; Select Master drive
+	call	StartDetectionWithDriveSelectByteInBHandStringInAX	; Detect and create DPT + BOOTNFO
+
+	mov		cx, g_szDetectSlave
+	mov		bh, MASK_DRVNHEAD_SET | FLG_DRVNHEAD_DRV  
+	call	StartDetectionWithDriveSelectByteInBHandStringInAX
+		
+	pop		cx
+
+	add		bp, BYTE IDEVARS_size			; Point to next IDEVARS
+
 %ifdef MODULE_SERIAL		
-	cmp		byte [cs:bp+IDEVARS.bDevice], DEVICE_SERIAL_PORT
-	jnz		.DriveNotSerial					; Special print string for serial drives
-	mov		si, g_szDetectCOM
-.DriveNotSerial:
+	jcxz	.done							; Set to zero on .ideVarsSerialAuto iteration (if any)
 %endif
-
-	call	.DetectDrives_WithIDEVARS		; Detect Master and Slave
-	add		bp, BYTE IDEVARS_size			; Point to next IDEVARS
+		
 	loop	.DriveDetectLoop
 
 %ifdef MODULE_SERIAL		
 ;
-; if serial drive detected, do not scan (avoids duplicate drives and isn't needed - we have a connection)
-; Note that XLATEVARS.bLastSerial is zero'd in RamVars_Initialize, called in Initialize_AutoDetectDrives;
-; bLastSerial it set in the detection code of SerialCommand.asm
+; if serial drive detected, do not scan (avoids duplicate drives and isn't needed - we already have a connection)
 ;
-	cmp		byte [RAMVARS.xlateVars+XLATEVARS.bLastSerial],cl 	; cx = zero after the loop above
-																; less instruction bytes than using immediate
-	jnz		.done												  
-		
+	call	FindDPT_ToDSDIforSerialDevice
+	jc		.done
+
+	mov		bp, ROMVARS.ideVarsSerialAuto	; Point to our special IDEVARS sructure, just for serial scans		
+				
 	mov		al,[cs:ROMVARS.wFlags]			; Configurator set to always scan?
 	or		al,[es:BDA.bKBFlgs1]			; Or, did the user hold down the ALT key?
 	and		al,8							; 8 = alt key depressed, same as FLG_ROMVARS_SERIAL_ALWAYSDETECT
-	jz		.done							
+	jnz		.DriveDetectLoop							
+%endif
 
-	mov		bp, ROMVARS.ideVarsSerialAuto	; Point to our special IDEVARS sructure, just for serial scans
-	mov		si, g_szDetectCOMAuto			; Special, special print string for serial drives during a scan
-;;; fall-through					
-%else
+.done:
 	ret
-%endif
 
 %if FLG_ROMVARS_SERIAL_SCANDETECT != 8
@@ -60,41 +64,10 @@
 %endif
 
-;--------------------------------------------------------------------
-; Detects IDE hard disks by using information from IDEVARS.
-;
-; DetectDrives_WithIDEVARS
-;	Parameters:
-;		CS:BP:		Ptr to IDEVARS
-;		DS:			RAMVARS segment
-;		ES:			Zero (BDA segment)
-;       SI:		    Ptr to template string
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AX, BX, DX, SI, DI
-;--------------------------------------------------------------------
-.DetectDrives_WithIDEVARS:
-	push	cx
-
-	push	si		
-	mov		ax, g_szMaster
-	mov		bh, MASK_DRVNHEAD_SET								; Select Master drive
-	call	StartDetectionWithDriveSelectByteInBHandStringInAX	; Detect and create DPT + BOOTNFO
-	pop		si
-
-	mov		ax, g_szSlave
-	mov		bh, MASK_DRVNHEAD_SET | FLG_DRVNHEAD_DRV
-	call	StartDetectionWithDriveSelectByteInBHandStringInAX
-	pop		cx
-		
-.done:	
-	ret
-
 		
 ;--------------------------------------------------------------------
 ; StartDetectionWithDriveSelectByteInBHandStringInAX
 ;	Parameters:
-;		AX:		Offset to "Master" or "Slave" string
 ;		BH:		Drive Select byte for Drive and Head Register
+;		CX:		Offset to "Master" or "Slave" string
 ;		CS:BP:	Ptr to IDEVARS for the drive
 ;		DS:		RAMVARS segment
Index: /trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectPrint.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectPrint.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectPrint.asm	(revision 233)
@@ -30,5 +30,5 @@
 ; DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP
 ;	Parameters:
-;		CS:AX:	Ptr to "Master" or "Slave" string
+;		CS:CX:	Ptr to "Master" or "Slave" string
 ;		CS:BP:	Ptr to IDEVARS
 ;       SI:		Ptr to template string 
@@ -39,30 +39,63 @@
 ;--------------------------------------------------------------------
 DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP:
-	push	bp
-	mov		di, [cs:bp+IDEVARS.wPort]
-%ifdef MODULE_SERIAL
-	mov		cx, [cs:bp+IDEVARS.wSerialPackedPrintBaud]
-%endif
+
+	mov		ax, [cs:bp+IDEVARS.wPort]    	; for IDE: AX=port address, DH=.bDevice
+	mov		dx, [cs:bp+IDEVARS.bDevice-1]   ; for Serial: AL=port address>>2, AH=baud rate
+											;			  DL=COM number character, DH=.bDevice
+
+	push	bp								; setup stack for call to 
+	mov		bp, sp							; BootMenuPrint_FormatCSSIfromParamsInSSBP
+
+	push 	cx								; Push "Master" or "Slave"
 		
-	mov		bp, sp
+	mov		cl, (g_szDetectPort-$$) & 0xff	; Setup print string for standard IDE
+											; Note that we modify only the low order bits of CX a lot here,
+											; saving code space rather than reloading CX completely.
+											; This optimization requires that all the g_szDetect* strings are
+											; on the same 256 byte page, which is checked in strings.asm.
 
-	push 	ax							; Push "Master" or "Slave"
+	cmp		dx, DEVICE_SERIAL_PORT << 8  	; Check if this is a serial device, 
+										 	; And also check if DL is zero, check with the jz below
+											; This optimization requires that DEVICE_SERIAL_PORT be 
+											; the highest value in the DEVICE_* series, ensuring that
+											; anything less in the high order bits is a different device.
+
+	jl		.pushAndPrint					; CX = string to print, AX = port address, DX won't be used
+
+	mov		cl, (g_szDetectCOM-$$) & 0xff	; Setup print string for COM ports
+	push	cx								; And push now.  We use the fact that format strings can contain
+											; themselves format strings.
+
+	push	dx								; Push COM number character
+				
+ 	mov		cl, (g_szDetectCOMAuto-$$) & 0xff	; Setup secondary print string for "Auto"
 		
-	push	di							; Push Port address or COM port number
+	jz		.pushAndPrint					; CX = string to print, AX and DX won't be used
+		
+	mov		cl, (g_szDetectCOMLarge-$$) & 0xff	; Setup secondary print string for "COMn/xx.yK"
 
-%ifdef MODULE_SERIAL
-;
-; Print baud rate from .wSerialPackedPrintBaud, in two parts - %u and then %c
-; 
-	mov		ax,cx						; Unpack baud rate number
-	and		ax,DEVICE_SERIAL_PRINTBAUD_NUMBERMASK
-	push	ax
+	mov		al,ah							; baud rate divisor to AL
+	cbw										; clear AH, AL will always be less than 128
+	xchg	si,ax							; move AX to SI for divide
+	mov		ax,1152							; baud rate to displa is 115200/divisor, the "00" is handled
+											; in the print strings
+	xor		dx,dx							; clear top 16-bits of dividend
+	div		si								; and divide...  Now AX = baud rate/100, DX = 0 (always a clean divide)
+		
+	mov		si,10							; Now separate the whole portion from the fractional for "K" display
+	div		si								; and divide...  Now AX = baud rate/1000, DX = low order digit
+		
+	cmp		ax,si							; <= 10: "2400", "9600", etc.; >10: "19.2K", "38.4K", etc.
+	jae		.pushAndPrint
 
-	mov		al,ch						; Unpack baud rate postfix ('0' or 'K')
-	eSHR_IM	al,2				        ; also effectively masks off the postfix
-	add		al,DEVICE_SERIAL_PRINTBAUD_POSTCHARADD
-	push	ax
-%endif
-						
+	mov		cl, (g_szDetectCOMSmall-$$) & 0xff	; Setup secondary print string for "COMn/XXy00"
+		
+.pushAndPrint:	
+	push	cx								; Push print string
+	push	ax								; Push high order digits, or port address, or N/A
+	push	dx								; Push low order digit, or N/A
+
+	mov		si, g_szDetectOuter				; Finally load SI with wrapper string "IDE %s at %s: "
+
 	jmp		short DetectPrint_BootMenuPrint_FormatCSSIfromParamsInSSBP_Relay	
 
@@ -92,2 +125,3 @@
 
 
+
Index: /trunk/XTIDE_Universal_BIOS/Src/Main.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 233)
@@ -112,6 +112,4 @@
 %ifdef MODULE_SERIAL
 	at	ROMVARS.ideVarsSerialAuto+IDEVARS.bDevice,		db	DEVICE_SERIAL_PORT
-	at	ROMVARS.ideVarsSerialAuto+IDEVARS.drvParamsMaster+DRVPARAMS.wFlags,	db	FLG_DRVPARAMS_BLOCKMODE
-	at	ROMVARS.ideVarsSerialAuto+IDEVARS.drvParamsSlave+DRVPARAMS.wFlags,	db	FLG_DRVPARAMS_BLOCKMODE
 %endif
 %else
@@ -145,6 +143,4 @@
 %ifdef MODULE_SERIAL
 	at	ROMVARS.ideVarsSerialAuto+IDEVARS.bDevice,		db	DEVICE_SERIAL_PORT
-	at	ROMVARS.ideVarsSerialAuto+IDEVARS.drvParamsMaster+DRVPARAMS.wFlags,	db	FLG_DRVPARAMS_BLOCKMODE
-	at	ROMVARS.ideVarsSerialAuto+IDEVARS.drvParamsSlave+DRVPARAMS.wFlags,	db	FLG_DRVPARAMS_BLOCKMODE
 %endif
 %endif
Index: /trunk/XTIDE_Universal_BIOS/Src/Strings.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Strings.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/Strings.asm	(revision 233)
@@ -12,9 +12,24 @@
 g_szRomAt:		db	"%s @ %x",LF,CR,NULL
 
-g_szMaster:				db	"IDE Master at ",NULL 
-g_szSlave:				db	"IDE Slave  at ",NULL
-g_szDetect:				db	"%s%x: ",NULL					   ; IDE Master at 1F0h:
-g_szDetectCOM:			db  "%sCOM%c/%u%c: ",NULL              ; IDE Master at COM1/115K:		
-g_szDetectCOMAuto:		db  "%sCOM Detect: ",NULL			   ; IDE Master at COM Detect:
+; The following strings are used by DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP
+; To support an optimization in that code, these strings must start on the same 256 byte page, 
+; which is checked at assembly time below.
+;
+g_szDetectStart:		
+g_szDetectMaster:		db	"Master",NULL 
+g_szDetectSlave:		db	"Slave ",NULL
+g_szDetectOuter:		db	"IDE %s at %s: ",NULL
+g_szDetectPort:			db	"%x",NULL					   	; IDE Master at 1F0h:
+g_szDetectCOM:			db  "COM%c%s",NULL            
+g_szDetectCOMAuto:		db	" Auto",NULL
+g_szDetectCOMSmall:		db	"/%u%u00",NULL					; IDE Master at COM1/9600:
+g_szDetectEnd:
+g_szDetectCOMLarge:		db	"/%u.%uK",NULL					; IDE Master at COM1/19.2K:
+		
+%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS				
+%if ((g_szDetectEnd-$$) & 0xff00) <> ((g_szDetectStart-$$) & 0xff00)
+%error "g_szDetect* strings must be on the same 256 byte page, required by DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP.  Please move this block up or down within strings.asm"
+%endif
+%endif				
 				
 ; Boot loader strings
@@ -137,10 +152,10 @@
 ;$translate{200}      = 18;    # DOUBLE_BOTTOM_LEFT_CORNER
 ;$translate{181}      = 19;    # DOUBLE_LEFT_HORIZONTAL_TO_SINGLE_VERTICAL
+;$translate{ord('0')} = 20;    # DOUBLE_LEFT_HORIZONTAL_TO_SINGLE_VERTICAL		
 ;
 ; Formats begin immediately after the last Translated character (they are in the same table)
 ;
-;$format_begin = 20;
+;$format_begin = 21;
 ;
-;$format{"s"}   = 20;        # n/a
 ;$format{"c"}   = 21;        # n/a
 ;$format{"2-I"} = 22;        # must be even
@@ -152,4 +167,5 @@
 ;$format{"2-u"} = 28;        # must be even
 ;$format{"A"}   = 29;        # n/a
+;$format{"s"}   = 30;        # n/a		
 ;
 ; NOTE: The last $format cannot exceed 31 (stored in a 5-bit quantity).
Index: /trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm	(revision 233)
@@ -20,32 +20,56 @@
 g_szRomAt:		; db	"%s @ %x",LF,CR,NULL
           		; db	 25h,  73h,  20h,  40h,  20h,  25h,  78h,  0ah,  0dh,  00h    ; uncompressed
-          		  db	 34h,  20h, 0c6h,  39h,  1bh                                  ; compressed
-
-
-g_szMaster:				; db	"IDE Master at ",NULL 
-           				; db	 49h,  44h,  45h,  20h,  4dh,  61h,  73h,  74h,  65h,  72h,  20h,  61h,  74h,  20h,  00h    ; uncompressed
-           				  db	 4fh,  4ah, 0cbh,  53h,  67h,  79h,  7ah,  6bh, 0f8h,  67h,  7ah,  00h                      ; compressed
-
-g_szSlave:				; db	"IDE Slave  at ",NULL
-          				; db	 49h,  44h,  45h,  20h,  53h,  6ch,  61h,  76h,  65h,  20h,  20h,  61h,  74h,  20h,  00h    ; uncompressed
-          				  db	 4fh,  4ah, 0cbh,  59h,  72h,  67h,  7ch, 0ebh,  20h,  67h,  7ah,  00h                      ; compressed
-
-g_szDetect:				; db	"%s%x: ",NULL					   ; IDE Master at 1F0h:
-           				; db	 25h,  73h,  25h,  78h,  3ah,  20h,  00h    ; uncompressed
-           				  db	 34h,  39h,  40h,  00h                      ; compressed
-
-g_szDetectCOM:			; db  "%sCOM%c/%u%c: ",NULL              ; IDE Master at COM1/115K:		
-              			; db   25h,  73h,  43h,  4fh,  4dh,  25h,  63h,  2fh,  25h,  75h,  25h,  63h,  3ah,  20h,  00h    ; uncompressed
-              			  db   34h,  49h,  55h,  53h,  35h,  2ah,  37h,  35h,  40h,  00h                                  ; compressed
-
-g_szDetectCOMAuto:		; db  "%sCOM Detect: ",NULL			   ; IDE Master at COM Detect:
-                  		; db   25h,  73h,  43h,  4fh,  4dh,  20h,  44h,  65h,  74h,  65h,  63h,  74h,  3ah,  20h,  00h    ; uncompressed
-                  		  db   34h,  49h,  55h, 0d3h,  4ah,  6bh,  7ah,  6bh,  69h,  7ah,  40h,  00h                      ; compressed
-
+          		  db	 3eh,  20h, 0c6h,  39h,  1bh                                  ; compressed
+
+
+; The following strings are used by DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP
+; To support an optimization in that code, these strings must start on the same 256 byte page, 
+; which is checked at assembly time below.
+;
+g_szDetectStart:		
+g_szDetectMaster:		; db	"Master",NULL 
+                 		; db	 4dh,  61h,  73h,  74h,  65h,  72h,  00h    ; uncompressed
+                 		  db	 53h,  67h,  79h,  7ah,  6bh, 0b8h          ; compressed
+
+g_szDetectSlave:		; db	"Slave ",NULL
+                		; db	 53h,  6ch,  61h,  76h,  65h,  20h,  00h    ; uncompressed
+                		  db	 59h,  72h,  67h,  7ch,  6bh,  00h          ; compressed
+
+g_szDetectOuter:		; db	"IDE %s at %s: ",NULL
+                		; db	 49h,  44h,  45h,  20h,  25h,  73h,  20h,  61h,  74h,  20h,  25h,  73h,  3ah,  20h,  00h    ; uncompressed
+                		  db	 4fh,  4ah, 0cbh,  3eh,  20h,  67h, 0fah,  3eh,  40h,  00h                                  ; compressed
+
+g_szDetectPort:			; db	"%x",NULL					   	; IDE Master at 1F0h:
+               			; db	 25h,  78h,  00h    ; uncompressed
+               			  db	 19h                ; compressed
+
+g_szDetectCOM:			; db  "COM%c%s",NULL            
+              			; db   43h,  4fh,  4dh,  25h,  63h,  25h,  73h,  00h    ; uncompressed
+              			  db   49h,  55h,  53h,  35h,  1eh                      ; compressed
+
+g_szDetectCOMAuto:		; db	" Auto",NULL
+                  		; db	 20h,  41h,  75h,  74h,  6fh,  00h    ; uncompressed
+                  		  db	 20h,  47h,  7bh,  7ah, 0b5h          ; compressed
+
+g_szDetectCOMSmall:		; db	"/%u%u00",NULL					; IDE Master at COM1/9600:
+                   		; db	 2fh,  25h,  75h,  25h,  75h,  30h,  30h,  00h    ; uncompressed
+                   		  db	 2ah,  37h,  37h,  34h,  14h                      ; compressed
+
+g_szDetectEnd:
+g_szDetectCOMLarge:		; db	"/%u.%uK",NULL					; IDE Master at COM1/19.2K:
+                   		; db	 2fh,  25h,  75h,  2eh,  25h,  75h,  4bh,  00h    ; uncompressed
+                   		  db	 2ah,  37h,  29h,  37h,  91h                      ; compressed
+
+
+%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS				
+%if ((g_szDetectEnd-$$) & 0xff00) <> ((g_szDetectStart-$$) & 0xff00)
+%error "g_szDetect* strings must be on the same 256 byte page, required by DetectPrint_StartDetectWithMasterOrSlaveStringInAXandIdeVarsInCSBP.  Please move this block up or down within strings.asm"
+%endif
+%endif				
 
 ; Boot loader strings
 g_szTryToBoot:			; db	"Booting from %s %x",ANGLE_QUOTE_RIGHT,"%x",LF,CR,NULL
               			; db	 42h,  6fh,  6fh,  74h,  69h,  6eh,  67h,  20h,  66h,  72h,  6fh,  6dh,  20h,  25h,  73h,  20h,  25h,  78h, 0afh,  25h,  78h,  0ah,  0dh,  00h    ; uncompressed
-              			  db	 48h,  75h,  75h,  7ah,  6fh,  74h, 0edh,  6ch,  78h,  75h, 0f3h,  34h,  20h,  39h,  24h,  39h,  1bh                                              ; compressed
+              			  db	 48h,  75h,  75h,  7ah,  6fh,  74h, 0edh,  6ch,  78h,  75h, 0f3h,  3eh,  20h,  39h,  24h,  39h,  1bh                                              ; compressed
 
 g_szBootSectorNotFound:	; db	"Boot sector "
@@ -77,5 +101,5 @@
 g_szHotkey:		; db	"%A%c%c%A%s%A ",NULL
            		; db	 25h,  41h,  25h,  63h,  25h,  63h,  25h,  41h,  25h,  73h,  25h,  41h,  20h,  00h    ; uncompressed
-           		  db	 3dh,  35h,  35h,  3dh,  34h,  3dh,  00h                                              ; compressed
+           		  db	 3dh,  35h,  35h,  3dh,  3eh,  3dh,  00h                                              ; compressed
 
 
@@ -88,5 +112,5 @@
 g_szFDLetter:	; db	"%s %c",NULL
              	; db	 25h,  73h,  20h,  25h,  63h,  00h    ; uncompressed
-             	  db	 34h,  20h,  15h                      ; compressed
+             	  db	 3eh,  20h,  15h                      ; compressed
 
 g_szFloppyDrv:	; db	"Floppy Drive",NULL
@@ -106,9 +130,9 @@
 g_szSizeSingle:	; db	"%s%u.%u %ciB",NULL
                	; db	 25h,  73h,  25h,  75h,  2eh,  25h,  75h,  20h,  25h,  63h,  69h,  42h,  00h    ; uncompressed
-               	  db	 34h,  37h,  29h,  37h,  20h,  35h,  6fh,  88h                                  ; compressed
+               	  db	 3eh,  37h,  29h,  37h,  20h,  35h,  6fh,  88h                                  ; compressed
 
 g_szSizeDual:	; db	"%s%5-u.%u %ciB /%5-u.%u %ciB",LF,CR,NULL
              	; db	 25h,  73h,  25h,  35h,  2dh,  75h,  2eh,  25h,  75h,  20h,  25h,  63h,  69h,  42h,  20h,  2fh,  25h,  35h,  2dh,  75h,  2eh,  25h,  75h,  20h,  25h,  63h,  69h,  42h,  0ah,  0dh,  00h    ; uncompressed
-             	  db	 34h,  38h,  29h,  37h,  20h,  35h,  6fh, 0c8h,  2ah,  38h,  29h,  37h,  20h,  35h,  6fh,  48h,  1bh                                                                                        ; compressed
+             	  db	 3eh,  38h,  29h,  37h,  20h,  35h,  6fh, 0c8h,  2ah,  38h,  29h,  37h,  20h,  35h,  6fh,  48h,  1bh                                                                                        ; compressed
 
 g_szCfgHeader:	; db	"Addr.",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",  SINGLE_VERTICAL,"IRQ",  SINGLE_VERTICAL,"Reset",LF,CR,NULL
@@ -118,5 +142,5 @@
 g_szCfgFormat:	; db	"%s"   ,SINGLE_VERTICAL,"%5-u", SINGLE_VERTICAL,"%s",SINGLE_VERTICAL," %2-I",SINGLE_VERTICAL,"%5-x",  NULL
               	; db	 25h,  73h, 0b3h,  25h,  35h,  2dh,  75h, 0b3h,  25h,  73h, 0b3h,  20h,  25h,  32h,  2dh,  49h, 0b3h,  25h,  35h,  2dh,  78h,  00h    ; uncompressed
-              	  db	 34h,  23h,  38h,  23h,  34h,  23h,  20h,  36h,  23h,  1ah                                                                            ; compressed
+              	  db	 3eh,  23h,  38h,  23h,  3eh,  23h,  20h,  36h,  23h,  1ah                                                                            ; compressed
 
 
@@ -159,13 +183,13 @@
 g_szFddUnknown:	; db	"%sUnknown",NULL
                	; db	 25h,  73h,  55h,  6eh,  6bh,  6eh,  6fh,  77h,  6eh,  00h    ; uncompressed
-               	  db	 34h,  5bh,  74h,  71h,  74h,  75h,  7dh, 0b4h                ; compressed
+               	  db	 3eh,  5bh,  74h,  71h,  74h,  75h,  7dh, 0b4h                ; compressed
 
 g_szFddSizeOr:	; db	"%s5",ONE_QUARTER,QUOTATION_MARK," or 3",ONE_HALF,QUOTATION_MARK," DD",NULL
               	; db	 25h,  73h,  35h, 0ach,  22h,  20h,  6fh,  72h,  20h,  33h, 0abh,  22h,  20h,  44h,  44h,  00h    ; uncompressed
-              	  db	 34h,  2fh,  21h,  26h,  20h,  75h, 0f8h,  2dh,  22h,  26h,  20h,  4ah,  8ah                      ; compressed
+              	  db	 3eh,  2fh,  21h,  26h,  20h,  75h, 0f8h,  2dh,  22h,  26h,  20h,  4ah,  8ah                      ; compressed
 
 g_szFddSize:	; db	"%s%s",QUOTATION_MARK,", %u kiB",NULL	; 3½", 1440 kiB
             	; db	 25h,  73h,  25h,  73h,  22h,  2ch,  20h,  25h,  75h,  20h,  6bh,  69h,  42h,  00h    ; uncompressed
-            	  db	 34h,  34h,  26h,  27h,  20h,  37h,  20h,  71h,  6fh,  88h                            ; compressed
+            	  db	 3eh,  3eh,  26h,  27h,  20h,  37h,  20h,  71h,  6fh,  88h                            ; compressed
 
 
@@ -265,10 +289,10 @@
 ;$translate{200}      = 18;    # DOUBLE_BOTTOM_LEFT_CORNER    [StringsCompress Processed]
 ;$translate{181}      = 19;    # DOUBLE_LEFT_HORIZONTAL_TO_SINGLE_VERTICAL    [StringsCompress Processed]
+;$translate{ord('0')} = 20;    # DOUBLE_LEFT_HORIZONTAL_TO_SINGLE_VERTICAL		    [StringsCompress Processed]
 ;
 ; Formats begin immediately after the last Translated character (they are in the same table)
 ;
-;$format_begin = 20;    [StringsCompress Processed]
-;
-;$format{"s"}   = 20;        # n/a    [StringsCompress Processed]
+;$format_begin = 21;    [StringsCompress Processed]
+;
 ;$format{"c"}   = 21;        # n/a    [StringsCompress Processed]
 ;$format{"2-I"} = 22;        # must be even    [StringsCompress Processed]
@@ -280,4 +304,5 @@
 ;$format{"2-u"} = 28;        # must be even    [StringsCompress Processed]
 ;$format{"A"}   = 29;        # n/a    [StringsCompress Processed]
+;$format{"s"}   = 30;        # n/a		    [StringsCompress Processed]
 ;
 ; NOTE: The last $format cannot exceed 31 (stored in a 5-bit quantity).
@@ -299,5 +324,5 @@
 StringsCompressed_NormalBase     equ   58
 
-StringsCompressed_FormatsBegin   equ   20
+StringsCompressed_FormatsBegin   equ   21
 
 StringsCompressed_TranslatesAndFormats: 
@@ -322,5 +347,5 @@
         db     200  ; 18
         db     181  ; 19
-        db     (DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_s)    ; 20
+        db     48  ; 20
         db     (DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_c)    ; 21
         db     (DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_2_I)    ; 22
@@ -332,35 +357,36 @@
         db     (DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_2_u)    ; 28
         db     (DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_A)    ; 29
+        db     (DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_s)    ; 30
 
 %ifndef CHECK_FOR_UNUSED_ENTRYPOINTS
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_c || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_c > 255
+%error "DisplayFormatCompressed_Format_c is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_2_I || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_2_I > 255
+%error "DisplayFormatCompressed_Format_2_I is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_u || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_u > 255
+%error "DisplayFormatCompressed_Format_u is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_5_u || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_5_u > 255
+%error "DisplayFormatCompressed_Format_5_u is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_x || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_x > 255
+%error "DisplayFormatCompressed_Format_x is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_5_x || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_5_x > 255
+%error "DisplayFormatCompressed_Format_5_x is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_nl || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_nl > 255
+%error "DisplayFormatCompressed_Format_nl is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_2_u || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_2_u > 255
+%error "DisplayFormatCompressed_Format_2_u is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
+%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_A || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_A > 255
+%error "DisplayFormatCompressed_Format_A is out of range of DisplayFormatCompressed_BaseFormatOffset"
+%endif
 %if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_s || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_s > 255
 %error "DisplayFormatCompressed_Format_s is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_c || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_c > 255
-%error "DisplayFormatCompressed_Format_c is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_2_I || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_2_I > 255
-%error "DisplayFormatCompressed_Format_2_I is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_u || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_u > 255
-%error "DisplayFormatCompressed_Format_u is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_5_u || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_5_u > 255
-%error "DisplayFormatCompressed_Format_5_u is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_x || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_x > 255
-%error "DisplayFormatCompressed_Format_x is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_5_x || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_5_x > 255
-%error "DisplayFormatCompressed_Format_5_x is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_nl || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_nl > 255
-%error "DisplayFormatCompressed_Format_nl is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_2_u || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_2_u > 255
-%error "DisplayFormatCompressed_Format_2_u is out of range of DisplayFormatCompressed_BaseFormatOffset"
-%endif
-%if DisplayFormatCompressed_BaseFormatOffset < DisplayFormatCompressed_Format_A || DisplayFormatCompressed_BaseFormatOffset - DisplayFormatCompressed_Format_A > 255
-%error "DisplayFormatCompressed_Format_A is out of range of DisplayFormatCompressed_BaseFormatOffset"
 %endif
 %endif
@@ -374,14 +400,14 @@
 ;; 5-u:3
 ;; x:6
+;; s:15
 ;; 5-x:1
-;; s:15
 ;; nl:6
 ;; 2-I:1
-;; c:8
-;; u:6
+;; c:7
+;; u:9
 ;; total format: 10
 
 ;; alphabet usage stats
-;; 58,::4
+;; 58,::2
 ;; 59,;:
 ;; 60,<:
@@ -390,19 +416,19 @@
 ;; 63,?:
 ;; 64,@:1
-;; 65,A:3
+;; 65,A:4
 ;; 66,B:11
-;; 67,C:5
-;; 68,D:12
-;; 69,E:4
+;; 67,C:4
+;; 68,D:10
+;; 69,E:3
 ;; 70,F:3
 ;; 71,G:
 ;; 72,H:4
-;; 73,I:3
+;; 73,I:2
 ;; 74,J:
-;; 75,K:
+;; 75,K:1
 ;; 76,L:3
-;; 77,M:4
+;; 77,M:3
 ;; 78,N:
-;; 79,O:3
+;; 79,O:2
 ;; 80,P:1
 ;; 81,Q:1
@@ -422,9 +448,9 @@
 ;; 95,_:
 ;; 96,`:
-;; 97,a:7
+;; 97,a:6
 ;; 98,b:
-;; 99,c:5
+;; 99,c:4
 ;; 100,d:4
-;; 101,e:11
+;; 101,e:9
 ;; 102,f:2
 ;; 103,g:2
@@ -436,14 +462,14 @@
 ;; 109,m:1
 ;; 110,n:9
-;; 111,o:17
+;; 111,o:18
 ;; 112,p:3
 ;; 113,q:
 ;; 114,r:11
 ;; 115,s:6
-;; 116,t:13
-;; 117,u:2
+;; 116,t:11
+;; 117,u:3
 ;; 118,v:2
 ;; 119,w:1
 ;; 120,x:
 ;; 121,y:2
-;; alphabet used count: 39
+;; alphabet used count: 40
Index: /trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm	(revision 233)
@@ -124,7 +124,8 @@
 
 ;--------------------------------------------------------------------
-; IterateToDptWithInterruptInServiceFlagSet
+; IterateToDptWithFlagsHighInBL
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT to examine
+;       BL:		Bit(s) to test in DPT.bFlagsHigh 
 ;	Returns:
 ;		CF:		Set if wanted DPT found
@@ -134,7 +135,7 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-IterateToDptWithInterruptInServiceFlagSet:
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE		; Clears CF (but we need the clc
-																		; below anyway for callers above)
+IterateToDptWithFlagsHighInBL:		
+	test	BYTE [di+DPT.bFlagsHigh], bl		; Clears CF (but we need the clc
+												; below anyway for callers above)
 	jnz		SHORT ReturnRightDPT
 
@@ -144,5 +145,5 @@
 
 ;--------------------------------------------------------------------
-; FindDPT_ToDSDIforInterruptInService
+; FindDPT_ToDSDIforSerialDevice
 ;	Parameters:
 ;		DS:		RAMVARS segment
@@ -154,7 +155,24 @@
 ;		SI
 ;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-FindDPT_ToDSDIforInterruptInService:
-	mov		si, IterateToDptWithInterruptInServiceFlagSet
+ALIGN JUMP_ALIGN		
+FindDPT_ToDSDIforSerialDevice:			
+	mov		bl, FLGH_DPT_SERIAL_DEVICE
+; fall-through
+				
+;--------------------------------------------------------------------
+; FindDPT_ToDSDIforFlagsHigh
+;	Parameters:
+;		DS:		RAMVARS segment
+;       BL:		Bit(s) to test in DPT.bFlagsHigh
+;	Returns:
+;		DS:DI:	Ptr to DPT
+;		CF:		Set if wanted DPT found
+;				Cleared if DPT not found
+;	Corrupts registers:
+;		SI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FindDPT_ToDSDIforFlagsHighInBL:		
+	mov		si, IterateToDptWithFlagsHighInBL
 	; Fall to IterateAllDPTs
 
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialBaud.txt
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialBaud.txt	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialBaud.txt	(revision 233)
@@ -1,1 +1,1 @@
-Supported baud rates are 2400, 9600, 38.4K, and 115.2K. The server must also be set to this same speed. Older UARTs may only support 2400 and 9600 baud, but sometimes can be pushed to 38.4K. 115.2K will likely only be possible with a newer UART that inclues a FIFO. Some high speed serial ports include UART clock multipliers, allowing for speeds at 230.4K (2x multiplier) and 460.8K (4x multiplier). These high speeds are supported by these BIOS, even on original 4.77MHz 8088 systems. Note that UART clock multipliers are not detectable by the software and 115.2K will still be used during configuration for high speeds; but if a multiplier is used, the actual speed (including the multiplier) will need to be used on the server.
+Supported baud rates are 2400, 4800, 9600, 19.2K, 28.8K, 38.4K, 57.6K, and 115.2K. The server must also be set to this same speed. Older UARTs may only support up to 9600 baud, but sometimes can be pushed to 38.4K. 115.2K will likely only be possible with a newer UART that inclues a FIFO. Some high speed serial ports include UART clock multipliers, allowing for speeds at 230.4K (2x multiplier) and 460.8K (4x multiplier) above 115.2K. These high speeds are supported by these BIOS, even on original 4.77MHz 8088 systems. Note that UART clock multipliers are not detectable by the software and 115.2K will still be used during configuration for high speeds; but if a multiplier is used, the actual speed (including the multiplier) will need to be used by the server.
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialCOM.txt
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialCOM.txt	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialCOM.txt	(revision 233)
@@ -1,1 +1,1 @@
-Select a serial port by COM port number. COM1 through COM4 have well established I/O port assignments, COM5 and onward are less well established. "COMA" represents COM10, "COMB" represents COM11, and "COMC" represents COM12. Selecting COMx enables the manual selection of an I/O port address.
+Select a serial port by COM port number. COM1 through COM4 have well established I/O port assignments, COM5 and onward are less well established. "COMA" represents COM10, "COMB" represents COM11, and "COMC" represents COM12. Selecting "COMx" enables the manual selection of an I/O port address.
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialPort.txt
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialPort.txt	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Help/IDE_SerialPort.txt	(revision 233)
@@ -1,1 +1,1 @@
-Select a serial port by I/O address. Supported values are between 240h and 430h, and must be on an 8-byte boundary. If the entered value corresponds to one of the established COM port numbers, then the selection of serial port will use COM numbers instead.
+Select a serial port by I/O address. Any port address is supported up to 3f8h, but must be on an 8-byte boundary. If the entered value corresponds to one of the established COM port numbers, then the selection will snap to that COM port and "COMx" must be selected again for custom I/O address entry.
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/MenuStructs.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/MenuStructs.inc	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/MenuStructs.inc	(revision 233)
@@ -30,4 +30,6 @@
 FLG_MENUITEM_BYTEVALUE		EQU	(1<<3)	; Item value is single byte
 FLG_MENUITEM_PROGRAMVAR		EQU	(1<<4)	; Item is for configuring program, not BIOS
+FLG_MENUITEM_CHOICESTRINGS  EQU (1<<5)  ; ChoiceToStringLookup table is 1-1 with ChoiceToValueLookup table, 
+										; ChoiceToStringLookup table must also NULL terminated
 
 ; Values for MENUITEM.bType
@@ -47,4 +49,5 @@
 	.rgwChoiceToValueLookup	resb	2	; Ptr to lookup table for translating selected choice to actual value
 	.rgszValueToStringLookup:			; Ptr to lookup table for translating value to string
+	.rgszChoiceToStringLookup:
 	.wMinValue				resb	2	; Minimum allowed integer value
 	.wMaxValue:
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menuitem.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menuitem.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menuitem.asm	(revision 233)
@@ -289,4 +289,10 @@
 	mov		ax, [es:di]
 
+	test	BYTE [si+MENUITEM.bFlags], FLG_MENUITEM_BYTEVALUE
+	jz		SHORT .NoConvertWordToByteValue
+	xor		ah, ah				; conversion needs to happen before call to the reader,
+								; in case the reader unpacks the byte to a word
+		
+.NoConvertWordToByteValue:
 	mov		bx, [si+MENUITEM.itemValue+ITEM_VALUE.fnValueReader]
 	test	bx,bx
@@ -300,6 +306,4 @@
 	pop		es
 
-	test	BYTE [si+MENUITEM.bFlags], FLG_MENUITEM_BYTEVALUE
-	jnz		SHORT .ConvertWordToByteValue
 	test	BYTE [si+MENUITEM.bFlags], FLG_MENUITEM_FLAGVALUE
 	jz		SHORT .Return
@@ -309,7 +313,5 @@
 	jnz		SHORT .Return
 	xor		ax, ax
-ALIGN JUMP_ALIGN
-.ConvertWordToByteValue:
-	xor		ah, ah
+
 ALIGN JUMP_ALIGN, ret
 .Return:
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/MenuitemPrint.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/MenuitemPrint.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/MenuitemPrint.asm	(revision 233)
@@ -156,4 +156,5 @@
 ALIGN JUMP_ALIGN
 MenuitemPrint_WriteLookupValueStringToBufferInESDIfromShiftedItemInDSSI:
+MenuitemPrint_WriteLookupValueStringToBufferInESDIfromRawItemInDSSI:
 	call	Menuitem_GetValueToAXfromMenuitemInDSSI
 	; Fall to PrintLookupValueFromAXtoBufferInESDI
@@ -173,11 +174,42 @@
 PrintLookupValueFromAXtoBufferInESDI:
 	push	si
+	test	byte [si+MENUITEM.bFlags], FLG_MENUITEM_CHOICESTRINGS
+	jnz		.lookupChoice	
+		
 	add		ax, [si+MENUITEM.itemValue+ITEM_VALUE.rgszValueToStringLookup]
 	xchg	bx, ax
+.found:	
 	mov		si, [bx]
+.errorReturn:
 	call	String_CopyDSSItoESDIandGetLengthToCX
 	pop		si
 	ret
 
+;
+; With FLG_MENUITEM_CHOICESTRINGS, the array at .rgszChoiceToStringLookup is based on the 
+; Choice number (offset within .rgwChoiceToValueLookup) instead of the value stored.
+; Here, we scan the .rgwChoiceToValueLookup array until we find the value there, and then
+; use the same offset in .rgszChoiceToStringLookup.  If we don't find the value, we 
+; return an "Error!" string instead.  
+;
+; Note that the pointer array at .rgszChoiceToStringLookup must be NULL terminated.  Since the
+; value could be zero, we don't use the .rgwChoiceToValueLookup array to find the end.
+;
+.lookupChoice:
+	mov		bx,[si+MENUITEM.itemValue+ITEM_VALUE.rgszChoiceToStringLookup]		
+	mov		si,[si+MENUITEM.itemValue+ITEM_VALUE.rgwChoiceToValueLookup]
+		
+.wordLoop:
+	cmp		ax,[si]
+	jz		.found
+	inc		si
+	inc		si
+	inc		bx
+	inc		bx
+	cmp		word [bx],0
+	jnz		.wordLoop
+
+	mov		si,g_szValueUnknownError
+	jmp		.errorReturn
 
 ;--------------------------------------------------------------------
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/IdeControllerMenu.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/IdeControllerMenu.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/IdeControllerMenu.asm	(revision 233)
@@ -46,5 +46,5 @@
 istruc MENUITEM
 	at	MENUITEM.fnActivate,		dw	Menuitem_ActivateMultichoiceSelectionForMenuitemInDSSI
-	at	MENUITEM.fnFormatValue,		dw	MenuitemPrint_WriteLookupValueStringToBufferInESDIfromShiftedItemInDSSI
+	at	MENUITEM.fnFormatValue,		dw	MenuitemPrint_WriteLookupValueStringToBufferInESDIfromRawItemInDSSI
 	at	MENUITEM.szName,			dw	g_szItemIdeDevice
 	at	MENUITEM.szQuickInfo,		dw	g_szNfoIdeDevice
@@ -93,16 +93,15 @@
 istruc MENUITEM
 	at	MENUITEM.fnActivate,		dw	Menuitem_ActivateMultichoiceSelectionForMenuitemInDSSI
-	at	MENUITEM.fnFormatValue,		dw	MenuitemPrint_WriteLookupValueStringToBufferInESDIfromUnshiftedItemInDSSI
+	at	MENUITEM.fnFormatValue,		dw	MenuitemPrint_WriteLookupValueStringToBufferInESDIfromRawItemInDSSI
 	at	MENUITEM.szName,			dw	g_szItemSerialCOM
 	at	MENUITEM.szQuickInfo,		dw	g_szNfoIdeSerialCOM
 	at	MENUITEM.szHelp,			dw	g_szHelpIdeSerialCOM
-	at	MENUITEM.bFlags,			db	FLG_MENUITEM_MODIFY_MENU
+	at	MENUITEM.bFlags,			db	FLG_MENUITEM_MODIFY_MENU | FLG_MENUITEM_BYTEVALUE | FLG_MENUITEM_CHOICESTRINGS
 	at	MENUITEM.bType,				db	TYPE_MENUITEM_MULTICHOICE 
 	at	MENUITEM.itemValue + ITEM_VALUE.wRomvarsValueOffset,		dw	NULL
 	at	MENUITEM.itemValue + ITEM_VALUE.szDialogTitle,				dw	g_szDlgDevice
 	at	MENUITEM.itemValue + ITEM_VALUE.szMultichoice,				dw	g_szSerialCOMChoice
-	at	MENUITEM.itemValue + ITEM_VALUE.rgwChoiceToValueLookup,		dw	NULL
-	at	MENUITEM.itemValue + ITEM_VALUE.rgszValueToStringLookup,	dw	g_rgszValueToStringLookupForCOM
-	at	MENUITEM.itemValue + ITEM_VALUE.fnValueReader,				dw	IdeControllerMenu_SerialReadCOM  
+	at	MENUITEM.itemValue + ITEM_VALUE.rgwChoiceToValueLookup,		dw	g_rgbChoiceToValueLookupForCOM
+	at	MENUITEM.itemValue + ITEM_VALUE.rgszChoiceToStringLookup,	dw	g_rgszChoiceToStringLookupForCOM
 	at	MENUITEM.itemValue + ITEM_VALUE.fnValueWriter,				dw	IdeControllerMenu_SerialWriteCOM
 iend
@@ -115,10 +114,10 @@
 	at	MENUITEM.szQuickInfo,		dw	g_szNfoIdeSerialPort
 	at	MENUITEM.szHelp,			dw	g_szHelpIdeSerialPort
-	at	MENUITEM.bFlags,			db	FLG_MENUITEM_MODIFY_MENU		
+	at	MENUITEM.bFlags,			db	FLG_MENUITEM_MODIFY_MENU | FLG_MENUITEM_BYTEVALUE
 	at	MENUITEM.bType,				db	TYPE_MENUITEM_HEX
 	at	MENUITEM.itemValue + ITEM_VALUE.wRomvarsValueOffset,		dw	NULL
 	at	MENUITEM.itemValue + ITEM_VALUE.szDialogTitle,				dw	g_szDlgIdeCmdPort
-	at	MENUITEM.itemValue + ITEM_VALUE.wMinValue,					dw	DEVICE_SERIAL_PACKEDPORTANDBAUD_MINPORT
-	at	MENUITEM.itemValue + ITEM_VALUE.wMaxValue,					dw	DEVICE_SERIAL_PACKEDPORTANDBAUD_MAXPORT
+	at	MENUITEM.itemValue + ITEM_VALUE.wMinValue,					dw	8h
+	at	MENUITEM.itemValue + ITEM_VALUE.wMaxValue,					dw	3f8h
 	at	MENUITEM.itemValue + ITEM_VALUE.fnValueReader,				dw	IdeControllerMenu_SerialReadPort
 	at	MENUITEM.itemValue + ITEM_VALUE.fnValueWriter,				dw	IdeControllerMenu_SerialWritePort
@@ -128,16 +127,15 @@
 istruc MENUITEM
 	at	MENUITEM.fnActivate,		dw	Menuitem_ActivateMultichoiceSelectionForMenuitemInDSSI
-	at	MENUITEM.fnFormatValue,		dw	MenuitemPrint_WriteLookupValueStringToBufferInESDIfromUnshiftedItemInDSSI
+	at	MENUITEM.fnFormatValue,		dw	MenuitemPrint_WriteLookupValueStringToBufferInESDIfromRawItemInDSSI
 	at	MENUITEM.szName,			dw	g_szItemSerialBaud
 	at	MENUITEM.szQuickInfo,		dw	g_szNfoIdeSerialBaud
 	at	MENUITEM.szHelp,			dw	g_szHelpIdeSerialBaud
+	at	MENUITEM.bFlags,			db	FLG_MENUITEM_BYTEVALUE | FLG_MENUITEM_CHOICESTRINGS
 	at	MENUITEM.bType,				db	TYPE_MENUITEM_MULTICHOICE
 	at	MENUITEM.itemValue + ITEM_VALUE.wRomvarsValueOffset,		dw	NULL
 	at	MENUITEM.itemValue + ITEM_VALUE.szDialogTitle,				dw	g_szDlgDevice
 	at	MENUITEM.itemValue + ITEM_VALUE.szMultichoice,				dw	g_szSerialBaudChoice
-	at	MENUITEM.itemValue + ITEM_VALUE.rgwChoiceToValueLookup,		dw	NULL
-	at	MENUITEM.itemValue + ITEM_VALUE.rgszValueToStringLookup,	dw	g_rgszValueToStringLookupForBaud
-	at	MENUITEM.itemValue + ITEM_VALUE.fnValueReader,				dw	IdeControllerMenu_SerialReadBaud
-	at	MENUITEM.itemValue + ITEM_VALUE.fnValueWriter,				dw	IdeControllerMenu_SerialWriteBaud
+	at	MENUITEM.itemValue + ITEM_VALUE.rgwChoiceToValueLookup,		dw	g_rgbChoiceToValueLookupForBaud
+	at	MENUITEM.itemValue + ITEM_VALUE.rgszChoiceToStringLookup,	dw	g_rgszChoiceToStringLookupForBaud
 iend
 		
@@ -188,5 +186,19 @@
 	dw	g_szValueCfgDeviceSerial
 
-g_rgszValueToStringLookupForCOM:		
+g_rgbChoiceToValueLookupForCOM:
+	dw	'1'
+	dw	'2'
+	dw	'3'
+	dw	'4'
+	dw	'5'
+	dw	'6'
+	dw	'7'
+	dw	'8'
+	dw	'9'
+	dw	'A'
+	dw	'B'
+	dw	'C'
+	dw	'x'				; must be last entry (see reader/write routines)
+g_rgszChoiceToStringLookupForCOM:		
 	dw	g_szValueCfgCOM1
 	dw	g_szValueCfgCOM2
@@ -202,16 +214,44 @@
 	dw	g_szValueCfgCOMC
 	dw	g_szValueCfgCOMx
-
-g_rgszValueToStringLookupForBaud:
-	dw	g_szValueCfgBaud2400
-	dw	g_szValueCfgBaud9600
-	dw	g_szValueCfgBaud38_4
-	dw	g_szValueCfgBaud115_2
-
-g_wPrintBaud:
-	dw	DEVICE_SERIAL_PRINTBAUD_2400
-	dw	DEVICE_SERIAL_PRINTBAUD_9600
-	dw	DEVICE_SERIAL_PRINTBAUD_38_4
-	dw	DEVICE_SERIAL_PRINTBAUD_115_2
+	dw	NULL
+
+DEVICE_SERIAL_DEFAULT_CUSTOM_PORT   EQU		300h           ; can't be any of the pre-defined COM values
+
+PackedCOMPortAddresses:				; COM1 - COMC (or COM12)
+	db      DEVICE_SERIAL_COM1 >> 2
+	db		DEVICE_SERIAL_COM2 >> 2 
+	db		DEVICE_SERIAL_COM3 >> 2 
+	db		DEVICE_SERIAL_COM4 >> 2 
+	db		DEVICE_SERIAL_COM5 >> 2 
+	db		DEVICE_SERIAL_COM6 >> 2 
+	db		DEVICE_SERIAL_COM7 >> 2 
+	db		DEVICE_SERIAL_COM8 >> 2 
+	db		DEVICE_SERIAL_COM9 >> 2 
+	db		DEVICE_SERIAL_COMA >> 2 
+	db		DEVICE_SERIAL_COMB >> 2 
+	db		DEVICE_SERIAL_COMC >> 2
+	db		DEVICE_SERIAL_DEFAULT_CUSTOM_PORT >> 2			; must be last entry (see reader/writer routines)
+DEVICE_SERIAL_DEFAULT_COM			EQU		'1'
+		
+g_rgbChoiceToValueLookupForBaud:
+	dw		(115200 / 115200) & 0xff
+	dw		(115200 /  57600) & 0xff
+	dw		(115200 /  38400) & 0xff
+	dw		(115200 /  28800) & 0xff
+	dw		(115200 /  19200) & 0xff
+	dw		(115200 /   9600) & 0xff
+	dw		(115200 /   4800) & 0xff
+	dw		(115200 /   2400) & 0xff
+g_rgszChoiceToStringLookupForBaud:
+	dw		g_szValueCfgBaud115_2
+	dw		g_szValueCfgBaud57_6
+	dw		g_szValueCfgBaud38_4
+	dw		g_szValueCfgBaud28_8
+	dw		g_szValueCfgBaud19_2
+	dw		g_szValueCfgBaud9600
+	dw		g_szValueCfgBaud4800
+	dw		g_szValueCfgBaud2400
+	dw		NULL
+DEVICE_SERIAL_DEFAULT_BAUD			EQU		((115200 / 9600)	& 0xff)
 
 ; Section containing code
@@ -240,11 +280,16 @@
 	lea		ax, [bx+IDEVARS.wPort]
 	mov		[cs:g_MenuitemIdeControllerCommandBlockAddress+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset], ax
+		
+	lea		ax, [bx+IDEVARS.bSerialPort]		
 	mov		[cs:g_MenuitemIdeControllerSerialPort+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset], ax
-	mov		[cs:g_MenuitemIdeControllerSerialCOM+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset], ax		
+
+	lea		ax, [bx+IDEVARS.bSerialBaud]
 	mov		[cs:g_MenuitemIdeControllerSerialBaud+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset], ax
-				;; baud also modifies the next two bytes (print chars in wPortCtrl), but it never reads them
 		
 	lea		ax, [bx+IDEVARS.wPortCtrl]
 	mov		[cs:g_MenuitemIdeControllerControlBlockAddress+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset], ax
+		
+	lea		ax, [bx+IDEVARS.bSerialCOMPortChar]
+	mov		[cs:g_MenuitemIdeControllerSerialCOM+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset], ax				
 
 	lea		ax, [bx+IDEVARS.bIRQ]
@@ -382,21 +427,22 @@
 ALIGN JUMP_ALIGN
 DisplayMasterSlaveMenu:
+;
+; block mode is not supported on serial drives, disable/enable the option as appropriate
+;
+	push	bx
+	mov		bx, [cs:g_MenuitemIdeControllerDevice+MENUITEM.itemValue+ITEM_VALUE.wRomvarsValueOffset]		
+	call	Buffers_GetRomvarsValueToAXfromOffsetInBX
+	mov		bx, g_MenuitemMasterSlaveBlockModeTransfers
+	cmp		al,DEVICE_SERIAL_PORT
+	jz		.isSerial
+	or		BYTE [cs:bx+MENUITEM.bFlags], FLG_MENUITEM_VISIBLE
+	jmp		.isDone
+.isSerial:		
+	and		BYTE [cs:bx+MENUITEM.bFlags], ~FLG_MENUITEM_VISIBLE
+.isDone:
+	pop		bx
+			
 	call	MasterSlaveMenu_InitializeToDrvparamsOffsetInBX
 	jmp		MasterSlaveMenu_EnterMenuOrModifyItemVisibility
-
-PackedCOMPortAddresses:				; COM1 - COMC (or COM12)
-	db      (DEVICE_SERIAL_COM1 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COM2 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COM3 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COM4 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1   
-	db		(DEVICE_SERIAL_COM5 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COM6 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COM7 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1   
-	db		(DEVICE_SERIAL_COM8 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1   
-	db		(DEVICE_SERIAL_COM9 - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COMA - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1   
-	db		(DEVICE_SERIAL_COMB - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1
-	db		(DEVICE_SERIAL_COMC - DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT) >> 1  
-	db		0						; null terminated
 
 ;------------------------------------------------------------------------------------------
@@ -474,16 +520,11 @@
 		jz		.done								; if we were already serial, nothing to do
 
-		mov		ax,DEVICE_SERIAL_DEFAULT_COM
+		mov		byte [es:di+IDEVARS.bSerialBaud-IDEVARS.wPort],DEVICE_SERIAL_DEFAULT_BAUD
+
+		mov		al,DEVICE_SERIAL_DEFAULT_COM
+		add		di,IDEVARS.bSerialCOMPortChar-IDEVARS.wPort
 		call	IdeControllerMenu_SerialWriteCOM
-		mov		[es:di],ax
-		
-		mov		ax,DEVICE_SERIAL_DEFAULT_BAUD
-		call	IdeControllerMenu_SerialWriteBaud
-		mov		[es:di],ax
+		mov		[es:di],al
 				
-		add		di,IDEVARS.bIRQ - IDEVARS.wPort		; clear out the interrupt information, we don't use interrupts
-		mov		al,0
-		mov		[es:di],al
-
 .done:	
 		pop		di
@@ -494,133 +535,96 @@
 
 ;
-; "COMn" ASCII characer -> Numeric COM number
-;
-ALIGN JUMP_ALIGN
-IdeControllerMenu_SerialReadCOM:
-		xor		ah,ah								; clear out packedportbaud value
-
-		cmp		al,'x'								; base this on the ASCII character used to print
-		jz		.custom
-
-		cmp		al,'A'
-		jae		.over10
-
-		sub		al, '0'+1							; convert ASCII value '0'-'9' to numeric
+; Doesn't modify COM character (unless it is not recognized, which would be an error case),
+; But does update the port address based on COM port selection  
+;				
+ALIGN JUMP_ALIGN
+IdeControllerMenu_SerialWriteCOM:
+		push	ax
+		push	bx
+		push	si
+		
+		mov		si,g_rgbChoiceToValueLookupForCOM
+		mov		bx,PackedCOMPortAddresses
+
+.loop:
+		mov		ah,[bx]
+
+		cmp		ah,(DEVICE_SERIAL_DEFAULT_CUSTOM_PORT >> 2)
+		jz		.notFound
+		
+		cmp		al,[si]
+		jz		.found
+		
+		inc		si
+		inc		si
+		inc		bx
+		
+		jmp		.loop
+
+.notFound:
+		mov		al, 'x'
+		
+.found:			
+		mov		[es:di+IDEVARS.bSerialPort-IDEVARS.bSerialCOMPortChar], ah
+
+		pop		si
+		pop		bx
+		pop		ax
+		
 		ret
-
-.over10:
-		sub		al, 'A'-10+1						; convert ASCII value 'A'-'C' to numeric
+		
+
+;
+; Packed Port (byte) -> Numeric Port (word)
+;				
+ALIGN JUMP_ALIGN
+IdeControllerMenu_SerialReadPort:
+		xor		ah,ah
+		shl		ax,1
+		shl		ax,1
 		ret
 
-.custom:
-		mov		al, 12								; convert ASCII value 'x' (for custom) to numeric
-		ret
-
-;
-; Numeric COM number -> Packed port address, and update ASCII character for printing "COMn"
-;				
-ALIGN JUMP_ALIGN
-IdeControllerMenu_SerialWriteCOM:
-		push	bx
-
-		cmp		al,12								; custom?
-		jge		.custom
-
-		mov		bx,ax								; lookup packed port address based on COM address
-		mov		ah,[cs:bx+PackedCOMPortAddresses]
-
-		cmp		al,9								; COMA or higher, but not custom
-		jge		.atorabove10
-
-		add		al, '0'+1							; convert numeric to ASCII '1' to '9'
-		jmp		IdeControllerMenu_SerialWriteCOM_PackAndRet
-
-.custom:
-		mov		al,'x'								; ASCII value 'x' for custom
-		mov		ah,1 << DEVICE_SERIAL_PACKEDPORTANDBAUD_PORT_FIELD_POSITION	; 248h 
-		jmp		IdeControllerMenu_SerialWriteCOM_PackAndRet
-
-.atorabove10:
-		add		al, 'A'-10+1						; convert numeric to ASCII 'A' to 'C'
-
-IdeControllerMenu_SerialWriteCOM_PackAndRet:
-		mov		bl,[es:di+1]						; read baud rate bits
-		and		bl,DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDMASK  	
-		or		ah,bl
-
-		pop		bx
-		ret		
-
-;
-; Packed Baud -> Numeric Baud
-;				
-ALIGN JUMP_ALIGN
-IdeControllerMenu_SerialReadBaud:
-		xchg	al,ah
-		and		ax,DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDMASK			; also clears high order byte
-		ret
-
-;
-; Numeric Baud -> Packed Baud, also update ASCII printing characters for baud rate
-;				
-ALIGN JUMP_ALIGN
-IdeControllerMenu_SerialWriteBaud:
-		and		ax,DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDBITS 		; ensure we only have the bits we want
-		
-		push	bx
-
-		mov		bx,ax												; lookup printing word for wPortCtrl
-		shl		bx,1
-		mov		bx,[cs:bx+g_wPrintBaud]
-		mov		[es:di+2],bx
-
-		xchg	al,ah												; or in port bits
-		mov		bx,[es:di]
-		and		bh,DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTMASK 
-		or		ax,bx
-
-		pop		bx
-		ret
-
-;
-; Packed Port -> Numeric Port
-;				
-ALIGN JUMP_ALIGN
-IdeControllerMenu_SerialReadPort:		
-		mov		al,ah
-		and		ax,DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTMASK    		; note that this clears AH
-		shl		ax,1
-		add		ax,DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT
-		ret
-
-;
-; Numeric Port -> Packed Port, convert from Custom to a defined COM port if we match one
+;
+; Numeric Port (word) -> Packed Port (byte)
+; And convert from Custom to a defined COM port if we match one of the pre-defined COM port numbers
 ;
 ALIGN JUMP_ALIGN
 IdeControllerMenu_SerialWritePort:		
 		push	bx
-
-		sub		ax,DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT		; convert from numeric to packed port number
+		push	si
+
 		shr		ax,1
-		and		al,DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTMASK
-
-		mov		bx,PackedCOMPortAddresses							; loop, looking for port address in known COM address list
-.next:	
-		mov		ah,[cs:bx]
+		shr		ax,1
+		and		al,0feh			; force 8-byte boundary
+
+		mov		si,g_rgbChoiceToValueLookupForCOM						
+		mov		bx,PackedCOMPortAddresses			; loop, looking for port address in known COM address list
+
+.loop:
+		mov		ah,[si]
+		cmp		ah,'x'
+		jz		.found
+				
+		cmp		al,[bx]
+		jz		.found
+		
+		inc		si
+		inc		si
 		inc		bx
-		test	ah,ah
-		jz		.notfound
-		cmp		al,ah
-		jnz		.next
-
-		sub		bx,PackedCOMPortAddresses + 1						; FOUND!, +1 since we already incremented
-		mov		ax,bx
+		
+		jmp		.loop
+
+.found:	
+		mov		[es:di+IDEVARS.bSerialCOMPortChar-IDEVARS.bSerialPort], ah
+
+		pop		si
 		pop		bx
-		jmp		IdeControllerMenu_SerialWriteCOM					; if found, use that logic to get ASCII character
-
-.notfound:
-		xchg	ah,al												
-		mov		al,'x'
-		jmp		IdeControllerMenu_SerialWriteCOM_PackAndRet
-
-
+
+		ret
+
+
+
+
+
+
+
Index: /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm	(revision 232)
+++ /trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm	(revision 233)
@@ -135,5 +135,5 @@
 g_szNfoIdeSerialCOM:	db	"Select a COM port by number.",NULL
 g_szNfoIdeSerialBaud:	db	"Select the COM port's Baud Rate. The server must match this speed. Note that UART clock multipliers may impact the actual speed.",NULL
-g_szNfoIdeSerialPort:	db	"Select a COM port by custom I/O port address. Address must be in the range 248h to 430h and be on an 8-byte boundary.", NULL
+g_szNfoIdeSerialPort:	db	"Select a COM port by custom I/O port address. Any address is valud up to 3f8h, but must be on an 8-byte boundary.", NULL
 
 g_szHelpIdeCmdPort:		incbin	"IDE_CommandPort.txt"
@@ -161,17 +161,17 @@
 
 g_szSerialCOMChoice:
-						db  "COM1 - Port 3f8h",LF
-						db	"COM2 - Port 2f8h",LF
-						db  "COM3 - Port 3e8h",LF
-						db  "COM4 - Port 2e8h",LF
-						db  "COM5 - Port 2f0h",LF
-						db  "COM6 - Port 3e0h",LF
-						db	"COM7 - Port 2e0h",LF
-						db	"COM8 - Port 260h",LF
-						db	"COM9 - Port 368h",LF
-						db	"COMA - Port 268h",LF
-						db	"COMB - Port 360h",LF
-						db	"COMC - Port 270h",LF
-						db  "COMx - Custom Port",NULL
+						db  "COM1 - address 3f8h",LF
+						db	"COM2 - address 2f8h",LF
+						db  "COM3 - address 3e8h",LF
+						db  "COM4 - address 2e8h",LF
+						db  "COM5 - address 2f0h",LF
+						db  "COM6 - address 3e0h",LF
+						db	"COM7 - address 2e0h",LF
+						db	"COM8 - address 260h",LF
+						db	"COM9 - address 368h",LF
+						db	"COMA - address 268h",LF
+						db	"COMB - address 360h",LF
+						db	"COMC - address 270h",LF
+						db  "COMx - Custom address",NULL
 
 g_szValueCfgCOM1:		db		"COM1",NULL
@@ -190,13 +190,22 @@
 		
 g_szSerialBaudChoice:
-						db  "2400 baud",LF
+						db  "115.2K baud",LF
+						db  "57.6K baud",LF
+						db	"38.4K baud",LF
+						db  "28.8K baud",LF
+						db  "19.2K baud",LF
 						db	"9600 baud",LF
-						db	"38.4K baud",LF
-						db  "115.2K baud",NULL
-
+						db  "4800 baud",LF		
+						db  "2400 baud",NULL
+
+g_szValueCfgBaud115_2:	db		"115.2K",NULL
+g_szValueCfgBaud57_6:	db		"57.6K",NULL
+g_szValueCfgBaud38_4:	db		"38.4K",NULL
+g_szValueCfgBaud28_8:	db		"28.8K",NULL
+g_szValueCfgBaud19_2:	db		"19.2K",NULL
+g_szValueCfgBaud9600:	db		"9600",NULL
+g_szValueCfgBaud4800:	db		"4800",NULL		
 g_szValueCfgBaud2400:	db		"2400",NULL
-g_szValueCfgBaud9600:	db		"9600",NULL
-g_szValueCfgBaud38_4:	db		"38.4K",NULL
-g_szValueCfgBaud115_2:	db		"115.2K",NULL
+
 		
 g_szValueCfgDeviceDual8b:	db	"XTIDE",NULL
@@ -363,2 +372,7 @@
 
 g_szDashForZero:		db		"- ",NULL
+
+g_szValueUnknownError:	db	"Error!",NULL
+
+
+
