Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/AssemblyLibrary.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/AssemblyLibrary.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/AssemblyLibrary.inc	(revision 348)
@@ -0,0 +1,54 @@
+; Project name	:	Assembly Library
+; Description	:	Common defines for all library functions.
+%ifndef ASSEMBLY_LIBRARY_INC
+%define ASSEMBLY_LIBRARY_INC
+
+; Include .inc files
+%include "Emulate.inc"			; Must be included first!
+%include "Macros.inc"
+%include "BiosData.inc"
+%include "BiosFunctions.inc"
+%include "CgaSnow.inc"
+%include "Debug.inc"
+%include "Delay.inc"
+%include "DosFunctions.inc"
+%include "File.inc"
+%include "Math.inc"
+%include "Registers.inc"
+%include "SystemTimer.inc"
+
+
+; Library dependencies
+%ifdef INCLUDE_MENU_DIALOGS
+	%include "Dialog.inc"
+	%define INCLUDE_MENU_LIBRARY
+	%define INCLUDE_FILE_LIBRARY
+%endif
+
+%ifdef INCLUDE_MENU_LIBRARY
+	%include "Menu.inc"
+	%include "MenuEvents.inc"
+	%define INCLUDE_KEYBOARD_LIBRARY
+	%define INCLUDE_TIME_LIBRARY
+%endif
+
+%ifdef INCLUDE_KEYBOARD_LIBRARY
+	%define INCLUDE_DISPLAY_LIBRARY
+	%define INCLUDE_UTIL_LIBRARY
+%endif
+
+%ifdef INCLUDE_DISPLAY_LIBRARY
+	%include "Display.inc"
+	%define INCLUDE_STRING_LIBRARY
+%endif
+
+%ifdef INCLUDE_STRING_LIBRARY
+	%define INCLUDE_UTIL_LIBRARY
+%endif
+
+%ifdef INCLUDE_FILE_LIBRARY
+	%define INCLUDE_UTIL_LIBRARY
+%endif
+
+
+%endif ; ASSEMBLY_LIBRARY_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/BiosData.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/BiosData.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/BiosData.inc	(revision 348)
@@ -0,0 +1,134 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Equates for BIOS Data Area.
+%ifndef BIOSDATA_INC
+%define BIOSDATA_INC
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; BIOS DATA AREA VARIABLES ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; BIOS Data Area (related to floppy drives and hard disks)
+struc BDA
+					resb	400h	; 40:0h, Start of BDA
+	.wCOM1			resb	2		; 0:400h, Serial I/O Address, Port 1
+	.wCOM2			resb	2		; 0:402h, Serial I/O Address, Port 2
+	.wCOM3			resb	2		; 0:404h, Serial I/O Address, Port 3
+	.wCOM4			resb	2		; 0:406h, Serial I/O Address, Port 4
+	.wLPT1			resb	2		; 0:408h, Parallel I/O Address, Port 1
+	.wLPT2			resb	2		; 0:40Ah, Parallel I/O Address, Port 2
+	.wLPT3			resb	2		; 0:40Ch, Parallel I/O Address, Port 3
+	.wLPT4:							; 0:40Eh, Parallel I/O Address, Port 4 (PC/XT)
+	.wSegEBDA		resb	2		; 0:40Eh, Extended BIOS Data Area segment (AT+)
+
+	.wEquipment		resb	2		; 0:410h, Equipment Word
+	.bTest			resb	1		; 0:412h, Manufacturing test
+	.wBaseMem		resb	2		; 0:413h, Base Memory Size in kB
+	.wAdptrMem:						; 0:415h, Adapter Memory Size (PC/XT)
+	.wError			resb	2		; 0:415h, Error Codes (AT+)
+	.bKBFlgs1		resb	1		; 0:417h, Keyboard, Shift Flags, Set 1
+	.bKBFlgs2		resb	1		; 0:418h, Keyboard, Shift Flags, Set 2
+	.bKBNumpad		resb	1		; 0:419h, Keyboard, ALT+Numpad work area
+	.wKBHead		resb	2		; 0:41Ah, Keyboard, Head of buffer pointer
+	.wKBTail		resb	2		; 0:41Ch, Keyboard, Tail of buffer pointer
+	.rgwKBBuff		resb	32		; 0:41Eh, Keyboard, 16-word buffer
+
+	.bFDRecal		resb	1		; 0:43Eh, Diskette, Recalibrate status
+	.bFDMotor		resb	1		; 0:43Fh, Diskette, Motor status
+
+	.bFDMotTime		resb	1		; 0:440h, Diskette, Motor timeout counter
+	.bFDRetST		resb	1		; 0:441h, Diskette, Controller status return code
+	.rgbFDStatus	resb	7		; 0:442h, Diskette, Diskette and Disk Controller status bytes
+	.bVidMode		resb	1		; 0:449h, Video, Mode
+	.wVidColumns	resb	2		; 0:44Ah, Video, Number of columns
+	.wVidBpP		resb	2		; 0:44Ch, Video, Total number of bytes per page
+	.wVidPageOff	resb	2		; 0:44Eh, Video, Current page offset
+
+	.rgwVidCurPos	resb	16		; 0:450h, Video, Cursor position, pages 0...7
+
+	.wVidCurShape	resb	2		; 0:460h, Video, Cursor shape
+	.bVidPageIdx	resb	1		; 0:462h, Video, Active display page
+	.wVidPort		resb	2		; 0:463h, Video, I/O Port number base
+	.bVidModeReg	resb	1		; 0:465h, Video, Internal mode register
+	.bVidPalette	resb	1		; 0:466h, Video, Color palette
+	.wCasTimeCnt:					; 0:467h, Cassette, Time count at data edge (PC)
+	.wGenOff		resb	2		; 0:467h, General use offset (XT+)
+	.wCasCRC:						; 0:469h, Cassette, CRC register (PC)
+	.wGenSeg		resb	2		; 0:469h, General use segment (XT+)
+	.bCasLast:						; 0:46Bh, Cassette, Last value read
+	.bLastIRQ		resb	1		; 0:46Bh, Last interrupt that occurred (XT+)
+	.dwTimerTicks	resb	4		; 0:46Ch, Timer ticks count
+
+	.bTimer24h		resb	1		; 0:470h, Timer ticks rollover flag
+	.bKBCtrlBrk		resb	1		; 0:471h, Keyboard, Ctrl+Break flag
+	.wBoot			resb	2		; 0:472h, Warm boot flag
+	.bHDLastSt		resb	1		; 0:474h, Hard Disk, Status of Last Operation (XT+)
+	.bHDCount		resb	1		; 0:475h, Hard Disk, Number of HDs Attached (XT+)
+	.bHDCtrl		resb	1		; 0:476h, Hard Disk, Control Byte (temp, XT+)
+	.bHDPortOff		resb	1		; 0:477h, Hard Disk, Port Offset (XT)
+	.bLPT1Timeout	resb	1		; 0:478h, Parallel Printer 1, Timeout (XT+)
+	.bLPT2Timeout	resb	1		; 0:479h, Parallel Printer 2, Timeout (XT+)
+	.bLPT3Timeout	resb	1		; 0:47Ah, Parallel Printer 3, Timeout (XT+)
+	.bLPT4Timeout	resb	1		; 0:47Bh, Parallel Printer 4, Timeout (XT+)
+	.bCOM1Timeout	resb	1		; 0:47Ch, Serial 1, Timeout (XT+)
+	.bCOM2Timeout	resb	1		; 0:47Dh, Serial 2, Timeout (XT+)
+	.bCOM3Timeout	resb	1		; 0:47Eh, Serial 3, Timeout (XT+)
+	.bCOM4Timeout	resb	1		; 0:47Fh, Serial 4, Timeout (XT+)
+
+	.wKBPtrStart	resb	2		; 0:480h, Keyboard, Pointer to start of buffer (XT+)
+	.wKBPtrEnd		resb	2		; 0:482h, Keyboard, Pointer to end of buffer (XT+)
+	.bVidRows		resb	1		; 0:484h, Video, Number of rows (EGA+)
+	.wVidPpC		resb	2		; 0:485h, Video, Pixels per character (EGA+)
+	.bVidOptns		resb	1		; 0:487h, Video, Options (EGA+)
+	.bVidSwitches	resb	1		; 0:488h, Video, Switches (EGA+)
+	.bVidSave1		resb	1		; 0:489h, Video, Save area 1 (VGA+)
+	.bVidSave2		resb	1		; 0:48Ah, Video, Save area 2 (VGA+)
+	.bFDCfgData		resb	1		; 0:48Bh, Diskette, Configuration data (AT+)
+	.bHDStatus		resb	1		; 0:48Ch, Hard Disk, Status Register (AT+)
+	.bHDError		resb	1		; 0:48Dh, Hard Disk, Error Register (AT+)
+	.bHDTaskFlg		resb	1		; 0:48Eh, Hard Disk, Task Complete Flag (AT+)
+	.bFDCtrlInfo	resb	1		; 0:48Fh, Diskette, Controller information (AT+)
+
+	.bFDMedia0		resb	1		; 0:490h, Diskette 0, Media state (AT+)
+	.bFDMedia1		resb	1		; 0:491h, Diskette 1, Media state (AT+)
+	.bFDOpStart0	resb	1		; 0:492h, Diskette 0, Operational starting state (AT+)
+	.bFDOpStart1	resb	1		; 0:493h, Diskette 1, Operational starting state (AT+)
+	.bFDCurCyl0		resb	1		; 0:494h, Diskette 0, Current cylinder (AT+)
+	.bFDCurCyl1		resb	1		; 0:495h, Diskette 1, Current cylinder (AT+)
+	.bKBFlgs3		resb	1		; 0:496h, Keyboard, Status flags 3 (AT+)
+	.bKBFlgs4		resb	1		; 0:497h, Keyboard, Status flags 4 (AT+)
+	.dwWaitPtr		resb	4		; 0:498h, User's wait flag pointer (AT+)
+	.dwWaitCnt		resb	4		; 0:49Ch, User's wait count (AT+)
+
+	.bWaitFlg		resb	1		; 0:4A0h, Wait flag (AT+)
+	.rgbLAN			resb	7		; 0:4A1h, Local Area Network (AT+)
+	.dwVidPtr		resb	4		; 0:4A8h, Video, Parameter Control Block Pointer (EGA+)
+					resb	22h		; Reserved from 0:4ACh...0:4CDh
+
+	.dwDays			resb	4		; 0:4CEh, Clock, Days since 1980 (some BIOSes, AT+)
+					resb	2Eh		; Reserved from 0:4D2h...0:4FFh
+
+	.bPrntScrn		resb	1		; 0:500, Print screen status
+endstruc
+
+; BDA struct with only Hard Disk related locations
+struc HDBDA
+					resb	474h
+	.bHDLastSt		resb	1		; 0:474h, Status of Last Operation (XT+)
+	.bHDCount		resb	1		; 0:475h, Number of HDs Attached (XT+)
+	.bHDCtrl		resb	1		; 0:476h, Control Byte (temp, XT+)
+	.bHDPortOff		resb	1		; 0:477h, Port Offset (XT)
+					resb	15h
+	.bHDStatus:						; 0:48Ch, Status Register (AT+)
+	.bHDError:						; 0:48Dh, Error Register (AT+)
+	.wHDStAndErr	resb	2
+	.bHDTaskFlg		resb	1		; 0:48Eh, Task Complete Flag (AT+)
+endstruc
+
+
+; Warm Boot Flags for BDA.wBoot
+BOOT_FLAG_COLD			EQU	0
+BOOT_FLAG_WARM			EQU	1234h	; Same effect as CTRL + ALT + DEL, skips memory tests
+BOOT_FLAG_PRESERVE_RAM	EQU	4321h	; No mem test, leave memory unchanged (AT+)
+
+
+%endif ; BIOSDATA_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/BiosFunctions.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/BiosFunctions.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/BiosFunctions.inc	(revision 348)
@@ -0,0 +1,63 @@
+; Project name	:	AssemblyLibrary
+; Description	:	Defines for BIOS functions.
+%ifndef BIOS_FUNCTIONS_INC
+%define BIOS_FUNCTIONS_INC
+
+; BIOS interrupts
+BIOS_VIDEO_INTERRUPT_10h		EQU		10h
+BIOS_DISK_INTERRUPT_13h			EQU		13h
+BIOS_SYSTEM_INTERRUPT_15h		EQU		15h
+BIOS_KEYBOARD_INTERRUPT_16h		EQU		16h
+BIOS_BOOT_FAILURE_INTERRUPT_18h	EQU		18h
+BIOS_BOOT_LOADER_INTERRUPT_19h	EQU		19h
+BIOS_DISKETTE_INTERRUPT_40h		EQU		40h
+HD0_DPT_POINTER_41h				EQU		41h
+HD1_DPT_POINTER_46h				EQU		46h
+
+; Hardware interrupts
+HARDWARE_IRQ_0_INTERRUPT_08h	EQU		08h		; System timer
+HARDWARE_IRQ_1_INTERRUPT_09h	EQU		09h		; Keyboard
+HARDWARE_IRQ_2_INTERRUPT_0Ah	EQU		0Ah
+HARDWARE_IRQ_3_INTERRUPT_0Bh	EQU		0Bh
+HARDWARE_IRQ_4_INTERRUPT_0Ch	EQU		0Ch
+HARDWARE_IRQ_5_INTERRUPT_0Dh	EQU		0Dh
+HARDWARE_IRQ_6_INTERRUPT_0Eh	EQU		0Eh
+HARDWARE_IRQ_7_INTERRUPT_0Fh	EQU		0Fh
+HARDWARE_IRQ_8_INTERRUPT_70h	EQU		70h
+HARDWARE_IRQ_9_INTERRUPT_71h	EQU		71h
+HARDWARE_IRQ_10_INTERRUPT_72h	EQU		72h
+HARDWARE_IRQ_11_INTERRUPT_73h	EQU		73h
+HARDWARE_IRQ_12_INTERRUPT_74h	EQU		74h
+HARDWARE_IRQ_13_INTERRUPT_75h	EQU		75h
+HARDWARE_IRQ_14_INTERRUPT_76h	EQU		76h
+HARDWARE_IRQ_15_INTERRUPT_77h	EQU		77h
+
+
+; BIOS video functions
+SET_VIDEO_MODE					EQU		00h
+SET_TEXT_MODE_CURSOR_SHAPE		EQU		01h
+SET_CURSOR_POSITION				EQU		02h
+GET_CURSOR_POSITION_AND_SIZE	EQU		03h
+SELECT_ACTIVE_DISPLAY_PAGE		EQU		05h
+TELETYPE_OUTPUT					EQU		0Eh
+
+; BIOS disk functions
+GET_DRIVE_PARAMETERS			EQU		08h
+GET_DISK_TYPE					EQU		15h
+GET_DRIVE_INFORMATION			EQU		25h
+CHECK_EXTENSIONS_PRESENT		EQU		41h
+GET_EXTENDED_DRIVE_INFORMATION	EQU		48h
+
+; BIOS system functions
+OS_HOOK_DEVICE_BUSY				EQU		90h
+OS_HOOK_DEVICE_POST				EQU		91h
+
+; BIOS keyboard functions
+GET_KEYSTROKE					EQU		00h
+CHECK_FOR_KEYSTROKE				EQU		01h
+
+; BIOS system functions
+EVENT_WAIT						EQU		86h
+
+
+%endif ; BIOS_FUNCTIONS_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/CgaSnow.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/CgaSnow.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/CgaSnow.inc	(revision 348)
@@ -0,0 +1,67 @@
+; File name		:	CgaSnow.inc
+; Project name	:	AssemblyLibrary
+; Created date	:	8.10.2010
+; Last update	:	11.10.2010
+; Author		:	Tomi Tilli
+; Description	:	Macros for preventing CGA snow.
+%ifndef CGASNOW_INC
+%define CGASNOW_INC
+
+;--------------------------------------------------------------------
+; WAIT_RETRACE_IF_NECESSARY_THEN
+;	Parameters:
+;		%1:		Instruction that accessed CGA memory
+;		AL:		Character to output
+;		AH:		Attribute to output (stosw only)
+;		DS:		BDA segment (zero)
+;		ES:SI:	Ptr to video memory where to read from (if %1 reads)
+;		ES:DI:	Ptr to video memory where to output (if %1 writes)
+;	Returns:
+;		SI, DI:	Updated according to instruction
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%macro WAIT_RETRACE_IF_NECESSARY_THEN 1
+%ifdef ELIMINATE_CGA_SNOW
+	%ifidn %1, stosb
+		call	CgaSnow_Stosb
+	%elifidn %1, stosw
+		call	CgaSnow_Stosw
+	%elifidn %1, rep movsb
+		call	CgaSnow_RepMovsb
+	%else
+		%error	"Invalid instruction passed to WAIT_RETRACE_IF_NECESSARY_THEN"
+	%endif
+%else	; No CGA snow prevention
+	%ifidn %1, rep movsb
+		eSEG_STR rep, es, movsb
+	%else
+		%1	; Single instruction
+	%endif
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; WAIT_UNTIL_SAFE_CGA_WRITE
+;	Parameters:
+;		DX:		CGA Status Register Address (3DAh)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+%macro WAIT_UNTIL_SAFE_CGA_WRITE 0
+%%WaitUntilNotInRetrace:
+	in		al, dx
+	shr		al, 1	; 1 = Bit 0: A 1 indicates that regen-buffer memory access can be
+					; made without interfering with the display. (H or V retrace)
+	jc		SHORT %%WaitUntilNotInRetrace
+%%WaitUntilNextRetraceStarts:
+	in		al, dx
+	shr		al, 1
+	jnc		SHORT %%WaitUntilNextRetraceStarts
+%endmacro
+
+
+%endif ; CGASNOW_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Debug.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Debug.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Debug.inc	(revision 348)
@@ -0,0 +1,105 @@
+; Project name	:	Assembly Library
+; Description	:	Debugging macros.
+%ifndef DEBUG_INC
+%define DEBUG_INC
+
+
+;--------------------------------------------------------------------
+; DISPLAY_DEBUG_WORD_AND_WAIT_ANY_KEY
+;	Parameters:
+;		%1:		Debug word
+;		%2:		Numeric base (2, 10, 16)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro DISPLAY_DEBUG_WORD_AND_WAIT_ANY_KEY 2
+	pushf
+	push	di
+	push	bx
+	push	ax
+
+	mov		ax, %1
+	mov		bx, %2
+	CALL_DISPLAY_LIBRARY PrintWordFromAXwithBaseInBX
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	call	Keyboard_RemoveAllKeystrokesFromBuffer
+%endif
+	call	Keyboard_GetKeystrokeToAXandWaitIfNecessary
+
+	pop		ax
+	pop		bx
+	pop		di
+	popf
+%endmacro
+
+
+;--------------------------------------------------------------------
+; DISPLAY_DEBUG_CHARACTER_AND_WAIT_ANY_KEY
+;	Parameters:
+;		%1:		Character to print
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro DISPLAY_DEBUG_CHARACTER_AND_WAIT_ANY_KEY 1
+	pushf
+	push	di
+	push	ax
+
+	mov		al, %1
+	CALL_DISPLAY_LIBRARY PrintCharacterFromAL
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	call	Keyboard_RemoveAllKeystrokesFromBuffer
+%endif
+	call	Keyboard_GetKeystrokeToAXandWaitIfNecessary
+
+	pop		ax
+	pop		di
+	popf
+%endmacro
+
+
+;--------------------------------------------------------------------
+; DISPLAY_DEBUG_CHARACTER
+;	Parameters:
+;		%1:		Character to print
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro DISPLAY_DEBUG_CHARACTER 1
+	pushf
+	push	di
+	push	ax
+	mov		al, %1
+	CALL_DISPLAY_LIBRARY PrintCharacterFromAL
+	pop		ax
+	pop		di
+	popf
+%endmacro
+
+
+;--------------------------------------------------------------------
+; WAIT_ANY_KEY_TO_CONTINUE
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro WAIT_ANY_KEY_TO_CONTINUE 0
+	push	ax
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	call	Keyboard_RemoveAllKeystrokesFromBuffer
+%endif
+	call	Keyboard_GetKeystrokeToAXandWaitIfNecessary
+	pop		ax
+%endmacro
+
+
+%endif ; DEBUG_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Delay.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Delay.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Delay.inc	(revision 348)
@@ -0,0 +1,59 @@
+; Project name	:	Assembly Library
+; Description	:	Delay macros.
+%ifndef DELAY_INC
+%define DELAY_INC
+
+;--------------------------------------------------------------------
+; Clears prefetch queue by jumping to next instruction.
+; This delays much more than nop instruction of fast systems.
+;
+; JMP_DELAY
+;	Parameters
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro JMP_DELAY 0
+	jmp		SHORT %%NextInstruction
+%%NextInstruction:
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Mimimun delays (without fetching) with some CPU architectures:
+;	8088/8086:	17 cycles for jump + 5 cycles for last comparison
+;	286:		10 cycles for jump + 4 cycles for last comparison
+;	386:		13 cycles for jump + ? cycles for last comparison
+;	486:		 7 cycles for jump + 6 cycles for last comparison
+;
+; LOOP instruction uses two bytes so aligned fetching will require:
+;   8088:		8 cycles (two BYTE reads)
+;   8086:		4 cycles (one WORD read)
+;   286:		2 cycles + wait states (usually 1)
+;   386:		?
+;	486:		Fetched only once to internal cache
+;
+; DELAY_WITH_LOOP_INSTRUCTION_NA	; No JUMP_ALIGN
+; DELAY_WITH_LOOP_INSTRUCTION
+;	Parameters
+;		CX:		Loop iterations (0 is maximum delay with 65536 iterations)
+;	Returns:
+;		CX:		Zero
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro DELAY_WITH_LOOP_INSTRUCTION_NA 0
+%%StartOfLoop:
+	loop	%%StartOfLoop
+%endmacro
+
+%macro DELAY_WITH_LOOP_INSTRUCTION 0
+ALIGN JUMP_ALIGN
+%%StartOfLoop:
+	loop	%%StartOfLoop
+%endmacro
+
+
+%endif ; DELAY_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Dialog.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Dialog.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Dialog.inc	(revision 348)
@@ -0,0 +1,101 @@
+; File name		:	Dialog.inc
+; Project name	:	Assembly Library
+; Created date	:	15.9.2010
+; Last update	:	22.10.2010
+; Author		:	Tomi Tilli
+; Description	:	Defines for Menu library dialogs.
+%ifndef DIALOG_INC
+%define DIALOG_INC
+
+; Struct and defines for all dialogs
+struc DIALOG
+	.menu					resb	MENU_size
+	.fpDialogIO				resb	4	; Ptr to DIALOG_INPUT + dialog specific data
+	.pParentMenu			resb	2
+endstruc
+
+DIALOG_DELTA_WIDTH_FROM_PARENT		EQU		5
+DIALOG_MAX_WIDTH					EQU		60
+DIALOG_MAX_HEIGHT					EQU		25
+
+
+; Dialog parameter and return value structs
+struc DIALOG_INPUT
+	.fszTitle			resb	4
+	.fszItems			resb	4
+	.fszInfo			resb	4
+endstruc
+
+struc WORD_DIALOG_IO
+	.dialogInput		resb	DIALOG_INPUT_size
+	.bUserCancellation	resb	1
+	.bNumericBase		resb	1
+	.wMin				resb	2
+	.wMax				resb	2
+	.wReturnWord		resb	2
+endstruc
+
+struc STRING_DIALOG_IO
+	.dialogInput		resb	DIALOG_INPUT_size
+	.bUserCancellation	resb	1
+						resb	1
+	.fnCharFilter		resb	2	; Optional, can be NULL to accept all
+	.wBufferSize:
+	.wReturnLength		resb	2	; String length without NULL
+	.fpReturnBuffer		resb	4
+endstruc
+
+struc PROGRESS_DIALOG_IO
+	.dialogInput					resb	DIALOG_INPUT_size
+									resb	2
+	.wCurrentProgressValue			resb	2
+	.wMaxProgressValue				resb	2
+	.wMinProgressValue				resb	2
+	.fnTaskWithParamInDSSI			resb	2
+
+	; Progress Dialog internal values
+	.wProgressPerCharacter			resb	2
+	.wStartTimeTicks				resb	2
+endstruc
+
+struc DRIVE_DIALOG_IO
+	.dialogInput		resb	DIALOG_INPUT_size
+	.bUserCancellation	resb	1
+						resb	1
+	.cReturnDriveLetter	resb	1
+	.bReturnDriveNumber	resb	1
+endstruc
+
+struc FILE_DIALOG_IO
+	; DIALOG_INPUT adjusted for File Dialog
+	.fszTitle			resb	4
+	.fszItemBuffer		resb	4	; For generating file strings
+						resb	4
+
+	.bUserCancellation	resb	1
+						resb	1
+	.bDialogFlags		resb	1
+	.bFileAttributes	resb	1
+						resb	2
+	.fpFileFilterString:			; Ptr to NULL terminated search string (may include path and wildcards)
+	.szFile				resb	FILENAME_BUFFER_SIZE
+endstruc
+
+
+; Progress bar dialog
+PROGRESS_COMPLETE_CHARACTER			EQU		BLOCK_FULL_FOREGROUND
+PROGRESS_INCOMPLETE_CHARACTER		EQU		BLOCK_MOSTLY_BACKGROUND
+
+; File dialog
+FILENAME_BUFFER_SIZE				EQU		14	; 8+1+3+NULL+alignment
+MAX_FILE_DIALOG_INFO_LINES			EQU		3
+FLG_FILEDIALOG_DRIVES				EQU		(1<<0)	; Allow changing drive
+FLG_FILEDIALOG_DIRECTORY			EQU		(1<<1)	; Select directory instead of file
+FLG_FILEDIALOG_NEW					EQU		(1<<2)	; Allow creating new file or directory
+
+KEY_FILEDIALOG_CHANGE_DRIVE			EQU		3Ch		; F2
+KEY_FILEDIALOG_SELECT_DIRECTORY		EQU		3Dh		; F3
+KEY_FILEDIALOG_NEW_FILE_OR_DIR		EQU		3Eh		; F4
+
+
+%endif ; DIALOG_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Display.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Display.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Display.inc	(revision 348)
@@ -0,0 +1,253 @@
+; Project name	:	AssemblyLibrary
+; Description	:	Defines for display library.
+%ifndef DISPLAY_INC
+%define DISPLAY_INC
+
+%ifndef MODULE_STRINGS_COMPRESSED_PRECOMPRESS
+;--------------------------------------------------------------------
+; Display Library users need to use this macro since it will provide
+; compatibility with future library versions.
+;
+; CALL_DISPLAY_LIBRARY
+;	Parameters:
+;		%1:			Function to call (functionName from DISPLAY_LIB)
+;		Registers:	Depends on function to call
+;	Returns:
+;		Depends on function to call
+;	Corrupts registers:
+;		AX (unless used as a return register), DI
+;--------------------------------------------------------------------
+%macro CALL_DISPLAY_LIBRARY 1
+	%ifidn %1, PushDisplayContext
+		call	DisplayContext_Push
+	%elifidn %1, PopDisplayContext
+		call	DisplayContext_Pop
+	%elifidn %1, PrepareOffScreenBufferInESBXwithLengthInCX
+		call	DisplayContext_PrepareOffScreenBufferInESBXwithLengthInCX
+	%else
+		mov		di, %1
+		call	Display_FunctionFromDI
+	%endif
+%endmacro
+
+%if 0
+;;;
+;;; struc no longer needed with direct calls to functions
+;;;
+
+; Display library functions
+struc DISPLAY_LIB
+	.PushDisplayContext:
+	.PopDisplayContext:
+	.InitializeDisplayContext						resb	2
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	.SetCharacterPointerFromBXAX					resb	2
+%endif
+	.SetCharOutputFunctionFromAXwithAttribFlagInBL	resb	2
+	.SetCharacterOutputParameterFromAX				resb	2
+	.SetCharacterAttributeFromAL					resb	2
+	.SetCursorShapeFromAX							resb	2
+	.SetCursorCoordinatesFromAX						resb	2
+	.SetNewPageFromAL								resb	2
+	.SynchronizeDisplayContextToHardware			resb	2
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	.GetCharacterPointerToBXAX						resb	2
+%endif
+	.GetSoftwareCoordinatesToAX						resb	2
+	.GetColumnsToALandRowsToAH						resb	2
+
+	.FormatNullTerminatedStringFromCSSI				resb	2
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	.PrintSignedWordFromAXWithBaseInBX				resb	2
+%endif
+	.PrintWordFromAXwithBaseInBX					resb	2
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS OR EXCLUDE_FROM_XTIDECFG
+	.PrintQWordFromSSBPwithBaseInBX					resb	2
+%endif
+	.PrintCharBufferFromBXSIwithLengthInCX			resb	2
+	.PrintNullTerminatedStringFromBXSI				resb	2
+	.PrintNullTerminatedStringFromCSSI				resb	2
+	.PrintRepeatedCharacterFromALwithCountInCX		resb	2
+	.PrintCharacterFromAL							resb	2
+	.PrintNewlineCharacters							resb	2
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	.ClearAreaWithHeightInAHandWidthInAL			resb	2
+%endif
+	.ClearScreenWithCharInALandAttrInAH				resb	2
+endstruc
+%endif
+
+; Attribute flags for DISPLAY_LIB.SetCharacterOutputFunctionFromAXwithAttributeFlagInDL
+ATTRIBUTES_NOT_USED							EQU		0
+ATTRIBUTES_ARE_USED							EQU		FLG_CONTEXT_ATTRIBUTES
+
+; Character output functions for DISPLAY_LIB.SetCharacterOutputFunctionFromAXwithAttributeFlagInDL
+TELETYPE_OUTPUT_WITH_ATTRIBUTE				EQU		DisplayCharOut_TeletypeOutputWithAttribute
+TELETYPE_OUTPUT_WITHOUT_ATTRIBUTE			EQU		DisplayCharOut_TeletypeOutput
+TELETYPE_OUTPUT_USING_BIOS					EQU		DisplayCharOut_BiosTeletypeOutput
+FAST_OUTPUT_WITH_ATTRIBUTE_ONLY				EQU		DisplayCharOut_Attribute
+FAST_OUTPUT_WITH_CHAR_ONLY					EQU		DisplayCharOut_Character
+FAST_OUTPUT_WITH_CHAR_AND_ATTRIBUTE			EQU		DisplayCharOut_CharacterWithAttribute
+BUFFER_OUTPUT_WITH_CHAR_ONLY				EQU		DisplayCharOut_WriteCharacterToBuffer
+
+DEFAULT_CHARACTER_OUTPUT					EQU		TELETYPE_OUTPUT_WITH_ATTRIBUTE
+
+
+struc VIDEO_BDA
+						resb	449h
+	.bMode				resb	1		; 0:449h, Video, Mode
+	.wColumns			resb	2		; 0:44Ah, Video, Number of columns
+	.wBytesPerPage		resb	2		; 0:44Ch, Video, Total number of bytes per page
+	.wPageOffset		resb	2		; 0:44Eh, Video, Current page offset
+	.rgwCursors			resb	4		; 0:450h, Video, Cursor position, pages 0...1
+	.displayContext		resb	12		; Our own display context (normally cursors for pages 2...7)
+	.wCursorShape		resb	2		; 0:460h, Video, Cursor shape
+	.bActivePage		resb	1		; 0:462h, Video, Active display page
+	.wVideoPort			resb	2		; 0:463h, Video, I/O Port number base
+	.bInternalModeReg	resb	1		; 0:465h, Video, Internal mode register
+	.bColorPalette		resb	1		; 0:466h, Video, Color palette
+endstruc
+
+struc DISPLAY_CONTEXT
+	.fpCursorPosition	resb	4	; Far pointer to cursor position in video memory
+	.fnCharOut			resb	2	; Function to draw character with
+	.wCharOutParam		resb	2	; User parameter for custom character output function
+	.wCursorShape		resb	2	; Current cursor shape
+	.bAttribute			resb	1	; Selected character attribute
+	.bFlags				resb	1	; Display context flags
+endstruc
+
+; Display context flags
+FLG_CONTEXT_ATTRIBUTES		EQU		(1<<0)	; Character output function uses attributes
+FLG_CONTEXT_CGA				EQU		(1<<1)	; CGA detected so prevent CGA snow
+
+
+; Text mode character attribute byte bits for CGA+ (color adapters)
+FLG_COLOR_FORE_BLUE			EQU		(1<<0)
+FLG_COLOR_FORE_GREEN		EQU		(1<<1)
+FLG_COLOR_FORE_RED			EQU		(1<<2)
+FLG_COLOR_FORE_INTENSITY	EQU		(1<<3)
+FLG_COLOR_FORE_FONT_B		EQU		(1<<3)	; Select font set B (if available, EGA+)
+FLG_COLOR_BACK_BLUE			EQU		(1<<4)
+FLG_COLOR_BACK_GREEN		EQU		(1<<5)
+FLG_COLOR_BACK_RED			EQU		(1<<6)
+FLG_COLOR_BACK_INTENSITY	EQU		(1<<7)	; Intensity when blinking is disabled
+FLG_COLOR_BLINK				EQU		(1<<7)	; Blinking color when enabled (enabled by default)
+
+; CGA colors
+%define COLOR_ATTRIBUTE(foreground, background)	( (foreground) | ((background)<<4) )
+COLOR_BLACK					EQU		0
+COLOR_BLUE					EQU		1
+COLOR_GREEN					EQU		2
+COLOR_CYAN					EQU		3
+COLOR_RED					EQU		4
+COLOR_MAGENTA				EQU		5
+COLOR_BROWN					EQU		6
+COLOR_WHITE					EQU		7		; Last background color if blinking enabled
+COLOR_GRAY					EQU		8
+COLOR_LIGHT_BLUE			EQU		9
+COLOR_LIGHT_GREEN			EQU		10
+COLOR_LIGHT_CYAN			EQU		11
+COLOR_LIGHT_RED				EQU		12
+COLOR_LIGHT_MAGENTA			EQU		13
+COLOR_YELLOW				EQU		14
+COLOR_BRIGHT_WHITE			EQU		15
+
+
+; Text mode character attribute byte bits for MDA (monochrome adapters)
+; (attributes 00h, 08h, 80h, 88h, 70h, 78h, F0h and F8h are exceptions)
+FLG_MONO_UNDERLINE			EQU		(1<<1)
+FLG_MONO_INTENSITY			EQU		(1<<3)
+FLG_MONO_BLINK				EQU		(1<<7)
+
+; Text mode character attribute bytes for MDA/Hercules (monochrome adapters)
+; *Not displayed on some monitors
+MONO_HIDDEN					EQU		00h		; Not displayed (same for 08h, 80h and 88h)
+MONO_UNDERLINE				EQU		01h		; Underlined
+MONO_NORMAL					EQU		07h		; Normal (white on black)
+MONO_BRIGHT_UNDERLINE		EQU		09h		; High intensity, underlined
+MONO_BRIGHT					EQU		0Fh		; High intensity
+MONO_REVERSE				EQU		70h		; Reverse video (black on white)
+MONO_REVERSE_DARK			EQU		78h		; (dark green on green)
+MONO_BLINK					EQU		87h		; Blinking white on black*
+MONO_BRIGHT_BLINK			EQU		8Fh		; Blinking high intensity*
+MONO_REVERSE_BLINK			EQU		0F0h	; Blinking reverse video
+MONO_REVERSE_DARK_BLINK		EQU		0F8h	; (blinking dark green on green)
+
+
+; Cursor position macro for DX register
+%define CURSOR_XY(x, y)	( (x) | ((y)<<8) )
+
+; Cursor shapes
+CURSOR_NORMAL				EQU		0607h		; Two line cursor near or at the bottom of cell (not valid for IBM MDA)
+CURSOR_HIDDEN				EQU		2000h
+
+
+; Display modes
+CGA_TEXT_MODE_BW40			EQU		0		; Applications should use...
+CGA_TEXT_MODE_CO40			EQU		1
+CGA_TEXT_MODE_BW80			EQU		2		; ..black, white and bright white attributes only
+CGA_TEXT_MODE_CO80			EQU		3
+MDA_TEXT_MODE				EQU		7		; Real monochrome attributes available
+
+
+; Display segments
+COLOR_TEXT_SEGMENT			EQU		0B800h	; Text modes 0...3 (CGA+)
+MONO_TEXT_SEGMENT			EQU		0B000h	; Text mode 7 (MDA, Hercules)
+
+OFFSET_TO_CGA_STATUS_REGISTER	EQU		6	; Base port 3D4h + 6 = 3DAh
+CGA_STATUS_REGISTER				EQU		3DAh
+
+%endif ; MODULE_STRINGS_COMPRESS_PRECOMPRESS
+
+; Control characters for teletype output
+NULL						EQU		00h
+SOH							EQU		01h		; Start of heading
+STX							EQU		02h		; Start of text
+BELL						EQU		07h		; Bell
+BS							EQU		08h		; Backspace
+TAB							EQU		09h		; Horizontal TAB
+LF							EQU		0Ah		; Line feed (newline)
+CR							EQU		0Dh		; Carriage return
+ESC							EQU		1Bh		; Escape
+
+; Non ASCII characters (code page 437)
+BETA										EQU		225
+QUOTATION_MARK								EQU		34
+DOUBLE_TOP_RIGHT_CORNER						EQU		187
+DOUBLE_TOP_LEFT_CORNER						EQU		201
+DOUBLE_BOTTOM_RIGHT_CORNER					EQU		188
+DOUBLE_BOTTOM_LEFT_CORNER					EQU		200
+DOUBLE_VERTICAL								EQU		186
+DOUBLE_HORIZONTAL							EQU		205
+DOUBLE_VERTICAL_TO_RIGHT_SINGLE				EQU		199
+DOUBLE_VERTICAL_TO_LEFT_SINGLE				EQU		182
+DOUBLE_LEFT_HORIZONTAL_TO_SINGLE_VERTICAL	EQU		181
+DOUBLE_RIGHT_HORIZONTAL_TO_SINGLE_VERTICAL	EQU		198
+SINGLE_VERTICAL								EQU		179
+SINGLE_HORIZONTAL							EQU		196
+SINGLE_LEFT_HORIZONTAL_TO_VERTICAL			EQU		180
+SINGLE_RIGHT_HORIZONTAL_TO_VERTICAL			EQU		195
+ANGLE_QUOTE_LEFT							EQU		174
+ANGLE_QUOTE_RIGHT							EQU		175
+BLOCK_MOSTLY_BACKGROUND						EQU		176
+BLOCK_EVEN_BACKGROUND_AND_FOREGROUND		EQU		177
+BLOCK_MOSTLY_FOREGROUND						EQU		178
+BLOCK_FULL_FOREGROUND						EQU		219
+ONE_HALF									EQU		171
+ONE_QUARTER									EQU		172
+
+
+; Background character for clearing screen
+%ifndef SCREEN_BACKGROUND_CHARACTER
+	%define	SCREEN_BACKGROUND_CHARACTER		BLOCK_MOSTLY_BACKGROUND
+%endif
+%ifndef SCREEN_BACKGROUND_ATTRIBUTE
+	%define	SCREEN_BACKGROUND_ATTRIBUTE		MONO_NORMAL
+%endif
+%define SCREEN_BACKGROUND_CHARACTER_AND_ATTRIBUTE	(SCREEN_BACKGROUND_CHARACTER | (SCREEN_BACKGROUND_ATTRIBUTE<<8))
+%define DOS_BACKGROUND_CHARACTER_AND_ATTRIBUTE		(' ' | (MONO_NORMAL<<8))
+
+%endif ; DISPLAY_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/DosFunctions.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/DosFunctions.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/DosFunctions.inc	(revision 348)
@@ -0,0 +1,74 @@
+; File name		:	DosFunctions.inc
+; Project name	:	AssemblyLibrary
+; Created date	:	1.9.2010
+; Last update	:	3.1.2011
+; Author		:	Tomi Tilli
+; Description	:	Defines for MS-DOS functions.
+%ifndef DOS_FUNCTIONS_INC
+%define DOS_FUNCTIONS_INC
+
+; DOS interrupts
+DOS_INTERRUPT_21h									EQU		21h
+DOS_CRITICAL_ERROR_HANDLER_24h						EQU		24h
+DOS_TSR_MULTIPLEX_INTERRUPT_2Fh						EQU		2Fh
+
+; DOS drive and file functions
+SELECT_DEFAULT_DRIVE								EQU		0Eh
+GET_CURRENT_DEFAULT_DRIVE							EQU		19h
+GET_DISK_TRANSFER_AREA_ADDRESS						EQU		2Fh
+GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE	EQU		32h
+SET_CURRENT_DIRECTORY								EQU		3Bh
+OPEN_EXISTING_FILE									EQU		3Dh
+CLOSE_FILE											EQU		3Eh
+READ_FROM_FILE_OR_DEVICE							EQU		3Fh
+WRITE_TO_FILE_OR_DEVICE								EQU		40h
+SET_CURRENT_FILE_POSITION							EQU		42h
+GET_CURRENT_DIRECTORY								EQU		47h
+FIND_FIRST_MATCHING_FILE							EQU		4Eh
+FIND_NEXT_MATCHING_FILE								EQU		4Fh
+
+; DOS functions for TSRs
+SET_INTERRUPT_VECTOR								EQU		25h
+GET_INTERRUPT_VECTOR								EQU		35h
+
+; DOS errors
+ERR_DOS_DRIVE_NOT_READY								EQU		15h
+
+
+
+; DOS Program Segment Prefix (PSP, first 256 (100h) bytes on top of program)
+struc PSP
+	.int20hInstruction				resb	2
+	.wSizeOfMemoryInParagraphs		resb	2
+	.reservedAt4h					resb	1
+	.callToDosFunctionDispatcher	resb	5
+	.fpInt22hTerminate				resb	4
+	.fpInt23hCtrlC					resb	4
+	.fpInt24hCriticalError			resb	4
+	.reservedAt16h					resb	22
+	.wEnvironmentSegment			resb	2
+	.reservedAt2Eh					resb	34
+	.int21hAndRetfInstructions		resb	3
+	.reservedAt53h					resb	9
+	.FCB1							resb	16
+	.FCB2							resb	20
+	.DiskTransferArea:
+	.bCommandLineLength				resb	1
+	.szCommandLine					resb	127
+endstruc
+
+
+; DOS DTA (Disk Transfer Area)
+struc DTA
+	; Undocumented fields
+	.reservedAt0h		resb	21
+	; Documented fields
+	.bFileAttributes	resb	1	; 15h, Attribute of matching file
+	.wFileTime			resb	2	; 16h, File time
+	.wFileDate			resb	2	; 18h, File date
+	.dwFileSize			resb	4	; 1Ah, File size in bytes
+	.szFile				resb	13	; 1Eh, ASCIZ filename + extension
+endstruc
+
+
+%endif ; DOS_FUNCTIONS_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Emulate.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Emulate.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Emulate.inc	(revision 348)
@@ -0,0 +1,520 @@
+; Project name	:	Emulation library
+; Description	:	Macros for emulating later x86 instructions with older
+;					processors.
+;					Macros are used so optimized builds can be done
+;					easily for different processors.
+;
+;					This file must be first to be included to
+;					any source file.
+%ifndef EMULATE_INC
+%define EMULATE_INC
+
+; Defines for processor support (should be set in makefile).
+; Unsupported instructions will be emulated using macros.
+; If AT class PC is used (instead of XT), define USE_AT
+
+;%define USE_186				; Define to use 18x/V20/V30 instructions
+;%define USE_286				; Define to use 286 instructions
+;%define USE_386				; Define to use 386 instructions
+;%define USE_AT					; Define for AT class machine
+
+%ifdef USE_386
+	%define USE_286				; Define to use 286 instructions
+%endif
+%ifdef USE_286
+	%define USE_186				; Define to use 18x/V20/V30 instructions
+%endif
+
+%ifdef USE_386
+	CPU 386						; Allow instructions up to 386
+%elifdef USE_286
+	CPU 286						; Allow instructions up to 286
+%elifdef USE_186
+	CPU 186						; Allow instructions up to 188/186/V20/V30
+%else
+	CPU 8086					; Allow 8088/8086 instructions only
+%endif
+
+BITS 16							; Set 16 bit code generation
+
+; Alignments for jump targets.
+; Following values are optimal for different processor types:
+; 286 and 386SX			WORD (16-bit, 2 bytes)
+; 386DX and 486			DWORD (32-bit, 4 bytes)
+; Pentium and later		QWORD (64-bit, 8 bytes)
+%ifdef USE_AT
+	%ifdef USE_386
+		JUMP_ALIGN		EQU		4
+		WORD_ALIGN		EQU		2
+	%else ; USE_286
+		JUMP_ALIGN		EQU		2
+		WORD_ALIGN		EQU		2
+	%endif
+%else ; XT
+	JUMP_ALIGN		EQU		1
+	WORD_ALIGN		EQU		1
+%endif
+
+;==========================================================================
+
+;--------------------------------------------------------------------
+; Emulates BSF (Bit Scan Forward) instruction when necessary.
+; BSF is used to find index of least significant bit.
+;
+; eBSF
+;	Parameters:
+;		%1:		Destination WORD Register for bit index (not CX or same as %2!)
+;		%2:		Source WORD operand where to search bit (not CX or same as %1!)
+;	Returns:
+;		%1:		Index of highest order bit from %2
+;		ZF:		Set if %2 is zero
+;				Cleared if %2 is non-zero
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eBSF 2
+%ifndef USE_386
+	push	cx
+	cmp		WORD %2, BYTE 0		; Source operand is zero?
+	je		SHORT %%Return		;  If so, return with ZF set
+
+	; Set destination to zero and load mask for bit 0
+	xor		%1, %1
+	mov		cx, 1
+
+ALIGN JUMP_ALIGN
+%%BitLoop:
+	test	%2, cx				; Bit set?
+	jnz		SHORT %%Return		;  If so, return with ZF cleared
+	shl		cx, 1				; Prepare to test next bit
+	inc		%1					; Increment bit index
+	jmp		SHORT %%BitLoop		; Loop until bit found
+%%Return:
+	pop		cx
+;-----------------------------------
+%else
+	bsf		%1, %2
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates BSR (Bit Scan Reverse) instruction when necessary.
+; BSR is used to find index of most significant bit.
+;
+; eBSR
+;	Parameters:
+;		%1:		Destination WORD Register for bit index (not CX or same as %2!)
+;		%2:		Source WORD operand where to search bit (not CX or same as %1!)
+;	Returns:
+;		%1:		Index of highest order bit from %2
+;		ZF:		Set if %2 is zero
+;				Cleared if %2 is non-zero
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eBSR 2
+%ifndef USE_386
+	push	cx
+	cmp		WORD %2, BYTE 0		; Source operand is zero?
+	je		SHORT %%Return		;  If so, return with ZF set
+
+	; Load mask for highest order bit
+	mov		cx, 1<<15
+	mov		%1, 15
+
+ALIGN JUMP_ALIGN
+%%BitLoop:
+	test	%2, cx				; Bit set?
+	jnz		SHORT %%Return		;  If so, return with ZF cleared
+	shr		cx, 1				; Prepare to test next bit
+	dec		%1					; Decrement bit index
+	jmp		SHORT %%BitLoop		; Loop until bit found
+%%Return:
+	pop		cx
+;-----------------------------------
+%else
+	bsr		%1, %2
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Conditional Move.
+;
+; eCMOVcc
+;	Parameters:
+;		%1:		Destination data
+;		%2:		Source data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eCMOVA 2
+	jbe		SHORT %%Return
+	mov		%1, %2
+%%Return:
+%endmacro
+
+%macro eCMOVC 2
+	jnc		SHORT %%Return
+	mov		%1, %2
+%%Return:
+%endmacro
+
+%macro eCMOVZ 2
+	jnz		SHORT %%Return
+	mov		%1, %2
+%%Return:
+%endmacro
+
+%macro eCMOVNZ 2
+	jz		SHORT %%Return
+	mov		%1, %2
+%%Return:
+%endmacro
+
+%macro eCMOVE 2
+	eCMOVZ %1, %2
+%endmacro
+
+%macro eCMOVNE 2
+	eCMOVNZ %1, %2
+%endmacro
+
+%macro eCMOVB 2
+	jnb		SHORT %%Return
+	mov		%1, %2
+%%Return:
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Conditional Set.
+;
+; eCSETcc
+;	Parameters:
+;		%1:		Destination data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Flags
+;--------------------------------------------------------------------
+%macro eCSETZ 1
+	mov		%1, 0			; Clear while preserving flags
+	jnz		SHORT %%Return	; Nothing to set
+	inc		%1
+%%Return:
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Moves byte with zero-extending to any Register.
+;
+; eMOVZX
+;	Parameters:
+;		%1:		Destination Register (SP not supported)
+;		%2:		Byte register or byte address
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		FLAGS
+;--------------------------------------------------------------------
+%macro eMOVZX 2
+%ifndef USE_386
+	%ifidni %1, ax
+		mov		al, %2
+		xor		ah, ah
+	%elifidni %1, bx
+		mov		bl, %2
+		xor		bh, bh		; %2 may use BX in effective address
+	%elifidni %1, cx
+		mov		cl, %2
+		xor		ch, ch
+	%elifidni %1, dx
+		mov		dl, %2
+		xor		dh, dh
+	%else	; SI, DI, BP (all may be used in effective address)
+		push	ax
+		mov		al, %2
+		xor		ah, ah
+		xchg	ax, %1
+		pop		ax
+	%endif
+;-----------------------------------
+%else
+	movzx	%1, %2
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates PUSHA instruction when necessary.
+;
+; ePUSHA
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro ePUSHA 0
+%ifndef USE_186
+	push	ax
+	push	cx
+	push	dx
+	push	bx
+	push	sp
+	push	bp
+	push	si
+	push	di
+;-----------------------------------
+%else
+	pusha
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates POPA instruction when necessary.
+;
+; ePOPA
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro ePOPA 0
+%ifndef USE_186
+	pop		di
+	pop		si
+	pop		bp
+	pop		ax		; Skip SP
+	pop		bx
+	pop		dx
+	pop		cx
+	pop		ax
+;-----------------------------------
+%else
+	popa
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates ENTER instruction when necessary.
+;
+; eENTER
+;	Parameters:
+;		%1:		Number of bytes to reserve from stack
+;		%2:		The lexical nesting level (not emulated, set to 0)
+;	Returns:
+;		SS:BP:	Ptr to old BP
+;				([bp-2] points to highest local stack frame word)
+;	Corrupts registers:
+;		FLAGS
+;--------------------------------------------------------------------
+%macro eENTER 2
+%ifndef USE_186
+	push	bp
+	mov		bp, sp
+	sub		sp, %1
+;-----------------------------------
+%else
+	enter	%1, %2
+%endif
+%endmacro
+
+;--------------------------------------------------------------------
+; Emulates LEAVE instruction when necessary.
+;
+; eLEAVE
+;	Parameters:
+;		Nothing
+;	Returns:
+;		BP:		What it was before eENTER
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eLEAVE 0
+%ifndef USE_186
+	mov		sp, bp
+	pop		bp
+;-----------------------------------
+%else
+	leave
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates LSS instruction when necessary.
+;
+; eLSS
+;	Parameters:
+;		%1:		Destination register
+;		%2:		Source memory address without brackets
+;	Returns:
+;		IF:		0 (interrupts disabled)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eLSS 2
+%ifndef USE_386
+	cli							; Disable interrupts
+	mov		%1, [%2]			; Load offset
+	mov		ss, [%2+2]			; Load segment
+;-----------------------------------
+%else
+	lss		%1, [%2]
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Repeats string instruction with segment override.
+; This macro prevents 8088/8086 restart bug.
+;
+; eSEG_STR
+;	Parameters:
+;		%1:		REP/REPNE or REPE prefix
+;		%2:		Source segment override (destination is always ES)
+;		%3:		String instruction
+;		CX:		Repeat count
+;	Returns:
+;		FLAGS for cmps and scas only
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eSEG_STR 3
+%ifndef USE_186	; 8088/8086 has string instruction restart bug when more than one prefix
+	%%Loop:
+		%1						; REP is the prefix that can be lost
+		%2						; SEG is the prefix that won't be lost
+		%3						; String instruction
+		jcxz	%%End			; Jump to end if no repeats left (preserves FLAGS)
+		jmp		SHORT %%Loop	; Loop while repeats left
+	%%End:
+%else	; No bug on V20/V30 and later, don't know about 188/186
+	%2
+	%1 %3
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Bit shifts and rotates with immediate.
+;
+; eSHIFT_IM
+;	Parameters:
+;		%1:		Shift target
+;		%2:		Number of bits to shift
+;		%3:		Instruction (SHL, SHR, ROL, ROR, RCL, RCR)
+;	Returns:
+;		FLAGS
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro eSHIFT_IM 3
+%ifndef USE_186
+	%ifidni %1, cl
+		times %2	%3		%1, 1
+	%elifidni %1, ch
+		times %2	%3		%1, 1
+	%elifidni %1, cx
+		times %2	%3		%1, 1
+	%else
+;		%if %2 > 7	; Original value
+		%if %2 > 3	; Size optimized value
+			push	cx
+			mov		cl, %2
+			%3		%1, cl
+			pop		cx
+		%else
+			times %2	%3		%1, 1
+		%endif
+	%endif
+;-----------------------------------
+%else
+	%3		%1, %2
+%endif
+%endmacro
+%macro eSHR_IM 2
+	eSHIFT_IM	%1, %2, shr
+%endmacro
+%macro eSHL_IM 2
+	eSHIFT_IM	%1, %2, shl
+%endmacro
+%macro eROR_IM 2
+	eSHIFT_IM	%1, %2, ror
+%endmacro
+%macro eROL_IM 2
+	eSHIFT_IM	%1, %2, rol
+%endmacro
+%macro eRCR_IM 2
+	eSHIFT_IM	%1, %2, rcr
+%endmacro
+%macro eRCL_IM 2
+	eSHIFT_IM	%1, %2, rcl
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates PUSH imm instruction when necessary.
+;
+; ePUSH_I
+;	Parameters:
+;		%1:		Immediate to push
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro ePUSH_I 1
+%ifndef USE_186
+	push	bp					; Immediate goes here
+	push	bp
+	mov		bp, sp
+	mov		WORD [bp+2], %1
+	pop		bp
+;-----------------------------------
+%else
+	push	%1
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Emulates PUSH imm instruction when necessary.
+; ePUSH_T uses temporary register for faster performance
+; and smaller code size than ePUSH_I.
+;
+; ePUSH_T
+;	Parameters:
+;		%1:		Temporary Register
+;		%2:		Immediate to push
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		%1
+;--------------------------------------------------------------------
+%macro ePUSH_T 2
+%ifndef USE_186
+	%ifidni %2, 0
+		xor		%1, %1
+	%else
+		mov		%1, %2
+	%endif
+	push	%1
+;-----------------------------------
+%else
+	push	%2
+%endif
+%endmacro
+
+
+%endif ; EMULATE_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/File.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/File.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/File.inc	(revision 348)
@@ -0,0 +1,37 @@
+; File name		:	File.inc
+; Project name	:	Assembly Library
+; Created date	:	8.10.2010
+; Last update	:	6.12.2010
+; Author		:	Tomi Tilli
+; Description	:	File library defines.
+%ifndef FILE_INC
+%define FILE_INC
+
+; File access and sharing modes
+struc FILE_ACCESS
+	.ReadOnly		resb	1
+	.WriteOnly		resb	1
+	.ReadAndWrite	resb	1
+endstruc
+
+; Origin of file seek
+struc SEEK_FROM
+	.startOfFile			resb	1	; 00h
+	.currentFilePosition	resb	1	; 01h
+	.endOfFile				resb	1	; 02h
+endstruc
+
+; File attribute flags
+FLG_FILEATTR_READ_ONLY			EQU		(1<<0)
+FLG_FILEATTR_HIDDEN				EQU		(1<<1)
+FLG_FILEATTR_SYSTEM				EQU		(1<<2)
+FLG_FILEATTR_VOLUME_LABEL		EQU		(1<<3)
+FLG_FILEATTR_DIRECTORY			EQU		(1<<4)
+FLG_FILEATTR_ARCHIVE			EQU		(1<<5)
+
+
+; Max number of bytes to read/write per DOS call when transferring DX:CX bytes
+SPLIT_SIZE_FOR_LARGE_TRANSFERS	EQU		(32<<10)
+
+
+%endif ; FILE_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Macros.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Macros.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Macros.inc	(revision 348)
@@ -0,0 +1,126 @@
+; Project name	:	Assembly Library
+; Description	:	This is the place to put various generic macros.
+;					Should be included immediately after emulate.inc
+%ifndef MACROS_INC
+%define MACROS_INC
+
+;--------------------------------------------------------------------
+; Skips the immediately following 2 byte instruction by using it
+; as an immediate value to a dummy instruction.
+; Destroys the contents of %1.
+;
+; SKIP2B
+;	Parameters:
+;		%1:		Any 16 bit general purpose register or F for flags.
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		%1
+;--------------------------------------------------------------------
+%macro SKIP2B 1
+	%ifidni		%1, f
+		db	03Dh					; Opcode byte for CMP AX, <immed>
+		;db	0A9h					; Alt. version TEST AX, <immed>
+	%elifidni	%1, ax
+		db	0B8h					; Opcode byte for MOV AX, <immed>
+	%elifidni	%1, cx
+		db	0B9h					; Opcode byte for MOV CX, <immed>
+	%elifidni	%1, dx
+		db	0BAh					; Opcode byte for MOV DX, <immed>
+	%elifidni	%1, bx
+		db	0BBh					; Opcode byte for MOV BX, <immed>
+	%elifidni	%1, sp
+		db	0BCh					; Opcode byte for MOV SP, <immed>
+	%elifidni	%1, bp
+		db	0BDh					; Opcode byte for MOV BP, <immed>
+	%elifidni	%1, si
+		db	0BEh					; Opcode byte for MOV SI, <immed>
+	%elifidni	%1, di
+		db	0BFh					; Opcode byte for MOV DI, <immed>
+	%else
+		%error "Invalid parameter passed to SKIP2B"
+	%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Load BDA (Bios Data Area) segment to wanted segment register.
+;
+; Use an exclamation point (!) as the third parameter when you want
+; to force the use of the register in the second parameter. This is
+; useful when that register needs to be zeroed in subsequent code or
+; when stack usage is undesirable (ie speed is critical).
+;
+; The PRESERVE_FLAGS version will zero the register with a MOV instead
+; of an XOR, thus preserving the flags.  It is one byte larger on
+; non-186 or higher systems.
+;
+; LOAD_BDA_SEGMENT_TO
+; LOAD_BDA_SEGMENT_PRESERVE_FLAGS_TO
+;	Parameters:
+;		%1:		Destination Segment Register
+;		%2:		Temporary WORD Register
+;		%3:		Can be ! or empty
+;	Returns:
+;		%1:		BDA segment (zero)
+;	Corrupts registers:
+;		%2
+;--------------------------------------------------------------------
+%macro LOAD_BDA_SEGMENT_TO 2-3
+%ifndef USE_186
+	xor		%2, %2
+	mov		%1, %2
+%elifidn %3, !
+	xor		%2, %2
+	mov		%1, %2
+%else
+	push	BYTE 0
+	pop		%1
+%endif
+%endmacro
+
+%macro LOAD_BDA_SEGMENT_PRESERVE_FLAGS_TO 2-3
+%ifndef USE_186
+	mov		%2, 0
+	mov		%1, %2
+%elifidn %3, !
+	mov		%2, 0
+	mov		%1, %2
+%else
+	push	BYTE 0
+	pop		%1
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; eENTER_STRUCT
+;	Parameters:
+;		%1:		Number of bytes to reserve from stack
+;	Returns:
+;		SS:BP:	Ptr to beginning of struct reserved from stack
+;	Corrupts registers:
+;		FLAGS
+;--------------------------------------------------------------------
+%macro eENTER_STRUCT 1
+	push	bp
+	sub		sp, %1
+	mov		bp, sp
+%endmacro
+
+;--------------------------------------------------------------------
+; eLEAVE_STRUCT
+;	Parameters:
+;		%1:		Number of bytes reserved with eENTER_STRUCT
+;	Returns:
+;		BP:		What it was before eENTER_STRUCT
+;	Corrupts registers:
+;		FLAGS
+;--------------------------------------------------------------------
+%macro eLEAVE_STRUCT 1
+	add		sp, %1
+	pop		bp
+%endmacro
+
+
+%endif ; MACROS_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Math.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Math.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Math.inc	(revision 348)
@@ -0,0 +1,108 @@
+; Project name	:	Assembly Library
+; Description	:	Math related macros.
+%ifndef MATH_INC
+%define MATH_INC
+
+FALSE		EQU		0
+TRUE		EQU		1
+
+
+;--------------------------------------------------------------------
+; MIN_U		Unsigned comparison
+; MIN_S		Signed comparison
+;	Parameters:
+;		%1:		Operand 1
+;		%2:		Operand 2
+;	Returns:
+;		%1:		Lesser operand
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro MIN_U 2
+	cmp		%1, %2				; Is %1 smaller?
+	jb		%%Return			;  If so, return
+	mov		%1, %2				; Copy %2 to %1
+ALIGN JUMP_ALIGN
+%%Return:
+%endmacro
+
+%macro MIN_S 2
+	cmp		%1, %2				; Is %1 smaller?
+	jl		%%Return			;  If so, return
+	mov		%1, %2				; Copy %2 to %1
+ALIGN JUMP_ALIGN
+%%Return:
+%endmacro
+
+
+;--------------------------------------------------------------------
+; MAX_U		Unsigned comparison
+; MAX_S		Signed comparison
+;	Parameters:
+;		%1:		Operand 1
+;		%2:		Operand 2
+;	Returns:
+;		%1:		Greater operand
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro MAX_U 2
+	cmp		%1, %2				; Is %1 greater?
+	ja		%%Return			;  If so, return
+	mov		%1, %2				; Copy %2 to %1
+ALIGN JUMP_ALIGN
+%%Return:
+%endmacro
+
+%macro MAX_S 2
+	cmp		%1, %2				; Is %1 greater?
+	jg		%%Return			;  If so, return
+	mov		%1, %2				; Copy %2 to %1
+ALIGN JUMP_ALIGN
+%%Return:
+%endmacro
+
+
+;--------------------------------------------------------------------
+; SHL_DXAX
+;	Parameters:
+;		%1:		Number of bits to shift
+;	Returns:
+;		DX:AX	Shifted value
+;	Corrupts registers:
+;		CX
+;--------------------------------------------------------------------
+%macro SHL_DXAX 1
+	%ifnidni %1, cx
+		mov		cx, %1
+	%endif
+ALIGN JUMP_ALIGN
+.ShiftNextBit:
+	shl		ax, 1
+	rcl		dx, 1
+	loop	.ShiftNextBit
+%endmacro
+
+
+;--------------------------------------------------------------------
+; SHR_DXAX
+;	Parameters:
+;		%1:		Number of bits to shift
+;	Returns:
+;		DX:AX	Shifted value
+;	Corrupts registers:
+;		CX
+;--------------------------------------------------------------------
+%macro SHR_DXAX 1
+	%ifnidni %1, cx
+		mov		cx, %1
+	%endif
+ALIGN JUMP_ALIGN
+.ShiftNextBit:
+	shr		dx, 1
+	rcr		ax, 1
+	loop	.ShiftNextBit
+%endmacro
+
+
+%endif ; MATH_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Menu.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Menu.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Menu.inc	(revision 348)
@@ -0,0 +1,158 @@
+; Project name	:	Assembly Library
+; Description	:	Defines for Menu library.
+%ifndef MENU_INC
+%define MENU_INC
+
+;--------------------------------------------------------------------
+; Menu Library users need to use this macro since it will provide
+; compatibility with future library versions.
+;
+; CALL_MENU_LIBRARY
+;	Parameters:
+;		%1:			Function to call (functionName from MENU_LIB)
+;		BP:			Menu handle
+;		Registers:	Depends on function to call
+;	Returns:
+;		Depends on function to call
+;	Corrupts registers:
+;		AX (unless used as a return register), DI
+;--------------------------------------------------------------------
+%macro CALL_MENU_LIBRARY 1
+	%ifidn %1, CloseMenuIfExitEventAllows
+		call	MenuInit_CloseMenuIfExitEventAllows
+
+	%elifidn %1, Close
+		call	MenuInit_CloseMenuWindow
+
+	%elifidn %1, SetUserDataFromDSSI
+		call	MenuInit_SetUserDataFromDSSI
+
+	%elifidn %1, GetUserDataToDSSI
+		call	MenuInit_GetUserDataToDSSI
+
+	%elifidn %1, SetTitleHeightFromAL
+		call	MenuInit_SetTitleHeightFromAL
+
+	%elifidn %1, GetHighlightedItemToAX
+		call	MenuInit_GetHighlightedItemToAX
+
+	%elifidn %1, SetTotalItemsFromAX
+		call	MenuInit_SetTotalItemsFromAX
+
+	%elifidn %1, SetInformationHeightFromAL
+		call	MenuInit_SetInformationHeightFromAL
+
+	%elifidn %1, SetTimeoutValueFromAX
+		call	MenuTime_SetSelectionTimeoutValueFromAX
+
+	%else
+		mov		di, %1
+		call	Menu_FunctionFromDI
+	%endif
+%endmacro
+
+%if 0
+;;;
+;;; struc no longer needed with direct call to function
+;;;
+
+; Menu library functions
+struc MENU_LIB
+	.DisplayWithHandlerInBXandUserDataInDXAX	resb	2
+	.SendExitMenuEvent:
+	.Close:
+	.RefreshWindow								resb	2
+
+	.SetUserDataFromDSSI:
+	.GetUserDataToDSSI:
+
+	.SetTitleHeightFromAL:
+	.ClearTitleArea								resb	2
+	.RefreshTitle								resb	2
+
+	.GetHighlightedItemToAX:
+	.HighlightItemFromAX						resb	2
+	.SetTotalItemsFromAX:
+	.RefreshItemFromAX							resb	2
+
+	.SetInformationHeightFromAL:
+	.ClearInformationArea						resb	2
+	.RefreshInformation							resb	2
+
+	.StartSelectionTimeoutWithTicksInAX			resb	2
+
+%ifdef INCLUDE_MENU_DIALOGS
+	.StartProgressTaskWithIoInDSSIandParamInDXAX	resb	2
+	.SetProgressValueFromAX							resb	2
+
+	.DisplayMessageWithInputInDSSI					resb	2
+	.GetSelectionToAXwithInputInDSSI				resb	2
+	.GetWordWithIoInDSSI							resb	2
+	.GetStringWithIoInDSSI							resb	2
+	.GetFileNameWithIoInDSSI						resb	2
+	.GetDriveWithIoInDSSI							resb	2
+%endif
+endstruc
+%endif
+
+; Menu initialization parameters
+struc MENUINIT
+	.wItems							resb	2	; Number of items in menu
+	.wHighlightedItem				resb	2	; Index for highlighted item
+
+	.wTitleAndInfoLines:
+	.bTitleLines					resb	1	; Number of title lines
+	.bInfoLines						resb	1	; Number of information lines
+
+	.wWidthAndHeight:
+	.bWidth							resb	1	; Menu width in characters
+	.bHeight						resb	1	; Menu height in characters
+endstruc
+
+
+; All menu parameters
+struc MENU
+	.menuInit						resb	MENUINIT_size	; Must be first
+	.fnEventHandler					resb	2	; Offset to Menu event handler
+	.dwUserData						resb	4	; User specified data
+
+	.bFlags							resb	1	; Menu flags
+									resb	1
+	.wTimeoutCounter				resb	2
+	.wFirstVisibleItem				resb	2	; Index for first visible item on the menu
+endstruc
+
+; Flags for MENU.wFlags
+FLG_MENU_EXIT						EQU		(1<<0)	; Close and exit menu
+FLG_MENU_NOHIGHLIGHT				EQU		(1<<1)	; Never highlight items
+FLG_MENU_USER_HANDLES_SCROLLING		EQU		(1<<2)
+FLG_MENU_TIMEOUT_COUNTDOWN			EQU		(1<<3)	; Timeout countdown in progress
+
+
+MENU_VERTICAL_BORDER_LINES			EQU		5	; Title top and bottom + Info top and bottom + bottom shadow
+MENU_HORIZONTAL_BORDER_LINES		EQU		3	; Left + Right borders + Right shadow
+MENU_TEXT_ROW_OFFSET				EQU		1
+MENU_TEXT_COLUMN_OFFSET				EQU		2
+MENU_TIMEOUT_STRING_CHARACTERS		EQU		19
+MENU_TIMEOUT_SECONDS_FOR_HURRY		EQU		3
+
+SCROLL_TRACK_CHARACTER				EQU		BLOCK_EVEN_BACKGROUND_AND_FOREGROUND
+SCROLL_THUMB_CHARACTER				EQU		BLOCK_FULL_FOREGROUND
+
+NO_ITEM_SELECTED					EQU		-1
+NO_ITEM_HIGHLIGHTED					EQU		-1
+NO_TIMEOUT_USED						EQU		0
+
+
+; Keyboard keys (scan codes) used by menu library
+;MENU_KEY_ENTER		EQU		1Ch
+;MENU_KEY_ESC		EQU		01h
+MENU_KEY_UP			EQU		48h
+MENU_KEY_DOWN		EQU		50h
+MENU_KEY_PGUP		EQU		49h
+MENU_KEY_PGDN		EQU		51h
+MENU_KEY_HOME		EQU		47h
+MENU_KEY_END		EQU		4Fh
+
+
+%endif ; MENU_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/MenuEvents.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/MenuEvents.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/MenuEvents.inc	(revision 348)
@@ -0,0 +1,104 @@
+; File name		:	MenuEvents.inc
+; Project name	:	Assembly Library
+; Created date	:	13.7.2010
+; Last update	:	18.10.2010
+; Author		:	Tomi Tilli
+; Description	:	Defines for Menu events send to the user.
+%ifndef MENUEVENTS_INC
+%define MENUEVENTS_INC
+
+;--------------------------------------------------------------------
+; Events to be processed in user implemented handler.
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Menu library handle
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+
+;
+; There are two ways to use MENUEVENT:
+;
+; 1. If the program needs two different menus, include the definition of the MENUEVENT structure below,
+;    instantiate with members that point to the routines that make up the menu.
+;
+; 2. If the program needs only one menu, %define MENUEVENT_INLINE_OFFSETS before this include file,
+;    and define (through EQU statements) each of the entry points as offsets from a base address.  
+; 
+
+;
+; If user level idle processing is desired, %define this symbol and .IdleProcessing will be called.
+; Otherwise, the code and structure entry will be omitted.  Note that INCLUDE_MENU_DIALOGS requires
+; the idle processing (if that is the case, it is turned on here).
+;
+;%define MENUEVENT_IDLEPROCESSING_ENABLE
+;
+
+%ifdef INCLUDE_MENU_DIALOGS
+%define MENUEVENT_IDLEPROCESSING_ENABLE
+%endif
+
+%ifndef MENUEVENT_INLINE_OFFSETS
+
+struc MENUEVENT
+	; Parameters:
+	;	DS:SI:		Ptr to MENUINIT struct to initialize
+	; Returns:
+	;	DS:SI:		Ptr to initialized MENUINIT struct
+	.InitializeMenuinitFromDSSI		resb	2
+%define MENUEVENT_InitializeMenuinitFromDSSI MENUEVENT.InitializeMenuinitFromDSSI
+
+	; Parameters:
+	;	None
+	; Returns:
+	;	CF:			Set to exit menu
+	;				Clear to cancel exit
+	.ExitMenu						resb	2
+%define MENUEVENT_ExitMenu MENUEVENT.ExitMenu
+
+%ifdef MENUEVENT_IDLEPROCESSING_ENABLE
+	; Parameters:
+	;	None
+	; See the definition of MENUEVENT_IDLEPROCESSING_ENABLE below.
+	.IdleProcessing					resb	2
+%define MENUEVENT_IdleProcessing MENUEVENT.IdleProcessing
+%endif
+
+	; Parameters:
+	;	CX:			Index of new highlighted item
+	;	DX:			Index of previously highlighted item or NO_ITEM_HIGHLIGHTED
+	.ItemHighlightedFromCX			resb	2
+%define MENUEVENT_ItemHighlightedFromCX MENUEVENT.ItemHighlightedFromCX
+
+	; Parameters:
+	;	CX:			Index of selected item
+	.ItemSelectedFromCX				resb	2
+%define MENUEVENT_ItemSelectedFromCX MENUEVENT.ItemSelectedFromCX
+
+	; Parameters:
+	;	AL:			ASCII character for the key
+	;	AH:			Keyboard library scan code for the key
+	.KeyStrokeInAX					resb	2
+%define MENUEVENT_KeyStrokeInAX MENUEVENT.KeyStrokeInAX
+
+	; Parameters:
+	;	CX:			Index of highlighted item
+	;	Cursor has been positioned to the beginning of first line
+	.RefreshTitle					resb	2
+	.RefreshInformation				resb	2
+%define MENUEVENT_RefreshTitle MENUEVENT.RefreshTitle
+%define MENUEVENT_RefreshInformation MENUEVENT.RefreshInformation
+
+	; Parameters:
+	;	CX:			Index of item to refresh
+	;	Cursor has been positioned to the beginning of item line
+	.RefreshItemFromCX				resb	2
+%define MENUEVENT_RefreshItemFromCX MENUEVENT.RefreshItemFromCX
+endstruc
+
+%endif ; MENUEVENTS_INLINE_OFFSETS
+
+%endif ; MENUEVENTS_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Registers.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Registers.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Registers.inc	(revision 348)
@@ -0,0 +1,194 @@
+; Project name	:	Assembly Library
+; Description	:	Register related macros.
+%ifndef REGISTERS_INC
+%define REGISTERS_INC
+
+struc INTPACK
+%ifdef USE_386
+;	.gs				resb	2
+;	.fs				resb	2
+%endif
+	.es				resb	2
+	.ds				resb	2
+	.di				resb	2
+	.si				resb	2
+	.bp				resb	2
+	.sp				resb	2
+	.bx:
+	.bl				resb	1
+	.bh				resb	1
+	.dx:
+	.dl				resb	1
+	.dh				resb	1
+	.cx:
+	.cl				resb	1
+	.ch				resb	1
+	.ax:
+	.al				resb	1
+	.ah				resb	1
+	.ip				resb	2
+	.cs				resb	2
+	.flags			resb	2
+endstruc
+
+; 8086/8088 FLAGS
+FLG_FLAGS_CF		EQU (1<<0)
+FLG_FLAGS_PF		EQU (1<<2)
+FLG_FLAGS_AF		EQU (1<<4)
+FLG_FLAGS_ZF		EQU (1<<6)
+FLG_FLAGS_SF		EQU (1<<7)
+FLG_FLAGS_TF		EQU (1<<8)
+FLG_FLAGS_IF		EQU (1<<9)
+FLG_FLAGS_DF		EQU (1<<10)
+FLG_FLAGS_OF		EQU (1<<11)
+
+
+;--------------------------------------------------------------------
+; This macro must be the first thing to call on Interrupt Service Routine.
+;
+; CREATE_INTPACK_TO_SSBP
+;	Parameters
+;		Nothing
+;	Returns:
+;		SS:BP:	Points to INTPACK
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro CREATE_INTPACK_TO_SSBP 0
+	ePUSHA
+	push	ds
+	push	es
+%ifdef USE_386
+;	push	fs
+;	push	gs
+%endif
+	mov		bp, sp
+%endmacro
+
+;--------------------------------------------------------------------
+; This macro must be the last thing to call on Interrupt Service Routine.
+;
+; RESTORE_INTPACK_FROM_SSBP
+;	Parameters
+;		SS:BP:	Ptr to INTPACK
+;	Returns:
+;		All Registers will be loaded from INTPACK
+;--------------------------------------------------------------------
+%macro RESTORE_INTPACK_FROM_SSBP 0
+%ifdef USE_386
+;	pop		gs
+;	pop		fs
+%endif
+	pop		es
+	pop		ds
+	ePOPA
+	iret
+%endmacro
+
+
+;--------------------------------------------------------------------
+; This macro must be the first thing to call on Interrupt Service Routine.
+;
+; CREATE_FRAME_INTPACK_TO_SSBP
+;	Parameters
+;		%1:		Number of extra bytes to reserve before INTPACK
+;	Returns:
+;		SS:BP:	Points to INTPACK
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro CREATE_FRAME_INTPACK_TO_SSBP 1
+	ePUSHA
+	push	ds
+	push	es
+%ifdef USE_386
+;	push	fs
+;	push	gs
+%endif
+	sub		sp, BYTE %1
+	mov		bp, sp
+%endmacro
+
+;--------------------------------------------------------------------
+; This macro must be the last thing to call on Interrupt Service Routine.
+;
+; RESTORE_FRAME_INTPACK_FROM_SSBP
+;	Parameters
+;		%1:		Number of extra bytes in INTPACK
+;		SS:BP:	Ptr to INTPACK
+;	Returns:
+;		All Registers will be loaded from INTPACK
+;--------------------------------------------------------------------
+%macro RESTORE_FRAME_INTPACK_FROM_SSBP 1
+	add		sp, BYTE %1
+%ifdef USE_386
+;	pop		gs
+;	pop		fs
+%endif
+	pop		es
+	pop		ds
+	ePOPA
+	iret
+%endmacro
+
+
+;--------------------------------------------------------------------
+; NORMALIZE_FAR_POINTER
+;	Parameters:
+;		%1:%2:		Far pointer to normalize
+;		%3:			Scratch register
+;		%4:			Scratch register
+;	Returns:
+;		%1:%2:		Normalized far pointer
+;	Corrupts registers:
+;		%3, %4
+;--------------------------------------------------------------------
+%macro NORMALIZE_FAR_POINTER 4
+	mov		%4, %2				; Copy offset to scratch reg
+	and		%2, BYTE 0Fh		; Clear offset bits 15...4
+	eSHR_IM	%4, 4				; Divide offset by 16
+	mov		%3, %1				; Copy segment to scratch reg
+	add		%3, %4				; Add shifted offset to segment
+	mov		%1, %3				; Set normalized segment
+%endmacro
+
+
+;--------------------------------------------------------------------
+; COPY_SSBP_TO_ESDI
+; COPY_SSBP_TO_DSSI
+; COPY_DSSI_TO_ESDI
+; COPY_ESDI_to_DSSI
+;	Parameters
+;		Nothing
+;	Returns:
+;		Copies farm pointer to different segment/pointer register pair
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro COPY_SSBP_TO_ESDI 0
+	push	ss
+	pop		es
+	mov		di, bp
+%endmacro
+
+%macro COPY_SSBP_TO_DSSI 0
+	push	ss
+	pop		ds
+	mov		si, bp
+%endmacro
+
+%macro COPY_DSSI_TO_ESDI 0
+	push	ds
+	pop		es
+	mov		di, si
+%endmacro
+
+%macro COPY_ESDI_to_DSSI 0
+	push	es
+	pop		ds
+	mov		si, di
+%endmacro
+
+
+
+%endif ; REGISTERS_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/Serial.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/Serial.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/Serial.inc	(revision 348)
@@ -0,0 +1,62 @@
+; Project name	:	AssemblyLibrary
+; Description	:	Defines for display library.
+
+%ifndef SERIAL_INC
+%define SERIAL_INC
+
+;--------------- UART Equates -----------------------------
+;
+; Serial Programming References:
+;    http://en.wikibooks.org/wiki/Serial_Programming
+;
+
+Serial_UART_base						EQU		0
+Serial_UART_transmitByte				EQU		0
+Serial_UART_receiveByte					EQU		0
+
+;
+; Values for UART_divisorLow:
+; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 4 = 28800, 3 = 38400, 2 = 57600, 1 = 115200
+;
+Serial_UART_divisorLow					EQU		0
+
+;
+; UART_divisorHigh is zero for all speeds including and above 1200 baud (which is all we do)
+;
+Serial_UART_divisorHigh					EQU		1
+
+Serial_UART_interruptIdent				EQU		2
+Serial_UART_FIFOControl					EQU		2
+
+Serial_UART_lineControl					EQU		3
+
+Serial_UART_modemControl				EQU		4
+
+Serial_UART_lineStatus					EQU		5
+
+Serial_UART_modemStatus					EQU		6
+
+Serial_UART_scratch						EQU		7
+
+;----------------------------------------------------------------------
+;
+; COM Number to I/O Port Address Mapping
+;
+; COM Number:                               1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12
+; Corresponds to I/O port:                3f8,  2f8,  3e8,  2e8,  2f0,  3e0,  2e0,  260,  368,  268,  360,  270
+; Corresponds to Packed I/O port (hex):    37,   17,   35,   15,   16,   34,   14,    4,   25,    5,   24,    6
+;
+SERIAL_COM1_IOADDRESS	EQU		3f8h
+SERIAL_COM2_IOADDRESS	EQU		2f8h
+SERIAL_COM3_IOADDRESS	EQU		3e8h
+SERIAL_COM4_IOADDRESS	EQU		2e8h
+SERIAL_COM5_IOADDRESS	EQU		2f0h
+SERIAL_COM6_IOADDRESS	EQU		3e0h
+SERIAL_COM7_IOADDRESS	EQU		2e0h
+SERIAL_COM8_IOADDRESS	EQU		260h
+SERIAL_COM9_IOADDRESS	EQU		368h
+SERIAL_COMA_IOADDRESS	EQU		268h
+SERIAL_COMB_IOADDRESS	EQU		360h
+SERIAL_COMC_IOADDRESS	EQU		270h
+
+%endif
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/SerialServer.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/SerialServer.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/SerialServer.inc	(revision 348)
@@ -0,0 +1,63 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Serial Server Defines
+
+%ifndef SERIALSERVER_INC
+%define SERIALSERVER_INC
+
+%include "Serial.inc"
+
+;
+; Command codes
+;
+SerialServer_Command_Header					EQU		0a0h
+SerialServer_Command_Write					EQU		(SerialServer_Command_Header | 3)
+SerialServer_Command_Read					EQU		(SerialServer_Command_Header | 2)
+SerialServer_Command_Inquire				EQU		(SerialServer_Command_Header | 0)
+SerialServer_Command_Custom_Read			EQU		(SerialServer_Command_Header | 4)
+SerialServer_Command_Custom_Write			EQU		(SerialServer_Command_Header | 5)
+
+SerialServer_SubCommand_Image_SendInitiate		EQU		1
+SerialServer_SubCommand_Image_SendSectors		EQU		2
+SerialServer_SubCommand_Image_SendComplete		EQU		3
+
+;
+; Locations within the ATA 512-byte Inquire structure, taken from the "Vendor specific area",
+; for serial port specific information that is returned by the server for an inquire.
+;
+; NOTE: These are byte offsets (because of the "*2"), which is more convenient here, while
+;       the ATA structure defines these in terms of word offsets.
+;
+SerialServer_ATA_wServerVersion			EQU		(157*2)
+SerialServer_ATA_wDriveFlags			EQU		(158*2)
+SerialServer_ATA_wPortAndBaud			EQU		(159*2)
+
+;
+; Command structure passed to SerialServer_SendReceive.  This mirrors IDEPACK in the XTIDE Universal BIOS, 
+; since that structure is passed directly without copying values into this structure.
+;
+struc SerialServer_Command
+	.wCommandAndCustom:	
+	.bCommand				resb	1
+
+	.bCustomCommand:	
+	.bDrvAndHead			resb	1	; LBA28 27...24
+
+	.wSectorCountAndLbaLow:
+	.bSectorCount			resb	1
+
+	.bCustomData3:		
+	.bSectorNumber:
+	.bLbaLow				resb	1	; LBA 7...0
+
+	.wCustomData1:		
+	.bCustomData1:		
+	.wCylinder:
+	.wLbaMiddleAndHigh:
+	.bLbaMiddle				resb	1	; LBA 15...8
+
+	.bCustomData2:		
+	.bLbaHigh				resb	1	; LBA 23...16
+endstruc
+
+%endif
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Inc/SystemTimer.inc
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Inc/SystemTimer.inc	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Inc/SystemTimer.inc	(revision 348)
@@ -0,0 +1,183 @@
+; Project name	:	Assembly Library
+; Description	:	System Timer (8254) relates equates and macros.
+%ifndef SYSTEMTIMER_INC
+%define SYSTEMTIMER_INC
+
+; Timer/Counter to program
+TIMER_0									EQU	(0<<6)
+TIMER_1									EQU	(1<<6)
+TIMER_2									EQU	(2<<6)
+
+; Counter commands
+LATCH									EQU	(0<<4)	; Counter Latch Command (latches the count for reading)
+READ_OR_WRITE_LSB_ONLY					EQU	(1<<4)	; MSB is always zero
+READ_OR_WRITE_MSB_ONLY					EQU	(2<<4)	; LSB is always zero
+READ_OR_WRITE_LSB_THEN_MSB				EQU	(3<<4)
+
+; Timer modes
+MODE_0_SINGLE_TIMEOUT					EQU	(0<<1)	; Interrupt on Terminal Count
+MODE_1_ONE_SHOT							EQU	(1<<1)	; Hardware Retriggerable One-Shot
+MODE_2_RATE_GENERATOR					EQU	(2<<1)
+MODE_3_SQUARE_WAVE_MODE					EQU	(3<<1)
+MODE_4_SOFTWARE_TRIGGERED_STROBE		EQU	(4<<1)
+MODE_5_HARDWARE_RETRIGGERABLE_STROBE	EQU	(5<<1)
+
+; Binary / BCD Mode
+BINARY_COUNTER							EQU	0
+BCD_COUNTER								EQU	1
+
+
+; Ports
+COUNT_REGISTER_0						EQU	40h		; Timer 0 Count Register (System Timer Ticks)
+COUNT_REGISTER_1						EQU	41h		; Timer 1 Count Register (DRAM Refresh)
+COUNT_REGISTER_2						EQU	42h		; Timer 2 Count Register (General Use)
+CONTROL_WORD_REGISTER_out				EQU	43h
+
+; Timer 2 is connected to PC Speaker that can be controller from port 61h.
+SPEAKER_CONTROL_REGISTER				EQU	61h
+FLG_TIMER_2_OUTPUT_in					EQU	(1<<5)	; AT+ only
+FLG_SPEAKER_DATA_ENABLED				EQU	(1<<1)
+FLG_SPEAKER_GATE_TIMER_2_ON				EQU	(1<<0)
+
+
+; The duration of one tick
+TIMER_CYCLE_TIME						EQU	838		; nanosecs
+
+
+
+
+;--------------------------------------------------------------------
+; OUTPUT_COUNTER_COMMAND_TO
+;	Parameters:
+;		%1:		TIMER_0, TIMER_1 or TIMER_2
+;		%2:		Command to counter
+;		%3:		Timer mode
+;		%4:		BINARY_COUNTER or BCD_COUNTER
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+%macro OUTPUT_COUNTER_COMMAND_TO 4
+	mov		al, %1 | %2 | %3 | %4
+	out		CONTROL_WORD_REGISTER_out, al
+%endmacro
+
+
+;--------------------------------------------------------------------
+; WRITE_COUNT_FROM_AL_TO
+; WRITE_COUNT_FROM_AX_TO
+;	Parameters:
+;		%1:		TIMER_0, TIMER_1 or TIMER_2
+;		AX:		Count to write to timer
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL (WRITE_COUNT_FROM_AX_TO only)
+;--------------------------------------------------------------------
+%macro WRITE_COUNT_FROM_AL_TO 1
+	%ifidni %1, TIMER_0
+		out		COUNT_REGISTER_0, al
+	%elifidni %1, TIMER_1
+		out		COUNT_REGISTER_1, al
+	%elifidni %1, TIMER_2
+		out		COUNT_REGISTER_2, al
+	%else
+		%error "Invalid timer name passed to WRITE_COUNT_FROM_AL_TO"
+	%endif
+%endmacro
+
+%macro WRITE_COUNT_FROM_AX_TO 1
+	%ifidni %1, TIMER_0
+		out		COUNT_REGISTER_0, al
+		mov		al, ah
+		out		COUNT_REGISTER_0, al
+	%elifidni %1, TIMER_1
+		out		COUNT_REGISTER_1, al
+		mov		al, ah
+		out		COUNT_REGISTER_1, al
+	%elifidni %1, TIMER_2
+		out		COUNT_REGISTER_2, al
+		mov		al, ah
+		out		COUNT_REGISTER_2, al
+	%else
+		%error "Invalid timer name passed to WRITE_COUNT_FROM_AX_TO"
+	%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
+; READ_COUNT_TO_AL_FROM
+; READ_COUNT_TO_AX_FROM
+;	Parameters:
+;		%1:		TIMER_0, TIMER_1 or TIMER_2
+;	Returns:
+;		AL/AX:	Counter value
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro READ_COUNT_TO_AL_FROM 1
+	%ifidni %1, TIMER_0
+		in		al, COUNT_REGISTER_0
+	%elifidni %1, TIMER_1
+		in		al, COUNT_REGISTER_1
+	%elifidni %1, TIMER_2
+		in		al, COUNT_REGISTER_2
+	%else
+		%error "Invalid timer name passed to READ_COUNT_TO_AL_FROM"
+	%endif
+%endmacro
+
+%macro READ_COUNT_TO_AX_FROM 1
+	%ifidni %1, TIMER_0
+		in		al, COUNT_REGISTER_0
+		mov		ah, al
+		in		al, COUNT_REGISTER_0
+	%elifidni %1, TIMER_1
+		in		al, COUNT_REGISTER_1
+		mov		ah, al
+		in		al, COUNT_REGISTER_1
+	%elifidni %1, TIMER_2
+		in		al, COUNT_REGISTER_2
+		mov		ah, al
+		in		al, COUNT_REGISTER_2
+	%else
+		%error "Invalid timer name passed to READ_COUNT_TO_AX_FROM"
+	%endif
+		xchg	al, ah
+%endmacro
+
+
+;--------------------------------------------------------------------
+; START_PRECISE_EVENT_TIMER
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+%macro START_PRECISE_EVENT_TIMER 0
+	in		al, SPEAKER_CONTROL_REGISTER
+	or		al, FLG_SPEAKER_GATE_TIMER_2_ON
+	out		SPEAKER_CONTROL_REGISTER, al
+%endmacro
+
+
+;--------------------------------------------------------------------
+; STOP_PRECISE_EVENT_TIMER
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+%macro STOP_PRECISE_EVENT_TIMER 0
+	in		al, SPEAKER_CONTROL_REGISTER
+	and		al, ~(FLG_SPEAKER_DATA_ENABLED | FLG_SPEAKER_GATE_TIMER_2_ON)
+	out		SPEAKER_CONTROL_REGISTER, al
+%endmacro
+
+
+%endif ; SYSTEMTIMER_INC
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/AssemblyLibrary.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/AssemblyLibrary.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/AssemblyLibrary.asm	(revision 348)
@@ -0,0 +1,100 @@
+; Project name	:	Assembly Library
+; Description	:	Assembly Library main file. This is the only file that
+;					needs to be included.
+
+; Section containing code
+SECTION .text
+
+%ifdef INCLUDE_DISPLAY_LIBRARY
+	%include "CgaSnow.asm"
+	%include "Display.asm"
+	%include "DisplayCharOut.asm"
+	%include "DisplayContext.asm"
+	%include "DisplayCursor.asm"
+	%include "DisplayPage.asm"
+	%include "DisplayPrint.asm"					; must come before DisplayFormat/DisplayFormatCompressed			
+%ifdef MODULE_STRINGS_COMPRESSED
+	%include "DisplayFormatCompressed.asm"
+%else
+	%include "DisplayFormat.asm"		
+%endif
+%endif
+
+%ifdef INCLUDE_FILE_LIBRARY
+	%include "Directory.asm"
+	%include "DosCritical.asm"
+	%include "Drive.asm"
+	%include "FileIO.asm"
+%endif
+
+%ifdef INCLUDE_KEYBOARD_LIBRARY
+	%include "Keyboard.asm"
+%endif
+
+%ifdef INCLUDE_MENU_LIBRARY
+	%include "CharOutLineSplitter.asm"
+	%include "Menu.asm"
+	%include "MenuAttributes.asm"
+	%include "MenuBorders.asm"
+	%include "MenuCharOut.asm"
+	%include "MenuEvent.asm"
+	%include "MenuInit.asm"
+	%include "MenuLocation.asm"
+	%include "MenuLoop.asm"
+	%include "MenuScrollbars.asm"
+	%include "MenuText.asm"
+	%include "MenuTime.asm"
+
+	%ifdef INCLUDE_MENU_DIALOGS
+		%include "Dialog.asm"
+		%include "DialogDrive.asm"
+		%include "DialogFile.asm"
+		%include "DialogMessage.asm"
+		%include "DialogProgress.asm"
+		%include "DialogSelection.asm"
+		%include "DialogString.asm"
+		%include "DialogWord.asm"
+		%include "ItemLineSplitter.asm"
+		%include "StringsForDialogs.asm"
+	%endif
+%endif
+
+%ifdef INCLUDE_STRING_LIBRARY
+	%include "Char.asm"
+	%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+		%include "String.asm"
+		%include "StringProcess.asm"
+	%endif
+%endif
+
+%ifdef INCLUDE_SERIAL_LIBRARY
+	%include "Serial.inc"
+%endif		
+%ifdef INCLUDE_SERIALSERVER_LIBRARY
+	%include "SerialServer.asm"
+	%include "SerialServerScan.asm"
+	%define INCLUDE_TIME_LIBRARY
+%endif		
+
+%ifdef INCLUDE_TIME_LIBRARY
+	%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+		%include "Delay.asm"
+		%include "SystemTimer.asm"
+	%endif
+	%include "TimerTicks.asm"
+%endif
+
+%ifdef INCLUDE_UTIL_LIBRARY
+	%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+		%include "Bit.asm"
+	%endif
+	%include "Math.asm"
+	%include "Registers.asm"
+	%include "Reboot.asm"
+	%include "Memory.asm"
+	%include "Size.asm"
+	%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+		%include "Sort.asm"
+	%endif
+%endif
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/CgaSnow.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/CgaSnow.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/CgaSnow.asm	(revision 348)
@@ -0,0 +1,131 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for preventing CGA snow.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; CgaSnow_IsCgaPresent
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		CF:		Set if CGA detected
+;				Cleared if CGA not detected
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CgaSnow_IsCgaPresent:
+	cmp		WORD [BDA.wVidPort], CGA_STATUS_REGISTER - OFFSET_TO_CGA_STATUS_REGISTER
+	jne		SHORT .CgaNotFound
+
+	; All standard CGA modes use 25 rows but only EGA and later store it to BDA.
+	cmp		BYTE [BDA.bVidRows], 25
+	jge		SHORT .CgaNotFound
+	stc
+	ret
+ALIGN JUMP_ALIGN
+.CgaNotFound:
+	clc
+	ret
+
+
+; CGA snow prevention must be kept optional to avoid unnecessary
+; overhead when building programs meant for non-CGA systems.
+%ifdef ELIMINATE_CGA_SNOW
+
+;--------------------------------------------------------------------
+; CgaSnow_Stosb
+; CgaSnow_Stosw
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output (CgaSnow_StoswWithoutCgaSnow only)
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to video memory where to output
+;	Returns:
+;		DI:		Incremented for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CgaSnow_Stosb:
+	call	LoadCgaStatusRegisterAddressToDXifCgaPresent
+	jz		SHORT .StosbWithoutWaitSinceUnknownPort
+
+	mov		ah, al
+	cli				; Interrupt request would mess up timing
+	WAIT_UNTIL_SAFE_CGA_WRITE
+	mov		al, ah
+.StosbWithoutWaitSinceUnknownPort:
+	stosb
+	sti
+	ret
+
+ALIGN JUMP_ALIGN
+CgaSnow_Stosw:
+	push	bx
+	call	LoadCgaStatusRegisterAddressToDXifCgaPresent
+	jz		SHORT .StoswWithoutWaitSinceUnknownPort
+
+	xchg	bx, ax
+	cli				; Interrupt request would mess up timing
+	WAIT_UNTIL_SAFE_CGA_WRITE
+	xchg	ax, bx
+.StoswWithoutWaitSinceUnknownPort:
+	stosw
+	sti
+	pop		bx
+	ret
+
+
+;--------------------------------------------------------------------
+; CgaSnow_RepMovsb
+;	Parameters:
+;		CX:		Number of characters to copy
+;		DS:		BDA segment (zero)
+;		ES:SI:	Ptr to video memory where to read from
+;		ES:DI:	Ptr to video memory where to write to
+;	Returns:
+;		SI, DI:	Updated for next character
+;	Corrupts registers:
+;		AX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CgaSnow_RepMovsb:
+	call	LoadCgaStatusRegisterAddressToDXifCgaPresent
+	jz		SHORT .RepMovsbWithoutWaitSinceUnknownPort
+
+.MovsbNextByte:
+	cli				; Interrupt request would mess up timing
+	WAIT_UNTIL_SAFE_CGA_WRITE
+	es movsb
+	sti
+	loop	.MovsbNextByte
+	ret
+.RepMovsbWithoutWaitSinceUnknownPort:
+	eSEG_STR rep, es, movsb
+	ret
+
+
+;--------------------------------------------------------------------
+; LoadCgaStatusRegisterAddressToDXifCgaPresent
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		DX:		CGA Status Register Address
+;		ZF:		Set if CGA not present
+;				Cleared if CGA present
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+LoadCgaStatusRegisterAddressToDXifCgaPresent:
+	test	BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_CGA
+	jz		SHORT .NoCgaDetected
+	mov		dx, CGA_STATUS_REGISTER
+ALIGN JUMP_ALIGN, ret
+.NoCgaDetected:
+	ret
+
+
+%endif ; ELIMINATE_CGA_SNOW
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/Display.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/Display.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/Display.asm	(revision 348)
@@ -0,0 +1,97 @@
+; Project name	:	Assembly Library
+; Description	:	Display Library functions for CALL_DISPLAY_LIBRARY macro
+;					that users should use to make library call.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DisplayFunctionFromDI
+;	Parameters:
+;		DI:		Function to call (DISPLAY_LIB.functionName)
+;		Others:	Depends on function to call (DX cannot be parameter)
+;	Returns:
+;		Depends on function to call
+;	Corrupts registers:
+;		AX (unless used as a return register), DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Display_FunctionFromDI:
+	push	es
+	push	ds
+	push	dx
+
+	cld
+	LOAD_BDA_SEGMENT_TO	ds, dx
+	mov		dx, di
+	les		di, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
+	call	dx
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
+
+	pop		dx
+	pop		ds
+	pop		es
+	ret
+
+;--------------------------------------------------------------------
+; Display_FormatNullTerminatedStringFromCSSI
+;	Parameters:
+;		Same as DisplayPrint_FormattedNullTerminatedStringFromCSSI
+;	Returns:
+;		Stack variables will be cleaned
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Display_FormatNullTerminatedStringFromCSSI:
+	pop		ax					; Discard return address to inside Display_FunctionFromDI
+	call	DisplayPrint_FormattedNullTerminatedStringFromCSSI
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
+
+	pop		dx
+	pop		ds
+	pop		es
+
+	pop		ax					; Pop return address
+	mov		sp, bp				; Clean stack variables
+	jmp		ax
+
+
+	%define InitializeDisplayContext						DisplayContext_Initialize
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	%define SetCharacterPointerFromBXAX						DisplayContext_SetCharacterPointerFromBXAX
+%endif
+	%define SetCharOutputFunctionFromAXwithAttribFlagInBL	DisplayContext_SetCharOutputFunctionFromAXwithAttribFlagInBL
+	%define SetCharacterOutputParameterFromAX				DisplayContext_SetCharacterOutputParameterFromAX
+	%define SetCharacterAttributeFromAL						DisplayContext_SetCharacterAttributeFromAL
+	%define SetCursorShapeFromAX							DisplayCursor_SetShapeFromAX
+	%define SetCursorCoordinatesFromAX						DisplayCursor_SetCoordinatesFromAX
+	%define SetNewPageFromAL								DisplayPage_SetFromAL
+	%define SynchronizeDisplayContextToHardware				DisplayContext_SynchronizeToHardware
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	%define GetCharacterPointerToBXAX						DisplayContext_GetCharacterPointerToBXAX
+%endif
+	%define GetSoftwareCoordinatesToAX						DisplayCursor_GetSoftwareCoordinatesToAX
+	%define GetColumnsToALandRowsToAH						DisplayPage_GetColumnsToALandRowsToAH
+
+	%define FormatNullTerminatedStringFromCSSI				Display_FormatNullTerminatedStringFromCSSI
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	%define PrintSignedWordFromAXWithBaseInBX				DisplayPrint_SignedWordFromAXWithBaseInBX
+%endif
+	%define PrintWordFromAXwithBaseInBX						DisplayPrint_WordFromAXWithBaseInBX
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS OR EXCLUDE_FROM_XTIDECFG
+	%define PrintQWordFromSSBPwithBaseInBX					DisplayPrint_QWordFromSSBPwithBaseInBX
+%endif
+	%define PrintCharBufferFromBXSIwithLengthInCX			DisplayPrint_CharacterBufferFromBXSIwithLengthInCX
+	%define PrintNullTerminatedStringFromBXSI				DisplayPrint_NullTerminatedStringFromBXSI
+	%define PrintNullTerminatedStringFromCSSI				DisplayPrint_NullTerminatedStringFromCSSI
+	%define PrintRepeatedCharacterFromALwithCountInCX		DisplayPrint_RepeatCharacterFromALwithCountInCX
+	%define PrintCharacterFromAL							DisplayPrint_CharacterFromAL
+	%define PrintNewlineCharacters							DisplayPrint_Newline
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	%define ClearAreaWithHeightInAHandWidthInAL				DisplayPrint_ClearAreaWithHeightInAHandWidthInAL
+%endif
+	%define ClearScreenWithCharInALandAttrInAH				DisplayPrint_ClearScreenWithCharInALandAttributeInAH
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayCharOut.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayCharOut.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayCharOut.asm	(revision 348)
@@ -0,0 +1,116 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for outputting characters to video memory.
+;					These functions are meant to be called by Display_CharacterFromAL
+;					and Display_RepeatCharacterFromAL using function pointer
+;					stored in DISPLAY_CONTEXT.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DisplayCharOut_TeletypeOutputWithAttribute
+; DisplayCharOut_TeletypeOutput
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to video memory where to output
+;	Returns:
+;		DI:		Incremented for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCharOut_TeletypeOutputWithAttribute:
+	cmp		al, ' '							; Printable character?
+	jb		SHORT DisplayCharOut_BiosTeletypeOutput
+	WAIT_RETRACE_IF_NECESSARY_THEN stosw
+	ret
+
+ALIGN JUMP_ALIGN
+DisplayCharOut_TeletypeOutput:
+	cmp		al, ' '							; Printable character?
+	jae		SHORT DisplayCharOut_Character
+	; Fall to DisplayCharOut_BiosTeletypeOutput
+
+;--------------------------------------------------------------------
+; DisplayCharOut_BiosTeletypeOutput
+;	Parameters:
+;		AL:		Control character
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to video memory where to output
+;	Returns:
+;		DI:		Incremented for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCharOut_BiosTeletypeOutput:
+	push	ax
+	call	DisplayCursor_SynchronizeCoordinatesToHardware
+	pop		ax
+
+	; Output character with BIOS
+	push	bx
+	mov		ah, TELETYPE_OUTPUT
+	mov		bh, [VIDEO_BDA.bActivePage]
+	int		BIOS_VIDEO_INTERRUPT_10h
+	pop		bx
+
+	call	DisplayCursor_GetHardwareCoordinatesToAX
+	jmp		DisplayCursor_SetCoordinatesFromAX
+
+
+;--------------------------------------------------------------------
+; DisplayCharOut_Attribute
+; DisplayCharOut_Character
+; DisplayCharOut_CharacterWithAttribute
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to video memory where to output
+;	Returns:
+;		DI:		Incremented for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCharOut_Attribute:
+	xchg	al, ah				; Swap character and attribute
+	inc		di					; Skip character
+	WAIT_RETRACE_IF_NECESSARY_THEN stosb
+	ret
+
+ALIGN JUMP_ALIGN
+DisplayCharOut_Character:
+	WAIT_RETRACE_IF_NECESSARY_THEN stosb
+	inc		di					; Skip attribute
+	ret
+
+ALIGN JUMP_ALIGN
+DisplayCharOut_CharacterWithAttribute:
+	WAIT_RETRACE_IF_NECESSARY_THEN stosw
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayCharOut_WriteCharacterToBuffer
+;	Parameters:
+;		AL:		Character to output
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to destination string buffer
+;		DISPLAY_CONTEXT.wCharOutParam:	Characters left in buffer
+;	Returns:
+;		ES:DI:	Updated for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCharOut_WriteCharacterToBuffer:
+	cmp		WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam], BYTE 0
+	je		SHORT .BufferFull
+	stosb
+	dec		WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam]
+.BufferFull:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayContext.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayContext.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayContext.asm	(revision 348)
@@ -0,0 +1,323 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for managing display context.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DisplayContext_Initialize
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_Initialize:
+	mov		WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fnCharOut], DEFAULT_CHARACTER_OUTPUT
+	mov		BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], SCREEN_BACKGROUND_ATTRIBUTE
+	mov		ax, [VIDEO_BDA.wCursorShape]
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCursorShape], ax
+	; Fall to .DetectAndSetDisplaySegment
+
+;--------------------------------------------------------------------
+; .DetectAndSetDisplaySegment
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+.DetectAndSetDisplaySegment:
+	mov		ax, COLOR_TEXT_SEGMENT
+	cmp		BYTE [VIDEO_BDA.bMode], MDA_TEXT_MODE
+	eCMOVE	ah, MONO_TEXT_SEGMENT >> 8
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition+2], ax
+	; Fall to .InitializeFlags
+
+;--------------------------------------------------------------------
+; .InitializeFlags
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+.InitializeFlags:
+	mov		dl, FLG_CONTEXT_ATTRIBUTES
+	call	CgaSnow_IsCgaPresent
+	jnc		SHORT .DoNotSetCgaFlag
+	or		dl, FLG_CONTEXT_CGA
+.DoNotSetCgaFlag:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], dl
+	; Fall to .InitializeCursor
+
+;--------------------------------------------------------------------
+; .InitializeCursor
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+.InitializeCursor:
+	call	DisplayCursor_GetHardwareCoordinatesToAX	; Coordinates before init
+	call	DisplayCursor_SetCoordinatesFromAX			; Cursor to Display Context
+	; Fall to DisplayContext_SynchronizeToHardware
+
+;--------------------------------------------------------------------
+; DisplayContext_SynchronizeToHardware
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_SynchronizeToHardware:
+	call	DisplayPage_SynchronizeToHardware
+	call	DisplayCursor_SynchronizeShapeToHardware
+	jmp		DisplayCursor_SynchronizeCoordinatesToHardware
+
+
+;--------------------------------------------------------------------
+; DisplayContext_Push
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_Push:
+	mov		di, ds					; Backup DS
+	LOAD_BDA_SEGMENT_TO	ds, ax
+	pop		ax						; Pop return address
+
+%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS
+	%assign i 0
+	%rep DISPLAY_CONTEXT_size / 2
+		push	WORD [VIDEO_BDA.displayContext + i]
+	%assign i i+2
+	%endrep
+%endif
+		
+	mov		ds, di					; Restore DS
+	jmp		ax
+
+;--------------------------------------------------------------------
+; DisplayContext_Pop
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_Pop:
+	mov		di, ds					; Backup DS
+	LOAD_BDA_SEGMENT_TO	ds, ax
+	pop		ax						; Pop return address
+
+%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS		
+	%assign i DISPLAY_CONTEXT_size-2
+	%rep DISPLAY_CONTEXT_size / 2
+		pop		WORD [VIDEO_BDA.displayContext + i]
+	%assign i i-2
+	%endrep
+%endif
+		
+	push	ax						; Push return address
+	push	dx
+	call	DisplayContext_SynchronizeToHardware
+	pop		dx
+	mov		ds, di					; Restore DS
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayContext_PrepareOffScreenBufferInESBXwithLengthInCX
+;	Parameters:
+;		CX:		Off screen buffer length in characters
+;		ES:BX:	Ptr to off screen buffer
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DI
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayContext_PrepareOffScreenBufferInESBXwithLengthInCX:
+	push	ds
+
+	LOAD_BDA_SEGMENT_TO	ds, di
+	xchg	ax, bx
+	mov		bx, es
+	call	DisplayContext_SetCharacterPointerFromBXAX	; ES:DI now has the pointer
+
+	mov		bl, ATTRIBUTES_NOT_USED
+	mov		ax, BUFFER_OUTPUT_WITH_CHAR_ONLY
+	call	DisplayContext_SetCharOutputFunctionFromAXwithAttribFlagInBL
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam], cx
+
+	mov		bx, di
+	pop		ds
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayContext_SetCharacterPointerFromBXAX
+;	Parameters:
+;		BX:AX:	Ptr to destination for next character to output
+;		DS:		BDA segment (zero)
+;	Returns:
+;		ES:DI:	Pointer that was in BX:AX
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayContext_SetCharacterPointerFromBXAX:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], ax
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition+2], bx
+	xchg	di, ax
+	mov		es, bx
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayContext_GetCharacterPointerToBXAX
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		BX:AX:	Ptr to destination for next character to output
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayContext_GetCharacterPointerToBXAX:
+	mov		ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
+	mov		bx, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition+2]
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayContext_SetCharOutputFunctionFromAXwithAttribFlagInBL
+;	Parameters:
+;		AX:		Offset to character output function
+;		BL:		Attribute Flag
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		BL
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_SetCharOutputFunctionFromAXwithAttribFlagInBL:
+	and		bl, FLG_CONTEXT_ATTRIBUTES
+	and		BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], ~FLG_CONTEXT_ATTRIBUTES
+	or		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], bl
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fnCharOut], ax
+	ret
+		
+
+;--------------------------------------------------------------------
+; DisplayContext_SetCharacterAttributeFromAL
+;	Parameters:
+;		AL:		Character attribute
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_SetCharacterAttributeFromAL:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayContext_SetCharacterOutputParameterFromAX
+;	Parameters:
+;		AX:		Parameter for Character Output function
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayContext_SetCharacterOutputParameterFromAX:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam], ax
+	ret
+
+		
+;--------------------------------------------------------------------
+; DisplayContext_GetCharacterOutputParameterToDX
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		DX:		User parameter for Character Output function
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS OR EXCLUDE_FROM_XTIDECFG	; This is currently unused (dead code)
+ALIGN JUMP_ALIGN
+DisplayContext_GetCharacterOutputParameterToDX:
+	mov		dx, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam]
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
+;	Parameters:
+;		AX:		Offset in bytes from some character to another
+;		DS:		BDA segment (zero)
+;	Returns:
+;		AX:		Offset in characters from some character to another
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef MODULE_STRINGS_COMPRESSED
+ALIGN JUMP_ALIGN
+DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX:
+	test	BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
+	jz		SHORT ReturnOffsetInAX
+	sar		ax, 1		; BYTE count to WORD count
+	ret
+%endif
+
+		
+;--------------------------------------------------------------------
+; DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
+;	Parameters:
+;		AX:		Offset in characters from some character to another
+;		DS:		BDA segment (zero)
+;	Returns:
+;		AX:		Offset in bytes from some character to another
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef MODULE_STRINGS_COMPRESSED
+ALIGN JUMP_ALIGN
+DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX:
+	test	BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
+	jz		SHORT ReturnOffsetInAX
+	sal		ax, 1		; WORD count to BYTE count
+ALIGN JUMP_ALIGN, ret
+ReturnOffsetInAX:
+	ret
+%endif
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayCursor.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayCursor.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayCursor.asm	(revision 348)
@@ -0,0 +1,163 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for managing display cursor.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DisplayCursor_SetShapeFromAX
+;	Parameters:
+;		AX:		Cursor shape (AH=Start scan line, AL=End scan line)
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCursor_SetShapeFromAX:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCursorShape], ax
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayCursor_SetCoordinatesFromAX
+;	Parameters:
+;		AL:		Cursor column (X-coordinate)
+;		AH:		Cursor row (Y-coordinate)
+;		DS:		BDA segment (zero)
+;	Returns:
+;		DI:		Offset to cursor location in video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCursor_SetCoordinatesFromAX:
+	xchg	dx, ax
+	mov		ax, [VIDEO_BDA.wColumns]		; Column count, 40 or 80
+	mul		dh								; AX = Column count * row index
+	xor		dh, dh
+	add		ax, dx							; Add column offset
+	shl		ax, 1							; Convert to WORD offset
+	add		ax, [VIDEO_BDA.wPageOffset]		; AX = Video RAM offset
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], ax
+	xchg	di, ax
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayCursor_GetSoftwareCoordinatesToAX
+;	Parameters:
+;		AX:		Offset to cursor location in selected page
+;		DS:		BDA segment (zero)
+;	Returns:
+;		AL:		Cursor column (X-coordinate)
+;		AH:		Cursor row (Y-coordinate)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCursor_GetSoftwareCoordinatesToAX:
+	mov		ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
+	sub		ax, [VIDEO_BDA.wPageOffset]
+	shr		ax, 1							; WORD offset to character offset
+	div		BYTE [VIDEO_BDA.wColumns]		; AL = full rows, AH = column index for last row
+	xchg	al, ah
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayCursor_GetHardwareCoordinatesToAX
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		AL:		Hardware cursor column (X-coordinate)
+;		AH:		Hardware cursor row (Y-coordinate)
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCursor_GetHardwareCoordinatesToAX:
+	push	cx
+	push	bx
+
+	mov		ah, GET_CURSOR_POSITION_AND_SIZE
+	mov		bh, [VIDEO_BDA.bActivePage]
+	int		BIOS_VIDEO_INTERRUPT_10h
+	xchg	ax, dx
+
+	pop		bx
+	pop		cx
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayCursor_SynchronizeShapeToHardware
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCursor_SynchronizeShapeToHardware:
+	mov		dx, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCursorShape]
+	; Fall to .SetHardwareCursorShapeFromDX
+
+;--------------------------------------------------------------------
+; .SetHardwareCursorShapeFromDX
+;	Parameters:
+;		DX:		Cursor shape
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+.SetHardwareCursorShapeFromDX:
+	cmp		dx, [VIDEO_BDA.wCursorShape]
+	je		SHORT .Return					; Return if no changes
+	push	cx
+	mov		cx, dx							; BIOS wants cursor shape in CX
+	mov		al, [VIDEO_BDA.bMode]			; Load video mode to prevent lock ups on some BIOSes
+	mov		ah, SET_TEXT_MODE_CURSOR_SHAPE
+	int		BIOS_VIDEO_INTERRUPT_10h
+	pop		cx
+.Return:
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayCursor_SynchronizeCoordinatesToHardware
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayCursor_SynchronizeCoordinatesToHardware:
+	call	DisplayCursor_GetSoftwareCoordinatesToAX
+	; Fall to .SetHardwareCursorCoordinatesFromAX
+
+;--------------------------------------------------------------------
+; .SetHardwareCursorCoordinatesFromAX
+;	Parameters:
+;		AL:		Cursor column (X-coordinate)
+;		AH:		Cursor row (Y-coordinate)
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+.SetHardwareCursorCoordinatesFromAX:
+	push	bx
+	xchg	dx, ax							; BIOS wants coordinates in DX
+	mov		ah, SET_CURSOR_POSITION
+	mov		bh, [VIDEO_BDA.bActivePage]
+	int		BIOS_VIDEO_INTERRUPT_10h
+	pop		bx
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayFormat.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayFormat.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayFormat.asm	(revision 348)
@@ -0,0 +1,420 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for displaying formatted strings.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DisplayFormat_ParseCharacters
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		SS:BP:	Pointer to first format parameter (-=2 updates to next parameter)
+;		CS:SI:	Pointer to string to format
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		CS:SI:	Ptr to end of format string (ptr to one past NULL)
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, BX, CX, DX, BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayFormat_ParseCharacters:
+	call	ReadCharacterAndTestForNull
+	jz		SHORT ReturnFromFormat
+
+	ePUSH_T	cx, DisplayFormat_ParseCharacters	; Return address
+	xor		cx, cx								; Initial placeholder size
+	cmp		al, '%'								; Format specifier?
+	jne		SHORT DisplayPrint_CharacterFromAL
+	; Fall to ParseFormatSpecifier
+
+;--------------------------------------------------------------------
+; ParseFormatSpecifier
+;	Parameters:
+;		CX:		Placeholder size
+;		DS:		BDA segment (zero)
+;		SS:BP:	Pointer to first format parameter (-=2 for next parameter)
+;		CS:SI:	Pointer to string to format
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		SI:		Updated to first unparsed character
+;		DI:		Updated offset to video RAM
+;		BP:		Updated to next format parameter
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ParseFormatSpecifier:
+	call	ReadCharacterAndTestForNull
+	call	Char_IsDecimalDigitInAL
+	jc		SHORT ParsePlaceholderSizeDigitFromALtoCX
+	call	GetFormatSpecifierParserToAX
+	call	ax				; Parser function
+	dec		bp
+	dec		bp				; SS:BP now points to next parameter
+	inc		cx
+	loop	PrependOrAppendSpaces
+ReturnFromFormat:
+	ret
+
+;--------------------------------------------------------------------
+; ParsePlaceholderSizeDigitFromALtoCX
+;	Parameters:
+;		AL:		Digit character from format string
+;		CX:		Current placeholder size
+;		DS:		BDA segment (zero)
+;	Returns:
+;		CX:		Current placeholder size
+;		Jumps back to ParseFormatSpecifier
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ParsePlaceholderSizeDigitFromALtoCX:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
+	sub		al, '0'				; Digit '0'...'9' to integer 0...9
+	mov		ah, cl				; Previous number parameter to AH
+	aad							; AL += (AH * 10)
+	mov		cl, al				; Updated number parameter now in CX
+	jmp		SHORT ParseFormatSpecifier
+
+
+;--------------------------------------------------------------------
+; ReadCharacterAndTestForNull
+;	Parameters:
+;		CS:SI:	Pointer next character from string
+;	Returns:
+;		AL:		Character from string
+;		SI:		Incremented to next character
+;		ZF:		Set if NULL, cleared if valid character
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ReadCharacterAndTestForNull:
+	cs lodsb								; Load from CS:SI to AL
+	test	al, al							; NULL to end string?
+	ret
+
+
+;--------------------------------------------------------------------
+; GetFormatSpecifierParserToAX
+;	Parameters:
+;		AL:		Format specifier character
+;	Returns:
+;		AX:		Offset to parser function
+;	Corrupts registers:
+;		AX, BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetFormatSpecifierParserToAX:
+	mov		bx, .rgcFormatCharToLookupIndex
+ALIGN JUMP_ALIGN
+.CheckForNextSpecifierParser:
+	cmp		al, [cs:bx]
+	je		SHORT .ConvertIndexToFunctionOffset
+	inc		bx
+	cmp		bx, .rgcFormatCharToLookupIndexEnd
+	jb		SHORT .CheckForNextSpecifierParser
+	mov		ax, c_FormatCharacter
+	ret
+ALIGN JUMP_ALIGN
+.ConvertIndexToFunctionOffset:
+	sub		bx, .rgcFormatCharToLookupIndex
+	shl		bx, 1				; Shift for WORD lookup
+	mov		ax, [cs:bx+.rgfnFormatSpecifierParser]
+	ret
+
+.rgcFormatCharToLookupIndex:
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	db		"aIAduxsSctz-+%"
+%else
+	db		"IAuxscz-"		; Required by XTIDE Universal BIOS
+%endif
+.rgcFormatCharToLookupIndexEnd:
+ALIGN WORD_ALIGN
+.rgfnFormatSpecifierParser:
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	dw		a_FormatAttributeForNextCharacter
+%endif
+	dw		I_FormatDashForZero
+	dw		A_FormatAttributeForRemainingString
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	dw		d_FormatSignedDecimalWord
+%endif
+	dw		u_FormatUnsignedDecimalWord
+	dw		x_FormatHexadecimalWord
+	dw		s_FormatStringFromSegmentCS
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	dw		S_FormatStringFromFarPointer
+%endif
+	dw		c_FormatCharacter
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	dw		t_FormatRepeatCharacter
+%endif
+	dw		z_FormatStringFromSegmentZero
+	dw		PrepareToPrependParameterWithSpaces
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	dw		PrepareToAppendSpacesAfterParameter
+	dw		percent_FormatPercent
+%endif
+
+
+;--------------------------------------------------------------------
+; PrependOrAppendSpaces
+;	Parameters:
+;		CX:		Minimum length for format specifier in characters
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PrependOrAppendSpaces:
+	mov		ax, di
+	sub		ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
+	test	cx, cx
+	js		SHORT .PrependWithSpaces
+	; Fall to .AppendSpaces
+
+;--------------------------------------------------------------------
+; .AppendSpaces
+;	Parameters:
+;		AX:		Number of format parameter BYTEs printed
+;		CX:		Minimum length for format specifier in characters
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX, DX
+;--------------------------------------------------------------------
+.AppendSpaces:
+	call	DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
+	sub		cx, ax
+	jle		SHORT .NothingToAppendOrPrepend
+	mov		al, ' '
+	jmp		DisplayPrint_RepeatCharacterFromALwithCountInCX
+
+;--------------------------------------------------------------------
+; .PrependWithSpaces
+;	Parameters:
+;		AX:		Number of format parameter BYTEs printed
+;		CX:		Negative minimum length for format specifier in characters
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.PrependWithSpaces:
+	xchg	ax, cx
+	neg		ax
+	call	DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
+	sub		ax, cx				; AX = BYTEs to prepend, CX = BYTEs to move
+	jle		SHORT .NothingToAppendOrPrepend
+
+	std
+	push	si
+
+	lea		si, [di-1]			; SI = Offset to last byte formatted
+	add		di, ax				; DI = Cursor location after preceeding completed
+	push	di
+	dec		di					; DI = Offset where to move last byte formatted
+	xchg	bx, ax				; BX = BYTEs to prepend
+	call	.ReverseCopyCXbytesFromESSItoESDI
+	xchg	ax, bx
+	call	.ReversePrintAXspacesStartingFromESDI
+
+	pop		di
+	pop		si
+	cld							; Restore DF
+.NothingToAppendOrPrepend:
+	ret
+
+;--------------------------------------------------------------------
+; .ReverseCopyCXbytesFromESSItoESDI
+;	Parameters:
+;		CX:		Number of bytes to copy
+;		DS:		BDA segment (zero)
+;		ES:SI:	Ptr to old location
+;		ES:DI:	Ptr to new location
+;	Returns:
+;		DI:		Updated to before last character copied
+;	Corrupts registers:
+;		AX, CX, DX, SI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ReverseCopyCXbytesFromESSItoESDI:
+	test	BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
+	jz		SHORT .CopyWithoutDisplayProcessing
+
+	WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
+	dec		di					; Point to preceeding character instead of attribute
+	ret
+ALIGN JUMP_ALIGN
+.CopyWithoutDisplayProcessing:
+	eSEG_STR rep, es, movsb
+	ret
+
+;--------------------------------------------------------------------
+; .ReversePrintAXspacesStartingFromESDI
+;	Parameters:
+;		AX:		Number of spaces to print
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to destination in video RAM
+;	Returns:
+;		DI:		Updated
+;	Corrupts registers:
+;		AX, CX, DX
+ALIGN JUMP_ALIGN
+.ReversePrintAXspacesStartingFromESDI:
+	call	DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
+	xchg	cx, ax				; CX = Spaces to prepend
+	mov		al, ' '
+	jmp		DisplayPrint_RepeatCharacterFromALwithCountInCX
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Formatting functions
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		SS:BP:	Pointer to next format parameter (-=2 updates to next parameter)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		SS:BP:	Points to last WORD parameter used
+;	Corrupts registers:
+;		AX, BX, DX
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+a_FormatAttributeForNextCharacter:
+	mov		bl, [bp]
+	xchg	bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
+	push	bx
+	push	cx
+	push	di
+	call	DisplayFormat_ParseCharacters	; Recursive call
+	pop		WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
+	pop		cx
+	pop		bx
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
+	ret
+%endif
+
+ALIGN JUMP_ALIGN
+A_FormatAttributeForRemainingString:
+	mov		al, [bp]
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
+	ret
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+d_FormatSignedDecimalWord:
+	mov		ax, [bp]
+	mov		bx, 10
+	jmp		DisplayPrint_SignedWordFromAXWithBaseInBX
+%endif
+
+ALIGN JUMP_ALIGN
+u_FormatUnsignedDecimalWord:
+	mov		ax, [bp]
+	mov		bx, 10
+	jmp		DisplayPrint_WordFromAXWithBaseInBX
+
+ALIGN JUMP_ALIGN
+x_FormatHexadecimalWord:
+	mov		ax, [bp]
+	mov		bx, 16
+	call	DisplayPrint_WordFromAXWithBaseInBX
+	mov		al, 'h'
+	jmp		DisplayPrint_CharacterFromAL
+
+ALIGN JUMP_ALIGN
+I_FormatDashForZero:
+	mov		ax, [bp]
+	test	ax,ax
+	jnz		u_FormatUnsignedDecimalWord
+	mov		[bp], word g_szDashForZero
+;;; fall-through
+
+ALIGN JUMP_ALIGN
+s_FormatStringFromSegmentCS:
+	push	si
+	push	cx
+	mov		si, [bp]
+
+	cmp		si, byte 07fh		;  well within the boundaries of ROMVARS_size
+	jb		.notFormatted
+
+	dec		bp
+	dec		bp
+	call	DisplayFormat_ParseCharacters
+	inc		bp					; will be decremented after the call is done
+	inc		bp
+	jmp		.done
+
+.notFormatted:
+	call	DisplayPrint_NullTerminatedStringFromCSSI
+
+.done:
+	pop		cx
+	pop		si
+	ret
+
+ALIGN JUMP_ALIGN
+z_FormatStringFromSegmentZero:
+	xchg	si, [bp]
+	xor		bx, bx
+	call	DisplayPrint_NullTerminatedStringFromBXSI
+	mov		si, [bp]
+	ret
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+S_FormatStringFromFarPointer:
+	mov		bx, [bp-2]
+	xchg	si, [bp]
+	call	DisplayPrint_NullTerminatedStringFromBXSI
+	mov		si, [bp]
+	dec		bp
+	dec		bp
+	ret
+%endif
+
+ALIGN JUMP_ALIGN
+c_FormatCharacter:
+	mov		al, [bp]
+	jmp		DisplayPrint_CharacterFromAL
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+t_FormatRepeatCharacter:
+	push	cx
+	mov		cx, [bp-2]
+	mov		al, [bp]
+	call	DisplayPrint_RepeatCharacterFromALwithCountInCX
+	pop		cx
+	dec		bp
+	dec		bp
+	ret
+
+ALIGN JUMP_ALIGN
+percent_FormatPercent:
+	mov		al, '%'
+	jmp		DisplayPrint_CharacterFromAL
+%endif
+
+ALIGN JUMP_ALIGN
+PrepareToPrependParameterWithSpaces:
+	neg		cx
+	; Fall to PrepareToAppendSpacesAfterParameter
+
+ALIGN JUMP_ALIGN
+PrepareToAppendSpacesAfterParameter:
+	add		sp, BYTE 2				; Remove return offset
+	jmp		ParseFormatSpecifier
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayFormatCompressed.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayFormatCompressed.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayFormatCompressed.asm	(revision 348)
@@ -0,0 +1,228 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for displaying formatted strings.
+;					** Compressed Strings edition **
+;					This is a plug replacement for DisplayFormat.asm,
+;					working instead with precompiled and slightly compressed strings.
+;
+; Strings are compressed in a simple manner:
+;	1. The two most common characters, space and null, are removed
+;	2. Format specifiers are reduced to a single byte, including length information
+;
+; Format of bytes in the string are:
+;     01 xxxxxx     Character in x plus StringsCompressed_NormalBase
+;     10 xxxxxx     Character in x plus StringsCompressed_NormalBase, followed by a null (last character)
+;     11 xxxxxx     Character in x plus StringsCompressed_NormalBase, followed by a space
+;     00 1 yyyyy    Character/Format in lookup table StringsCopmressed_TranslatesAndFormats
+;     00 0 yyyyy    Character/Format in lookup table StringsCompressed_TranslatesAndFormats, followed by a null
+;
+; StringsCompressed_NormalBase is defined by the compressor, but is usually around 0x40,
+; which gives a range of 0x40 to 0x7f, or roughly the upper and lower case letters.
+;
+; StringsCompressed_TranslatesAndFormats is a lookup table with the first few bytes being translation
+; characters, and the last few bytes being format jump offsets from DisplayFormatCompressed_BaseFormatOffset.
+; The dividing line is defined by StringsCompressed_FormatsBegin
+;
+; The assignments of the first two bits above is not by accident.  The translates/format branch is 00
+; which is easy to test for.  The '01' for "normal" (no null or space) and '001' for translates/format "normal"
+; match, allowing the translates/format codes to be shifted left by 1 and then tested with the same instructions.
+;
+; It is always possible to say that a null character follows the current character - thus there is
+; no way (nor need) to specify a zero character.
+;
+; Note that this code is optimized for size, not speed.  Since this code is used only during initialization
+; and only for the user interface, small performance hits should not be noticed.  It will seem odd to do so
+; much "preload", just in case a branch is taken, but that is cheaper (in size) than adding additional branches.
+;
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Format Handlers
+;
+; Names of format handlers are DisplayFormatCompressed_Format_* where * is
+; replaced with the format code after the '%' in the original string,
+; with '-' replaced with '_'.
+;
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		AX:     Parameter to Format
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI
+;--------------------------------------------------------------------
+
+;
+; The following routines do not need any pre or post processing and can be jumped to directly.
+; Note that they need to be within 256 bytes of DisplayFormatCompressed_BaseFormatOffset
+;
+%define DisplayFormatCompressed_Format_c DisplayPrint_CharacterFromAL
+%define DisplayFormatCompressed_Format_nl DisplayPrint_Newline_FormatAdjustBP
+%define DisplayFormatCompressed_Format_s DisplayFormat_ParseCharacters_FromAX
+
+DisplayFormatCompressed_Format_A:
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
+DisplayFormatCompressed_ret:			; jump target for other routines who need a "ret"
+	ret
+
+DisplayFormatCompressed_Format_z:
+	xor		bx, bx
+	xchg	si, ax
+	jmp		short DisplayPrint_NullTerminatedStringFromBXSI
+
+DisplayFormatCompressed_Format_x:
+DisplayFormatCompressed_Format_5_x:
+	mov		si,16						; hex output, change base to 16
+	mov		bx,(04<<8) + 'h'	        ; 4 bytes, with postfix character 'h' to emit
+										; (note that the count includes the 'h')
+	jmp		DisplayFormatCompressed_Format_u
+
+DisplayFormatCompressed_Format_2_I:
+	mov		si,g_szDashForZero			; preload dash string in case we jump
+	test	ax,ax						; if parameter equals zero, emit dash string instead
+	jz		DisplayFormat_ParseCharacters
+	; fall through
+
+DisplayFormatCompressed_Format_2_u:
+	mov		bh,2						; only two characters (instead of the default 5)
+	; fall through
+
+DisplayFormatCompressed_Format_u:
+DisplayFormatCompressed_Format_5_u:
+	push	bx							; push postfix character - either a zero (default) or a 'h'
+	mov		bl,bh						; preserve character count for .PrintLoop
+
+.DivLoop:
+	xor		dx, dx						; Zero DX for division
+	div		si							; DX:AX / 10 => AX=quot, DX=rem
+ 	push	dx							; Push digit
+
+	dec		bh
+	jnz		.DivLoop
+
+.PrintLoop:
+	pop		ax							; Pop digit, postfix character on last iteration
+
+	dec		bl							; on second to last iteration, emit digit whether it is zero or not
+	jz		.PrintDigit
+
+	js		short DisplayPrint_CharacterFromAL	; on last iteration, emit postfix character
+												; if it is zero, DisplayPrint_CharacterFromAL will not emit
+
+	or		bh, al						; skip leading zeros, bh keeps track if we have emitted anything non-zero
+	jnz		.PrintDigit					; note that bh starts at zero, from the loop above
+
+	test	ch,2						; are we padding with leading spaces?
+	jnz		.PrintLoop					; test the even/odd of the format byte in the string
+
+	mov		al, 89h						; emit space
+
+.PrintDigit:
+	add		al, 90h						; Convert binary digit in AL to ASCII hex digit (0 - 9 or A - F)
+	daa
+	adc		al, 40h
+	daa
+
+	call	DisplayPrint_CharacterFromAL
+
+	jmp		.PrintLoop
+
+
+;--------------------------------------------------------------------
+; DisplayFormat_ParseCharacters
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		SS:BP:	Pointer to first format parameter (-=2 updates to next parameter)
+;		CS:SI:	Pointer to string to format
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		CS:SI:	Ptr to end of format string (ptr to one past NULL)
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, BX, CX, DX, BP
+;--------------------------------------------------------------------
+
+DisplayFormatCompressed_BaseFormatOffset:
+
+DisplayFormat_ParseCharacters_FromAX:
+	mov		si,ax
+	; fall through to DisplayFormat_ParseCharacters
+
+ALIGN JUMP_ALIGN
+DisplayFormat_ParseCharacters:
+;
+; This routine is used to output all strings from the ROM.  The strings in ROMVARS are not compressed,
+; and must be handled differently.
+;
+	cmp		si,byte 07fh		; well within the boundaries of ROMVARS_size
+	mov		bx,cs				; preload bx with cs in case we take the following jump
+	jb		short DisplayPrint_NullTerminatedStringFromBXSI
+
+.decode:
+	cs lodsb					; load next byte of the string
+
+	mov		ch,al				; save a copy for later processing of high order bits
+
+	test	al,0c0h				; check for translation/format character
+	jz		DisplayFormatCompressed_TranslatesAndFormats
+
+	and		al,03fh								; "Normal" character, mask off high order bits
+	add		al,StringsCompressed_NormalBase		; and add character offset (usually around 0x40)
+
+.output:
+	call 	DisplayPrint_CharacterFromAL
+
+.process_after_output:
+	shl		ch,1								; check high order bits for end of string or space
+	jns		short DisplayFormatCompressed_ret
+	jnc		.decode
+	mov		al,' '
+	call	DisplayPrint_CharacterFromAL
+	jmp		.decode
+
+
+ALIGN JUMP_ALIGN
+DisplayFormatCompressed_TranslatesAndFormats:
+;
+; This routine is here (above DisplayFormat_ParseCharacters) to reduce the amount of code between
+; DisplayFormatCompressed_BaseFormatOffset and jump targets (must fit in 256 bytes)
+;
+	shl		ch,1				; setup ch for later testing of null in .process_after_output
+	and		ax,0001fh			; also clears AH for addition with BX and DX below
+
+	mov		bx,StringsCompressed_TranslatesAndFormats	; calculate offset of translation/formats offset byte
+	add		bx,ax
+
+	cmp		al,StringsCompressed_FormatsBegin			; determine if this is a translation or a format
+
+	mov		al,[cs:bx]									; fetch translation/formats byte
+
+	jb		DisplayFormat_ParseCharacters.output		; check if this a translation or a format
+														; if it is translation, output and postprocess for eos
+														; note that the flags for this conditional jump were
+														; set with the cmp al,StringsCompressed_FormatsBegin
+
+	mov		dx,DisplayFormatCompressed_BaseFormatOffset   ; calculate address to jump to for format handler
+	sub		dx,ax
+
+	mov		ax,[bp]				; preload ax with parameter
+	dec		bp					; if no parameter is needed (format 'nl' for example),
+	dec		bp					; the format handler can reincrement bp
+
+	mov		bx,0500h			; preload bh with 5 decimal places for numeric output
+								; bl is zero, indicating not to output a 'h' (default base 10)
+
+	push	si					; preserve si and cx, in the case of outputing a string
+	push	cx
+
+	mov		si,10				; preload si with 10 for numeric output (default base 10)
+
+	call	dx					; call the format routine
+
+	pop		cx					; restore cx and si
+	pop		si
+
+	jmp		DisplayFormat_ParseCharacters.process_after_output	; continue postprocessing, check for end of string
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayPage.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayPage.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayPage.asm	(revision 348)
@@ -0,0 +1,64 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for managing display page.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DisplayPage_SetFromAL
+;	Parameters:
+;		AL:		New display page
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayPage_SetFromAL:
+	xor		ah, ah
+	mul		WORD [VIDEO_BDA.wBytesPerPage]		; AX = Offset to page
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], ax
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayPage_GetColumnsToALandRowsToAH
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		AL:		Number of columns in selected text mode
+;		AH:		Number of rows in selected text mode
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPage_GetColumnsToALandRowsToAH:
+	mov		al, [VIDEO_BDA.wColumns]		; 40 or 80
+	mov		ah, 25							; Always 25 rows on standard text modes
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayPage_SynchronizeToHardware
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPage_SynchronizeToHardware:
+	xor		dx, dx
+	mov		ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
+	div		WORD [VIDEO_BDA.wBytesPerPage]	; AX = Page
+
+	cmp		al, [VIDEO_BDA.bActivePage]
+	je		SHORT .Return					; Same page, no need to synchronize
+	mov		ah, SELECT_ACTIVE_DISPLAY_PAGE
+	int		BIOS_VIDEO_INTERRUPT_10h
+.Return:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayPrint.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayPrint.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Display/DisplayPrint.asm	(revision 348)
@@ -0,0 +1,421 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for display output.
+
+; Section containing code
+SECTION .text
+
+
+;--------------------------------------------------------------------
+; Supports following formatting types:
+;	%a		Specifies attribute for next character
+;	%A		Specifies attribute for remaining string (or until next %A)
+;	%d		Prints signed 16-bit decimal integer
+;	%u		Prints unsigned 16-bit decimal integer
+;	%x		Prints 16-bit hexadecimal integer
+;	%s		Prints string (from CS segment)
+;	%S		Prints string (far pointer)
+;	%c		Prints character
+;	%t		Prints character number of times (character needs to be pushed first, then repeat times)
+;	%%		Prints '%' character (no parameter pushed)
+;
+;	Any placeholder can be set to minimum length by specifying
+;	minimum number of characters. For example %8d would append spaces
+;	after integer so that at least 8 characters would be printed.
+;
+;	When placing '-' after number, then spaces will be used for prepending.
+;	For example %8-d would prepend integer with spaces so that at least
+;	8 characters would be printed.
+;
+; DisplayPrint_FormattedNullTerminatedStringFromCSSI
+;	Parameters:
+;		BP:		SP before pushing parameters
+;		DS:		BDA segment (zero)
+;		CS:SI:	Pointer to string to format
+;		ES:DI:	Ptr to cursor location in video RAM
+;		Stack:	Parameters for formatting placeholders.
+;				Parameter for first placeholder must be pushed first.
+;				Low word must pushed first for placeholders requiring
+;				32-bit parameters (two words).
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_FormattedNullTerminatedStringFromCSSI:
+	push	bp
+	push	si
+	push	cx
+	push	bx
+	push	WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
+
+	dec		bp					; Point BP to...
+	dec		bp					; ...first stack parameter
+	call	DisplayFormat_ParseCharacters
+
+	; Pop original character attribute
+	pop		ax
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
+
+	pop		bx
+	pop		cx
+	pop		si
+	pop		bp
+
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_SignedWordFromAXWithBaseInBX
+;	Parameters:
+;		AX:		Word to display
+;		BX:		Integer base (binary=2, octal=8, decimal=10, hexadecimal=16)
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayPrint_SignedWordFromAXWithBaseInBX:
+	test	ax, ax
+	jns		SHORT DisplayPrint_WordFromAXWithBaseInBX
+
+	push	ax
+	mov		al, '-'
+	call	DisplayPrint_CharacterFromAL
+	pop		ax
+	neg		ax
+	; Fall to DisplayPrint_WordFromAXWithBaseInBX
+%endif
+
+
+%ifndef MODULE_STRINGS_COMPRESSED
+;--------------------------------------------------------------------
+; DisplayPrint_WordFromAXWithBaseInBX
+;	Parameters:
+;		AX:		Word to display
+;		BX:		Integer base (binary=2, octal=8, decimal=10, hexadecimal=16)
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_WordFromAXWithBaseInBX:
+	push	cx
+	push	bx
+
+	xor		cx, cx
+ALIGN JUMP_ALIGN
+.DivideLoop:
+	xor		dx, dx				; DX:AX now holds the integer
+	div		bx					; Divide DX:AX by base
+	push	dx					; Push remainder
+	inc		cx					; Increment character count
+	test	ax, ax				; All divided?
+	jnz		SHORT .DivideLoop	;  If not, loop
+
+PrintAllPushedDigits:
+	mov		bx, g_rgcDigitToCharacter
+ALIGN JUMP_ALIGN
+.PrintNextDigit:
+	pop		ax					; Pop digit
+	cs xlatb
+	call	DisplayPrint_CharacterFromAL
+	loop	.PrintNextDigit
+
+	pop		bx
+	pop		cx
+	ret
+
+g_rgcDigitToCharacter:	db	"0123456789ABCDEF"
+
+;--------------------------------------------------------------------
+; DisplayPrint_QWordFromSSBPwithBaseInBX
+;	Parameters:
+;		SS:BP:	QWord to display
+;		BX:		Integer base (binary=2, octal=8, decimal=10, hexadecimal=16)
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX, [SS:BP]
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDECFG	; Not used in XTIDECFG
+ALIGN JUMP_ALIGN
+DisplayPrint_QWordFromSSBPwithBaseInBX:
+	push	cx
+	push	bx
+
+	mov		cx, bx				; CX = Integer base
+	xor		bx, bx				; BX = Character count
+ALIGN JUMP_ALIGN
+.DivideLoop:
+	call	Math_DivQWatSSBPbyCX; Divide by base
+	push	dx					; Push remainder
+	inc		bx					; Increment character count
+	cmp		WORD [bp], BYTE 0	; All divided?
+	jne		SHORT .DivideLoop	;  If not, loop
+	mov		cx, bx				; Character count to CX
+	jmp		SHORT PrintAllPushedDigits
+%endif	; EXCLUDE_FROM_XTIDECFG
+
+%endif	; MODULE_STRINGS_COMPRESSED
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_CharacterBufferFromBXSIwithLengthInCX
+;	Parameters:
+;		CX:		Buffer length (characters)
+;		BX:SI:	Ptr to NULL terminated string
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayPrint_CharacterBufferFromBXSIwithLengthInCX:
+	jcxz	.NothingToPrintSinceZeroLength
+	push	si
+	push	cx
+
+ALIGN JUMP_ALIGN
+.PrintNextCharacter:
+	mov		ds, bx
+	lodsb
+	LOAD_BDA_SEGMENT_TO	ds, dx
+	call	DisplayPrint_CharacterFromAL
+	loop	.PrintNextCharacter
+
+	pop		cx
+	pop		si
+.NothingToPrintSinceZeroLength:
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_ClearScreenWithCharInALandAttributeInAH
+;	Parameters:
+;		AL:		Character to clear with
+;		AH:		Attribute to clear with
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_ClearScreenWithCharInALandAttributeInAH:
+	push	di
+	push	cx
+
+	xchg	cx, ax
+	xor		ax, ax
+	call	DisplayCursor_SetCoordinatesFromAX		; Updates DI
+	call	DisplayPage_GetColumnsToALandRowsToAH
+	mul		ah		; AX = AL*AH = Characters on screen
+	xchg	cx, ax	; AX = Char+Attr, CX = WORDs to store
+	rep stosw
+
+	pop		cx
+	pop		di
+	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_ClearAreaWithHeightInAHandWidthInAL
+;	Parameters:
+;		AH:		Area height
+;		AL:		Area width
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+DisplayPrint_ClearAreaWithHeightInAHandWidthInAL:
+	push	si
+	push	cx
+	push	bx
+
+	xchg	bx, ax							; Area size to BX
+	call	DisplayCursor_GetSoftwareCoordinatesToAX
+	xchg	si, ax							; Software (Y,X) coordinates now in SI
+	xor		cx, cx
+
+ALIGN JUMP_ALIGN
+.ClearRowLoop:
+	mov		cl, bl							; Area width now in CX
+	mov		al, SCREEN_BACKGROUND_CHARACTER
+	call	DisplayPrint_RepeatCharacterFromALwithCountInCX
+
+	xchg	ax, si							; Coordinates to AX
+	inc		ah								; Increment row
+	mov		si, ax
+	call	DisplayCursor_SetCoordinatesFromAX
+	dec		bh								; Decrement rows left
+	jnz		SHORT .ClearRowLoop
+
+	pop		bx
+	pop		cx
+	pop		si
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_RepeatCharacterFromALwithCountInCX
+;	Parameters:
+;		AL:		Character to display
+;		CX:		Repeat count
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_RepeatCharacterFromALwithCountInCX:
+	jcxz	.NothingToRepeat
+	push	cx
+
+ALIGN JUMP_ALIGN
+.RepeatCharacter:
+	push	ax
+	call	DisplayPrint_CharacterFromAL
+	pop		ax
+	loop	.RepeatCharacter
+
+	pop		cx
+.NothingToRepeat:
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_NullTerminatedStringFromCSSI
+;	Parameters:
+;		CS:SI:	Ptr to NULL terminated string
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%ifndef MODULE_STRINGS_COMPRESSED
+;;;
+;;; Take care when using this routine with compressed strings (which is why it is disabled).
+;;; All strings in CSSI should go through the DisplayFormatCompressed code to be decoded.
+;;;
+ALIGN JUMP_ALIGN
+DisplayPrint_NullTerminatedStringFromCSSI:
+	push	bx
+	mov		bx, cs
+	call	DisplayPrint_NullTerminatedStringFromBXSI
+	pop		bx
+	ret
+%endif
+
+
+;;;
+;;; Note that the following routines need to be at the bottom of this file
+;;; to accomodate short jumps from the next file (DisplayFormat/DisplayFormatCompressed)
+;;;
+
+;--------------------------------------------------------------------
+; DisplayPrint_Newline
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%ifdef MODULE_STRINGS_COMPRESSED
+ALIGN JUMP_ALIGN
+DisplayPrint_Newline_FormatAdjustBP:
+	inc		bp					; we didn't need a parameter after all, readjust BP
+	inc		bp
+	; fall through to DisplayPrint_Newline
+%endif
+
+ALIGN JUMP_ALIGN
+DisplayPrint_Newline:
+	mov		al, LF
+	call	DisplayPrint_CharacterFromAL
+	mov		al, CR
+	; Fall to DisplayPrint_CharacterFromAL
+
+;--------------------------------------------------------------------
+; DisplayPrint_CharacterFromAL
+;	Parameters:
+;		AL:		Character to display
+;               Zero value is ignored (no characer is printed)
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_CharacterFromAL:
+	test	al,al
+	jz		DisplayPrint_Ret
+
+	mov		ah, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
+	jmp		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fnCharOut]
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_NullTerminatedStringFromBXSI
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		BX:SI:	Ptr to NULL terminated string
+;		ES:DI:	Ptr to cursor location in video RAM
+;	Returns:
+;		DI:		Updated offset to video RAM
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_NullTerminatedStringFromBXSI:
+	push	si
+	push	cx
+
+	xor		cx, cx
+ALIGN JUMP_ALIGN
+.PrintNextCharacter:
+	mov		ds, bx				; String segment to DS
+	lodsb
+	mov		ds, cx				; BDA segment to DS
+	test	al, al				; NULL?
+	jz		SHORT .EndOfString
+	call	DisplayPrint_CharacterFromAL
+	jmp		SHORT .PrintNextCharacter
+
+ALIGN JUMP_ALIGN
+.EndOfString:
+	pop		cx
+	pop		si
+
+DisplayPrint_Ret:				; random ret to jump to
+	ret
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/File/Directory.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/File/Directory.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/File/Directory.asm	(revision 348)
@@ -0,0 +1,143 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for accessing directories.
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Directory_GetDiskTransferAreaAddressToDSSI
+;	Parameters:
+;		Nothing
+;	Returns:
+;		DS:SI:	Ptr to DTA
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Directory_GetDiskTransferAreaAddressToDSSI:
+	push	es
+	push	bx
+
+	mov		ah, GET_DISK_TRANSFER_AREA_ADDRESS
+	int		DOS_INTERRUPT_21h
+	push	es
+	pop		ds
+	mov		si, bx
+
+	pop		bx
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; Directory_ChangeToPathFromDSSI
+;	Parameters:
+;		DS:SI:	Ptr to NULL terminated path (max 64 bytes)
+;	Returns:
+;		AX:		Error code
+;		CF:		Cleared if success
+;				Set if error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Directory_ChangeToPathFromDSSI:
+	xchg	dx, si		; Path now in DS:DX
+	mov		ah, SET_CURRENT_DIRECTORY
+	int		DOS_INTERRUPT_21h
+	xchg	si, dx
+	ret
+
+
+;--------------------------------------------------------------------
+; Directory_WriteCurrentPathToDSSI
+;	Parameters:
+;		DS:SI:	Ptr to destination buffer (64 bytes)
+;	Returns:
+;		AX:		Error code
+;		CF:		Cleared if success
+;				Set if error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Directory_WriteCurrentPathToDSSI:
+	push	dx
+
+	mov		ah, GET_CURRENT_DIRECTORY	; GET_CURRENT_DIRECTORY = 47h
+	cwd									; Default drive (00h)
+	int		DOS_INTERRUPT_21h
+
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; Directory_GetMatchCountToAXforSearchStringInDSSIwithAttributesInCX
+;	Parameters:
+;		CX:		File attributes
+;		DS:SI:	NULL terminated search string (may include path and wildcards)
+;	Returns:
+;		AX:		Number of matching files found
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Directory_GetMatchCountToAXforSearchStringInDSSIwithAttributesInCX:
+	push	dx
+	xor		dx, dx				; Zero counter
+	call	Directory_UpdateDTAForFirstMatchForDSSIwithAttributesInCX
+	jc		SHORT .NoMoreFilesFound
+ALIGN JUMP_ALIGN
+.FindNextFile:
+	inc		dx					; Increment match count
+	call	Directory_UpdateDTAForNextMatchUsingPreviousParameters
+	jnc		SHORT .FindNextFile
+ALIGN JUMP_ALIGN
+.NoMoreFilesFound:
+	xchg	ax, dx				; Match count to AX
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; Directory_UpdateDTAForFirstMatchForDSSIwithAttributesInCX
+;	Parameters:
+;		CX:		File attributes
+;		DS:SI:	NULL terminated search string (may include path and wildcards)
+;	Returns:
+;		AX:		Error code
+;		CF:		Cleared if success
+;				Set if error
+;		Disk Transfer Area (DTA) will be updated
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Directory_UpdateDTAForFirstMatchForDSSIwithAttributesInCX:
+	xchg	dx, si							; Search string now in DS:DX
+	mov		ax, FIND_FIRST_MATCHING_FILE<<8	; Zero AL (special flag for APPEND)
+	int		DOS_INTERRUPT_21h
+	xchg	si, dx
+	ret
+
+
+;--------------------------------------------------------------------
+; Directory_UpdateDTAForNextMatchUsingPreviousParameters
+;	Parameters:
+;		Nothing (Parameters from previous call to
+;				Directory_UpdateDTAForFirstMatchForDSSIwithAttributesInCX are used)
+;	Returns:
+;		AX:		Error code
+;		CF:		Cleared if success
+;				Set if error
+;		Disk Transfer Area (DTA) will be updated
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Directory_UpdateDTAForNextMatchUsingPreviousParameters:
+	mov		ah, FIND_NEXT_MATCHING_FILE
+	int		DOS_INTERRUPT_21h
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/File/DosCritical.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/File/DosCritical.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/File/DosCritical.asm	(revision 348)
@@ -0,0 +1,79 @@
+; File name		:	DosCritical.asm
+; Project name	:	Assembly Library
+; Created date	:	1.9.2010
+; Last update	:	2.9.2010
+; Author		:	Tomi Tilli
+; Description	:	DOS Critical Error Handler (24h) replacements.
+
+; DOS Critical Error Handler return values
+struc CRITICAL_ERROR_ACTION
+	.ignoreErrorAndContinueProcessingRequest	resb	1
+	.retryOperation								resb	1
+	.terminateProgramAsThoughInt21hAH4ChCalled	resb	1
+	.failSystemCallInProgress					resb	1
+endstruc
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DosCritical_InstallNewHandlerFromCSDX
+;	Parameters:
+;		CS:DX:	New Critical Error Handler
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DosCritical_InstallNewHandlerFromCSDX:
+	push	ds
+
+	push	cs
+	pop		ds
+	mov		ax, (SET_INTERRUPT_VECTOR<<8) | DOS_CRITICAL_ERROR_HANDLER_24h
+	int		DOS_INTERRUPT_21h
+
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; DosCritical_RestoreDosHandler
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DosCritical_RestoreDosHandler:
+	push	ds
+	push	dx
+	push	ax
+
+	lds		dx, [cs:PSP.fpInt24hCriticalError]
+	mov		ax, (SET_INTERRUPT_VECTOR<<8) | DOS_CRITICAL_ERROR_HANDLER_24h
+	int		DOS_INTERRUPT_21h
+
+	pop		ax
+	pop		dx
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; DosCritical_HandlerToIgnoreAllErrors
+;	Parameters:
+;		Nothing
+;	Returns:
+;		AL:		CRITICAL_ERROR_ACTION
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------	
+ALIGN JUMP_ALIGN
+DosCritical_HandlerToIgnoreAllErrors:
+	mov		al, CRITICAL_ERROR_ACTION.ignoreErrorAndContinueProcessingRequest
+	iret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/File/Drive.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/File/Drive.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/File/Drive.asm	(revision 348)
@@ -0,0 +1,181 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for accessing drives.
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Drive_GetNumberOfAvailableDrivesToAX
+;	Parameters:
+;		Nothing
+;	Returns:
+;		AX:		Number of available drives
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Drive_GetNumberOfAvailableDrivesToAX:
+	push	dx
+	push	cx
+
+	call	Drive_GetFlagsForAvailableDrivesToDXAX
+	call	Bit_GetSetCountToCXfromDXAX
+	xchg	ax, cx
+
+	pop		cx
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; Drive_GetFlagsForAvailableDrivesToDXAX
+;	Parameters:
+;		Nothing
+;	Returns:
+;		DX:AX:	Flags containing valid drives (bit 0 = drive A, bit 1 = drive B ...)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Drive_GetFlagsForAvailableDrivesToDXAX:
+	push	cx
+	push	bx
+	mov		dx, DosCritical_HandlerToIgnoreAllErrors
+	call	DosCritical_InstallNewHandlerFromCSDX
+
+	call	.GetNumberOfPotentiallyValidDriveLettersToCX
+	xor		bx, bx
+	xor		ax, ax				; Temporary use BX:AX for flags
+	cwd							; Start from drive 0
+	call	.CheckDriveValidityUntilCXisZero
+	mov		dx, bx				; Flags now in DX:AX
+
+	call	DosCritical_RestoreDosHandler
+	pop		bx
+	pop		cx
+	ret
+
+;--------------------------------------------------------------------
+; .GetNumberOfPotentiallyValidDriveLettersToCX
+;	Parameters:
+;		Nothing
+;	Returns:
+;		CX:		Number of potentially valid drive letters available
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.GetNumberOfPotentiallyValidDriveLettersToCX:
+	call	Drive_GetDefaultToAL
+	xchg	dx, ax			; Default drive to DL
+	call	Drive_SetDefaultFromDL
+	eMOVZX	cx, al			; Number of potentially valid drive letters available
+	cmp		cl, 32
+	jb		SHORT .Return
+	mov		cl, 32
+ALIGN JUMP_ALIGN, ret
+.Return:
+	ret
+
+;--------------------------------------------------------------------
+; .CheckDriveValidityUntilCXisZero
+;	Parameters:
+;		CX:		Number of potentially valid drive letters left
+;		DL:		Drive number (00h=A:, 01h=B: ...)
+;		BX:AX:	Flags for drive numbers
+;	Returns:
+;		BX:AX:	Flags for valid drive numbers
+;	Corrupts registers:
+;		CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.CheckDriveValidityUntilCXisZero:
+	call	.IsValidDriveNumberInDL
+	jnz		SHORT .PrepareToCheckNextDrive
+	call	.SetFlagToBXAXfromDriveInDL
+ALIGN JUMP_ALIGN
+.PrepareToCheckNextDrive:
+	inc		dx
+	loop	.CheckDriveValidityUntilCXisZero
+	ret
+
+;--------------------------------------------------------------------
+; .IsValidDriveNumberInDL
+;	Parameters:
+;		DL:		Drive number (00h=A:, 01h=B: ...)
+;	Returns:
+;		ZF:		Set if drive number is valid
+;				Cleared if drive number is invalid
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.IsValidDriveNumberInDL:
+	push	ds
+	push	bx
+	push	ax
+
+	inc		dx			; Default drive is 00h and first drive is 01h
+	mov		ah, GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE
+	int		DOS_INTERRUPT_21h
+	dec		dx
+	test	al, al
+
+	pop		ax
+	pop		bx
+	pop		ds
+	ret
+
+;--------------------------------------------------------------------
+; .SetFlagToBXAXfromDriveInDL
+;	Parameters:
+;		DL:		Drive number (0...31)
+;		BX:AX:	Flags containing drive numbers
+;	Returns:
+;		BX:AX:	Flags with wanted drive bit set
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.SetFlagToBXAXfromDriveInDL:
+	push	cx
+
+	mov		cl, dl
+	xchg	dx, bx
+	call	Bit_SetToDXAXfromIndexInCL
+	xchg	bx, dx
+
+	pop		cx
+	ret
+
+
+;--------------------------------------------------------------------
+; Drive_GetDefaultToAL
+;	Parameters:
+;		Nothing
+;	Returns:
+;		AL:		Current default drive (00h=A:, 01h=B: ...)
+;	Corrupts registers:
+;		AH
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Drive_GetDefaultToAL:
+	mov		ah, GET_CURRENT_DEFAULT_DRIVE
+	SKIP2B	f	; cmp ax, <next instruction>
+	; Fall to Drive_SetDefaultFromDL
+
+
+;--------------------------------------------------------------------
+; Drive_SetDefaultFromDL
+;	Parameters:
+;		DL:		New default drive (00h=A:, 01h=B: ...)
+;	Returns:
+;		AL:		Number of potentially valid drive letters available
+;	Corrupts registers:
+;		AH
+;--------------------------------------------------------------------
+Drive_SetDefaultFromDL:
+	mov		ah, SELECT_DEFAULT_DRIVE
+	int		DOS_INTERRUPT_21h
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/File/FileIO.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/File/FileIO.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/File/FileIO.asm	(revision 348)
@@ -0,0 +1,267 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for file access.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; FileIO_OpenWithPathInDSSIandFileAccessInAL
+;	Parameters:
+;		AL:		FILE_ACCESS.(mode)
+;		DS:SI:	Ptr to NULL terminated path or file name
+;	Returns:
+;		AX:		DOS error code if CF set
+;		BX:		File handle if CF cleared
+;		CF:		Clear if file opened successfully
+;				Set if error
+;	Corrupts registers:
+;		AX, BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_OpenWithPathInDSSIandFileAccessInAL:
+	xchg	dx, si		; Path now in DS:DX
+	mov		ah, OPEN_EXISTING_FILE
+	int		DOS_INTERRUPT_21h
+	xchg	si, dx
+	mov		bx, ax		; Copy file handle to BX
+	ret
+
+
+;--------------------------------------------------------------------
+; FileIO_ReadDXCXbytesToDSSIusingHandleFromBX
+;	Parameters:
+;		BX:		File handle
+;		DX:CX:	Number of bytes to read
+;		DS:SI:	Ptr to destination buffer
+;	Returns:
+;		AX:		DOS error code if CF set
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_ReadDXCXbytesToDSSIusingHandleFromBX:
+	push	bp
+	mov		bp, FileIO_ReadCXbytesToDSSIusingHandleFromBX
+	call	SplitLargeReadOrWritesToSmallerBlocks
+	pop		bp
+	ret
+
+;--------------------------------------------------------------------
+; File position is updated so next read will start where
+; previous read stopped.
+;
+; FileIO_ReadCXbytesToDSSIusingHandleFromBX
+;	Parameters:
+;		BX:		File handle
+;		CX:		Number of bytes to read
+;		DS:SI:	Ptr to destination buffer
+;	Returns:
+;		AX:		Number of bytes actually read if successful (0 if at EOF before call)
+;				DOS error code if CF set
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_ReadCXbytesToDSSIusingHandleFromBX:
+	xchg	dx, si				; DS:DX now points to destination buffer
+	mov		ah, READ_FROM_FILE_OR_DEVICE
+	int		DOS_INTERRUPT_21h
+	xchg	si, dx
+	ret
+
+
+;--------------------------------------------------------------------
+; FileIO_WriteDXCXbytesFromDSSIusingHandleFromBX
+;	Parameters:
+;		BX:		File handle
+;		DX:CX:	Number of bytes to write
+;		DS:SI:	Ptr to source buffer
+;	Returns:
+;		AX:		DOS error code if CF set
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_WriteDXCXbytesFromDSSIusingHandleFromBX:
+	push	bp
+	mov		bp, FileIO_WriteCXbytesFromDSSIusingHandleFromBX
+	call	SplitLargeReadOrWritesToSmallerBlocks
+	pop		bp
+	ret
+
+;--------------------------------------------------------------------
+; File position is updated so next write will start where
+; previous write stopped.
+;
+; FileIO_WriteCXbytesFromDSSIusingHandleFromBX:
+;	Parameters:
+;		BX:		File handle
+;		CX:		Number of bytes to write
+;		DS:SI:	Ptr to source buffer
+;	Returns:
+;		AX:		Number of bytes actually written if successful (EOF check)
+;				DOS error code if CF set
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_WriteCXbytesFromDSSIusingHandleFromBX:
+	xchg	dx, si				; DS:DX now points to source buffer
+	mov		ah, WRITE_TO_FILE_OR_DEVICE
+	int		DOS_INTERRUPT_21h
+	xchg	si, dx
+	ret
+
+
+;--------------------------------------------------------------------
+; SplitLargeReadOrWritesToSmallerBlocks
+;	Parameters:
+;		BX:		File handle
+;		BP:		Ptr to transfer function
+;		DX:CX:	Number of bytes to transfer
+;		DS:SI:	Ptr to transfer buffer
+;	Returns:
+;		AX:		DOS error code if CF set
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SplitLargeReadOrWritesToSmallerBlocks:
+	push	ds
+	push	si
+	push	dx
+	push	cx
+
+	xchg	ax, cx					; DX:AX now holds bytes to transfer
+	mov		cx, SPLIT_SIZE_FOR_LARGE_TRANSFERS
+	div		cx						; AX = Number of full transfers
+	push	dx						; Bytes for last transfer
+	test	ax, ax
+	jz		SHORT .TransferRemainingBytes
+	xchg	dx, ax					; DX = Number of full transfers
+
+ALIGN JUMP_ALIGN
+.TransferNextBytes:
+	call	NormalizeDSSI
+	call	bp						; Transfer function
+	jc		SHORT .ErrorOccurredDuringTransfer
+	add		si, SPLIT_SIZE_FOR_LARGE_TRANSFERS
+	dec		dx
+	jnz		SHORT .TransferNextBytes
+.TransferRemainingBytes:
+	pop		cx						; CX = Bytes for last transfer
+	jcxz	.ReturnErrorCodeInAX	; No remaining bytes
+	call	NormalizeDSSI
+	call	bp
+.ReturnErrorCodeInAX:
+	pop		cx
+	pop		dx
+	pop		si
+	pop		ds
+	ret
+.ErrorOccurredDuringTransfer:
+	pop		cx						; Remove bytes for last transfer
+	jmp		SHORT .ReturnErrorCodeInAX
+
+;--------------------------------------------------------------------
+; NormalizeDSSI
+;	Parameters
+;		DS:SI:	Ptr to normalize
+;	Returns:
+;		DS:SI:	Normalized pointer
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+NormalizeDSSI:
+	push	dx
+	push	ax
+	NORMALIZE_FAR_POINTER ds, si, ax, dx
+	pop		ax
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; FileIO_GetFileSizeToDXAXusingHandleFromBXandResetFilePosition:
+;	Parameters:
+;		BX:		File handle
+;	Returns:
+;		DX:AX:	Signed file size (if CF cleared)
+;		AX:		DOS error code (if CF set)
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_GetFileSizeToDXAXusingHandleFromBXandResetFilePosition:
+	push	cx
+
+	; Get file size to DX:AX
+	xor		cx, cx
+	xor		dx, dx
+	mov		al, SEEK_FROM.endOfFile
+	call	FileIO_SeekFromOriginInALtoOffsetInDXAXusingHandleFromBX
+	jc		SHORT .ReturnFileError
+	push	dx
+	push	ax
+
+	; Reset file position
+	xor		dx, dx
+	mov		al, SEEK_FROM.startOfFile
+	call	FileIO_SeekFromOriginInALtoOffsetInDXAXusingHandleFromBX
+	pop		ax
+	pop		dx
+
+.ReturnFileError:
+	pop		cx
+	ret
+
+
+;--------------------------------------------------------------------
+; FileIO_CloseUsingHandleFromBX
+;	Parameters:
+;		BX:		File handle
+;	Returns:
+;		AX:		DOS error code if CF set
+;		CF:		Clear if file closed successfully
+;				Set if error
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileIO_CloseUsingHandleFromBX:
+	mov		ah, CLOSE_FILE
+	SKIP2B	f	; cmp ax, <next instruction>
+	; Fall to FileIO_SeekFromOriginInALtoOffsetInDXAXusingHandleFromBX
+
+
+;--------------------------------------------------------------------
+; FileIO_SeekFromOriginInALtoOffsetInDXAXusingHandleFromBX:
+;	Parameters:
+;		AL:		SEEK_FROM.(origin)
+;		BX:		File handle
+;		CX:DX:	Signed offset to seek starting from AL
+;	Returns:
+;		DX:AX:	New file position in bytes from start of file (if CF cleared)
+;		AX:		DOS error code (if CF set)
+;		CF:		Clear if successful
+;				Set if error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+FileIO_SeekFromOriginInALtoOffsetInDXAXusingHandleFromBX:
+	mov		ah, SET_CURRENT_FILE_POSITION
+	int		DOS_INTERRUPT_21h
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Keyboard/Keyboard.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Keyboard/Keyboard.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Keyboard/Keyboard.asm	(revision 348)
@@ -0,0 +1,290 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for managing keyboard.
+
+BUFFER_SIZE_FOR_WORD_INPUT		EQU		6	; 5 chars + NULL
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Reads user inputted word.
+; Function returns when ENTER or ESC will be pressed.
+;
+; Keyboard_ReadUserInputtedWordWhilePrinting
+;	Parameters
+;		BX:		Numeric base (10 or 16)
+;	Returns:
+;		AX:		User inputted word
+;		ZF:		Set if user cancellation
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Keyboard_ReadUserInputtedWordWhilePrinting:
+	push	ds
+	push	si
+	push	cx
+
+	mov		cx, BUFFER_SIZE_FOR_WORD_INPUT
+	call	Memory_ReserveCXbytesFromStackToDSSI
+
+	call	Char_GetFilterFunctionToDXforNumericBaseInBX
+	call	Registers_ExchangeDSSIwithESDI
+	call	Keyboard_ReadUserInputtedStringToESDIWhilePrinting
+	call	Registers_ExchangeDSSIwithESDI	; Does not modify FLAGS
+	jz		SHORT .CancelledByUser
+
+	call	String_ConvertWordToAXfromStringInDSSIwithBaseInBX
+.CancelledByUser:
+	add		sp, BYTE BUFFER_SIZE_FOR_WORD_INPUT
+	test	cx, cx							; Set ZF if string length is zero
+	pop		cx
+	pop		si
+	pop		ds
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Reads user inputted string to buffer. Character filter is
+; supported to ignore unwanted characters.
+; Function returns when ENTER or ESC will be pressed.
+;
+; Keyboard_ReadUserInputtedStringToESDIWhilePrinting
+;	Parameters:
+;		CX:		Buffer size (with NULL)
+;		ES:DI:	Ptr to destination buffer
+;		CS:DX:	Ptr to character filter function:
+;					Parameters:
+;						AL:		Character inputted by user
+;					Returns:
+;						CF:		Set if character is accepted
+;								Cleared if character is rejected
+;					Corrupts registers:
+;						Nothing
+;	Returns:
+;		CX:		String length in characters (without NULL)
+;		ZF:		Set if user cancellation
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Keyboard_ReadUserInputtedStringToESDIWhilePrinting:
+	push	di
+	push	si
+	push	bx
+	call	.PrepareDisplayContextForKeyboardInput
+	jcxz	.ReturnAfterUpdatingZF
+
+	xor		bx, bx								; Zero character counter
+	dec		cx									; Decrement buffer size for NULL
+	cld
+ALIGN JUMP_ALIGN
+.GetCharacterFromUser:
+	call	Keyboard_GetKeystrokeToAXandWaitIfNecessary	; Get ASCII to AL
+	call	.ProcessControlCharacter
+	jz		SHORT .TerminateStringWithNULL
+	jc		SHORT .PlayBellForRejectedCharacter
+	call	dx									; Filter character
+	jnc		SHORT .PlayBellForRejectedCharacter
+	inc		bx									; Increment number of characters stored
+	stosb										; Store from AL to ES:DI
+	call	Keyboard_PrintInputtedCharacter
+	loop	.GetCharacterFromUser
+.PlayBellForRejectedCharacter:
+	cmp		al, BS								; No bell for backspace
+	je		SHORT .GetCharacterFromUser
+	call	Keyboard_PlayBellForUnwantedKeystroke
+	jmp		SHORT .GetCharacterFromUser
+
+.TerminateStringWithNULL:
+	stosb										; Terminate string with NULL
+	mov		cx, bx								; String length now in CX
+
+.ReturnAfterUpdatingZF:
+	CALL_DISPLAY_LIBRARY PopDisplayContext
+	test	cx, cx								; Clear or set ZF
+	pop		bx
+	pop		si
+	pop		di
+	ret
+
+;--------------------------------------------------------------------
+; .PrepareDisplayContextForKeyboardInput
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing (Display context pushed to stack)
+;	Corrupts registers:
+;		AX, BX, SI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.PrepareDisplayContextForKeyboardInput:
+	pop		bx					; Pop return address to BX
+	mov		si, di
+
+	CALL_DISPLAY_LIBRARY PushDisplayContext
+	mov		ax, CURSOR_NORMAL
+	CALL_DISPLAY_LIBRARY SetCursorShapeFromAX
+	CALL_DISPLAY_LIBRARY SynchronizeDisplayContextToHardware
+
+	mov		di, si
+	jmp		bx
+
+
+;--------------------------------------------------------------------
+; .ProcessControlCharacter
+;	Parameters:
+;		AL:		Character inputted by user
+;		CX:		Number of bytes left in buffer
+;		BX:		Total number of characters inputted
+;		ES:DI:	Ptr where to store next character
+;	Returns:
+;		AL:		Character inputted by user or NULL if end of input
+;		BX:		Cleared if user cancellation
+;		ZF:		Set if user has ended or cancelled key input
+;		CF:		Set if character is rejected
+;	Corrupts registers:
+;		AH
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ProcessControlCharacter:
+	cmp		al, CR								; ENTER to terminate string?
+	je		SHORT .EndCharacterInput
+	cmp		al, ESC								; Cancel input?
+	je		SHORT .CancelCharacterInput
+	cmp		al, BS								; Backspace?
+	je		SHORT .Backspace
+	jcxz	.RejectCharacter
+	clc											; Clear CF (ZF is already cleared)
+	ret
+
+.Backspace:
+	test	bx, bx								; At the beginning?
+	jz		SHORT .RejectCharacter
+	inc		cx									; Increment bytes left
+	dec		bx									; Decrement characters inputted
+	dec		di
+	call	Keyboard_PrintBackspace
+	mov		al, BS								; Restore character
+.RejectCharacter:
+	test	al, al								; Clear ZF...
+	stc											; ...and set CF
+	ret
+
+.CancelCharacterInput:
+	xor		bx, bx
+.EndCharacterInput:
+	xor		al, al								; Set ZF and clear CF
+	ret
+%endif ; EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+
+
+;--------------------------------------------------------------------
+; Keyboard_PrintBackspace
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Keyboard_PrintBackspace:
+	mov		al, BS
+	call	Keyboard_PrintInputtedCharacter
+	mov		al, ' '
+	call	Keyboard_PrintInputtedCharacter
+	mov		al, BS
+	jmp		SHORT Keyboard_PrintInputtedCharacter
+%endif
+
+
+;--------------------------------------------------------------------
+; Keyboard_PlayBellForUnwantedKeystroke
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Keyboard_PlayBellForUnwantedKeystroke:
+	mov		al, BELL
+	; Fall to Keyboard_PrintInputtedCharacter
+%endif
+
+;--------------------------------------------------------------------
+; Keyboard_PrintInputtedCharacter
+;	Parameters:
+;		AL:		Character inputted by user
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Keyboard_PrintInputtedCharacter:
+	push	di
+	CALL_DISPLAY_LIBRARY PrintCharacterFromAL
+	CALL_DISPLAY_LIBRARY SynchronizeDisplayContextToHardware	; Hardware cursor
+	pop		di
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Keyboard_RemoveAllKeystrokesFromBuffer
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS	; Only used when debugging
+ALIGN JUMP_ALIGN
+Keyboard_RemoveAllKeystrokesFromBuffer:
+	call	Keyboard_GetKeystrokeToAX
+	jnz		SHORT Keyboard_RemoveAllKeystrokesFromBuffer
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Keyboard_GetKeystrokeToAX
+; Keyboard_GetKeystrokeToAXandLeaveItToBuffer
+; Keyboard_GetKeystrokeToAXandWaitIfNecessary
+;	Parameters:
+;		Nothing
+;	Returns:
+;		AL:		ASCII character (if keystroke available)
+;		AH:		BIOS scan code (if keystroke available)
+;		ZF:		Set if no keystroke available
+;				Cleared if keystroke available
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Keyboard_GetKeystrokeToAXandLeaveItToBuffer:
+	mov		ah, CHECK_FOR_KEYSTROKE
+	int		BIOS_KEYBOARD_INTERRUPT_16h
+	ret
+ALIGN JUMP_ALIGN
+Keyboard_GetKeystrokeToAX:
+	call	Keyboard_GetKeystrokeToAXandLeaveItToBuffer
+	jz		SHORT Keyboard_GetKeystrokeToAXReturn
+	; Fall to Keyboard_GetKeystrokeToAXandWaitIfNecessary
+ALIGN JUMP_ALIGN
+Keyboard_GetKeystrokeToAXandWaitIfNecessary:
+	xor		ah, ah						; GET_KEYSTROKE
+	int		BIOS_KEYBOARD_INTERRUPT_16h
+	test	ax, ax						; Clear ZF
+Keyboard_GetKeystrokeToAXReturn:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/LibSizeCheck.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/LibSizeCheck.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/LibSizeCheck.asm	(revision 348)
@@ -0,0 +1,20 @@
+; Project name	:	Assembly Library
+; Description	:	Tests for Assembly Library.
+;					Builds wanted library functions to check their size.
+
+; Include .inc files
+%define EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+;%define INCLUDE_DISPLAY_LIBRARY
+;%define INCLUDE_FILE_LIBRARY
+;%define INCLUDE_KEYBOARD_LIBRARY
+%define INCLUDE_MENU_LIBRARY
+;%define INCLUDE_MENU_DIALOGS
+;%define INCLUDE_STRING_LIBRARY
+;%define INCLUDE_TIME_LIBRARY
+;%define INCLUDE_UTIL_LIBRARY
+
+%include "AssemblyLibrary.inc"	; Assembly Library. Must be included first!
+
+
+; Include library sources
+%include "AssemblyLibrary.asm"
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/LibraryTests.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/LibraryTests.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/LibraryTests.asm	(revision 348)
@@ -0,0 +1,640 @@
+; File name		:	LibraryTests.asm
+; Project name	:	Assembly Library
+; Created date	:	27.6.2010
+; Last update	:	7.12.2010
+; Author		:	Tomi Tilli
+; Description	:	Tests for Assembly Library.
+;					This file should not be included when using the library on
+;					some other project.		
+
+; Include .inc files
+%define INCLUDE_MENU_DIALOGS
+%include "AssemblyLibrary.inc"	; Assembly Library. Must be included first!
+
+
+; Section containing code
+SECTION .text
+
+; Program first instruction.
+ORG	100h						; Code starts at offset 100h (DOS .COM)
+Start:
+	jmp		LibraryTests_Start
+
+; Include library sources
+%include "AssemblyLibrary.asm"
+
+
+;--------------------------------------------------------------------
+; Program start
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+LibraryTests_Start:	
+	CALL_DISPLAY_LIBRARY InitializeDisplayContext
+	mov		ax, SCREEN_BACKGROUND_CHARACTER_AND_ATTRIBUTE
+	CALL_DISPLAY_LIBRARY ClearScreenWithCharInALandAttrInAH
+
+	;call	LibraryTests_Sort
+	;call	LibraryTests_ForDisplayLibrary
+	;call	LibraryTests_ForKeyboardLibrary
+	call	LibraryTests_ForMenuLibrary
+
+	; Exit to DOS
+	;mov		ax, CURSOR_XY(1, 1)
+	;CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	CALL_DISPLAY_LIBRARY SynchronizeDisplayContextToHardware
+	mov 	ax, 4C00h			; Exit to DOS
+	int 	21h
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ALIGN JUMP_ALIGN
+LibraryTests_ForMenuLibrary:
+	mov		[cs:g_dialogInputOutput+DIALOG_INPUT.fszTitle+2], cs
+	mov		[cs:g_dialogInputOutput+DIALOG_INPUT.fszItems+2], cs
+	mov		[cs:g_dialogInputOutput+DIALOG_INPUT.fszInfo+2], cs
+
+	mov		bx, .MenuEventHandler
+	call	MenuInit_DisplayMenuWithHandlerInBXandUserDataInDXAX
+	ret
+
+ALIGN JUMP_ALIGN
+.MenuEventHandler:
+	jmp		[cs:bx+.rgfnMenuEvents]
+.NotHandled:
+	clc		; Not handled so clear
+	ret
+
+ALIGN JUMP_ALIGN
+.InitializeMenu:
+	mov		WORD [si+MENUINIT.wItems], 51
+	mov		BYTE [si+MENUINIT.bWidth], 40
+	mov		BYTE [si+MENUINIT.bHeight], 20
+	mov		BYTE [si+MENUINIT.bTitleLines], TEST_MENU_TITLE_LINES
+	mov		BYTE [si+MENUINIT.bInfoLines], TEST_MENU_INFO_LINES
+	mov		WORD [si+MENUINIT.wHighlightedItem], 1
+	
+	mov		ax, 10000 / 55	; 10 seconds
+	CALL_MENU_LIBRARY StartSelectionTimeoutWithTicksInAX
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.RefreshTitle:
+	mov		si, .szMenuTitle
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	stc
+	ret
+.szMenuTitle:
+	db		"Simple test program for Assembly Library. Can be used to find bugs.",NULL
+
+ALIGN JUMP_ALIGN
+.RefreshInformation:
+	push	bp
+	mov		bp, sp
+	mov		si, .szInfoTitle
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	pop		bp
+	stc
+	ret
+.szInfoTitle:
+	db		"Information line 1,",LF,CR,
+	db		"Information line 2. Auto splitter should split this very long line.",NULL
+
+ALIGN JUMP_ALIGN
+.RefreshItemFromCX:
+	cmp		cx, TEST_MENU_VALID_ITEMS
+	jb		SHORT .PrintKnownItem
+
+	push	bp
+	mov		si, .szItem
+	mov		bp, sp
+	push	cx				; Item index
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	pop		bp
+	stc
+	ret
+.szItem:
+	db	"This is item %d.",NULL
+.PrintKnownItem:
+	mov		si, cx
+	shl		si, 1
+	mov		si, [cs:si+.rgszItems]
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.ItemSelectedFromCX:
+	push	cs
+	pop		ds
+	cmp		cx, TEST_MENU_VALID_ITEMS
+	jae		SHORT .ReturnWithoutHandling
+	mov		bx, cx
+	shl		bx, 1
+	jmp		[bx+.rgfnSelectionHandler]
+.ReturnWithoutHandling:
+	stc
+	ret
+
+ALIGN WORD_ALIGN
+.rgfnSelectionHandler:
+	dw		.ExitMenuByItem
+	dw		.ToggleTitle
+	dw		.ToggleInfo
+	dw		.ShowMessageDialogWithUnformattedText
+	dw		.AskWordFromUser
+	dw		.AskStringFromUser
+	dw		.AskSelectionFromUser
+	dw		.AskFileFromUser
+	dw		.TestProgressBar
+
+
+ALIGN JUMP_ALIGN
+.ExitMenuByItem:
+	CALL_MENU_LIBRARY Close
+.ExitMenuByMenuLibrary:
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.ToggleTitle:
+	mov		al, [bp+MENUINIT.bTitleLines]
+	xor		al, TEST_MENU_TITLE_LINES
+	CALL_MENU_LIBRARY SetTitleHeightFromAL
+	jmp		SHORT .RefreshMenuWindow
+ALIGN JUMP_ALIGN
+.ToggleInfo:
+	mov		al, [bp+MENUINIT.bInfoLines]
+	xor		al, TEST_MENU_INFO_LINES
+	CALL_MENU_LIBRARY SetInformationHeightFromAL
+.RefreshMenuWindow:
+	;CALL_MENU_LIBRARY RestartTimeout
+	CALL_MENU_LIBRARY RefreshWindow
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.ShowMessageDialogWithUnformattedText:
+	mov		di, g_szVeryLongString
+	jmp		.ShowDialogWithStringInCSDI
+
+ALIGN JUMP_ALIGN
+.AskWordFromUser:
+	mov		si, g_dialogInputOutput
+	mov		BYTE [si+WORD_DIALOG_IO.bNumericBase], 10
+	mov		WORD [si+WORD_DIALOG_IO.wMin], 10
+	mov		WORD [si+WORD_DIALOG_IO.wMax], 20
+	CALL_MENU_LIBRARY GetWordWithIoInDSSI
+
+	mov		ax, [si+WORD_DIALOG_IO.wReturnWord]
+	mov		di, g_szBuffer
+	call	.FormatWordFromAXtoStringBufferInCSDI
+	call	.ShowDialogWithStringInCSDI
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.AskStringFromUser:
+	mov		si, g_dialogInputOutput
+	mov		WORD [si+STRING_DIALOG_IO.fnCharFilter], NULL
+	mov		WORD [si+STRING_DIALOG_IO.wBufferSize], 17
+	mov		WORD [si+STRING_DIALOG_IO.fpReturnBuffer], g_szBuffer
+	mov		[si+STRING_DIALOG_IO.fpReturnBuffer+2], cs
+	CALL_MENU_LIBRARY GetStringWithIoInDSSI
+
+	mov		di, g_szBuffer
+	call	.ShowDialogWithStringInCSDI
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.AskSelectionFromUser:
+	mov		si, g_dialogInputOutput
+	mov		WORD [si+DIALOG_INPUT.fszItems], .szSelections
+	CALL_MENU_LIBRARY GetSelectionToAXwithInputInDSSI
+
+	mov		di, g_szBuffer
+	call	.FormatWordFromAXtoStringBufferInCSDI
+	call	.ShowDialogWithStringInCSDI
+	stc
+	ret
+.szSelections:
+	db		"Cancel",LF
+	db		"Yes",LF
+	db		"No",NULL
+
+ALIGN JUMP_ALIGN
+.AskFileFromUser:
+	mov		si, g_dialogInputOutput
+	mov		WORD [si+FILE_DIALOG_IO.fszItemBuffer], g_szBuffer
+	mov		BYTE [si+FILE_DIALOG_IO.bDialogFlags], FLG_FILEDIALOG_DIRECTORY | FLG_FILEDIALOG_NEW | FLG_FILEDIALOG_DRIVES
+	mov		BYTE [si+FILE_DIALOG_IO.bFileAttributes], FLG_FILEATTR_DIRECTORY | FLG_FILEATTR_ARCHIVE
+	mov		WORD [si+FILE_DIALOG_IO.fpFileFilterString], .szAllFiles
+	mov		[si+FILE_DIALOG_IO.fpFileFilterString+2], cs
+	CALL_MENU_LIBRARY GetFileNameWithIoInDSSI
+	cmp		BYTE [g_dialogInputOutput+FILE_DIALOG_IO.bUserCancellation], TRUE
+	je		SHORT .FileSelectionCancelled
+
+	mov		di, g_dialogInputOutput + FILE_DIALOG_IO.szFile
+	call	.ShowDialogWithStringInCSDI
+.FileSelectionCancelled:
+	stc
+	ret
+.szAllFiles:
+	db		"*.*",NULL
+
+
+ALIGN JUMP_ALIGN
+.FormatWordFromAXtoStringBufferInCSDI:
+	push	bp
+	push	di
+	mov		si, di
+	xchg	cx, ax
+	CALL_DISPLAY_LIBRARY PushDisplayContext
+
+	mov		bx, cs
+	mov		ax, si
+	CALL_DISPLAY_LIBRARY SetCharacterPointerFromBXAX
+	mov		bl, ATTRIBUTES_NOT_USED
+	mov		ax, BUFFER_OUTPUT_WITH_CHAR_ONLY
+	CALL_DISPLAY_LIBRARY SetCharOutputFunctionFromAXwithAttribFlagInBL
+	lea		ax, [si+STRING_BUFFER_SIZE]
+	CALL_DISPLAY_LIBRARY SetCharacterOutputParameterFromAX
+
+	mov		si, .szFormatWord
+	mov		bp, sp
+	push	cx
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	mov		al, NULL
+	CALL_DISPLAY_LIBRARY PrintCharacterFromAL	; Terminate buffer with NULL
+
+	CALL_DISPLAY_LIBRARY PopDisplayContext
+	pop		di
+	pop		bp
+	ret
+.szFormatWord:
+	db		"Integer %d selected!",NULL
+
+
+ALIGN JUMP_ALIGN
+.ShowDialogWithStringInCSDI:
+	push	cs
+	pop		ds
+	mov		si, g_dialogInputOutput
+	mov		WORD [si+DIALOG_INPUT.fszItems], di
+	CALL_MENU_LIBRARY DisplayMessageWithInputInDSSI
+	stc
+	ret
+
+
+ALIGN JUMP_ALIGN
+.TestProgressBar:
+	push	cs
+	pop		ds
+	mov		si, g_dialogInputOutput
+	mov		WORD [si+PROGRESS_DIALOG_IO.wCurrentProgressValue], 0
+	mov		WORD [si+PROGRESS_DIALOG_IO.wMaxProgressValue], 500
+	mov		WORD [si+PROGRESS_DIALOG_IO.wMinProgressValue], 0
+	mov		WORD [si+PROGRESS_DIALOG_IO.fnTaskWithParamInDSSI], .ProgressTaskWithParamInDSSI
+	mov		ax, 500			; Counter for progress task
+	CALL_MENU_LIBRARY StartProgressTaskWithIoInDSSIandParamInDXAX
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.ProgressTaskWithParamInDSSI:
+	mov		ax, 50000					; 50 millisec delay
+	call	Delay_MicrosecondsFromAX
+	dec		si
+	CALL_MENU_LIBRARY SetUserDataFromDSSI
+	mov		ax, 500
+	sub		ax, si
+	push	si
+	CALL_MENU_LIBRARY SetProgressValueFromAX
+	pop		si
+	test	si, si
+	jnz		.ProgressTaskWithParamInDSSI
+	ret
+	
+	
+
+ALIGN WORD_ALIGN
+.rgfnMenuEvents:
+	dw		.InitializeMenu			; .InitializeMenuinitToDSSI
+	dw		.ExitMenuByMenuLibrary	; .ExitMenu
+	dw		.NotHandled				; .IdleProcessing
+	dw		.NotHandled				; .ItemHighlightedFromCX
+	dw		.ItemSelectedFromCX		; .ItemSelectedFromCX
+	dw		.NotHandled				; .KeyStrokeInDX
+	dw		.RefreshTitle			; .RefreshTitle
+	dw		.RefreshInformation		; .RefreshInformation
+	dw		.RefreshItemFromCX		; .RefreshItemFromCX
+
+.rgszItems:
+	dw		.szExitMenu
+	dw		.szToggleTitle
+	dw		.szToggleInfo
+	dw		.szShowMessage
+	dw		.szAskWord
+	dw		.szAskString
+	dw		.szAskSelection
+	dw		.szAskFile
+	dw		.szTestProgress
+.szExitMenu:	db	"Exit menu",NULL
+.szToggleTitle:	db	"Toggle title",NULL
+.szToggleInfo:	db	"Toggle information",NULL
+.szShowMessage:	db	"Display unformatted message",NULL
+.szAskWord:		db	"Input word",NULL
+.szAskString:	db	"Input string",NULL
+.szAskSelection:db	"Display selection dialog",NULL
+.szAskFile:		db	"Display file dialog",NULL
+.szTestProgress:db	"Display progress bar",NULL
+TEST_MENU_VALID_ITEMS			EQU		9
+TEST_MENU_TITLE_LINES			EQU		2
+TEST_MENU_INFO_LINES			EQU		3
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ALIGN JUMP_ALIGN
+LibraryTests_ForKeyboardLibrary:
+	mov		ax, CURSOR_XY(0, 6)
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	call	ReadUnsignedDecimalInteger
+	call	ReadHexadecimalWord
+	ret
+
+
+ReadUnsignedDecimalInteger:
+	mov		si, .szEnterUnsignedWord
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	CALL_DISPLAY_LIBRARY SynchronizeDisplayContextToHardware	; Move hardware cursor
+
+	mov		bx, 10			; Numeric base
+	call	Keyboard_ReadUserInputtedWordWhilePrinting
+
+	mov		si, .szWordEntered
+	mov		bp, sp
+	push	ax
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szWordEntered:
+	db	". Word entered: %u",LF,CR,NULL
+.szEnterUnsignedWord:
+	db	"Enter unsigned word: ",NULL
+
+
+ReadHexadecimalWord:
+	mov		si, .szEnterHexadecimalWord
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	CALL_DISPLAY_LIBRARY SynchronizeDisplayContextToHardware	; Move hardware cursor
+
+	mov		bx, 16			; Numeric base
+	call	Keyboard_ReadUserInputtedWordWhilePrinting
+
+	mov		si, .szWordEntered
+	mov		bp, sp
+	push	ax
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szWordEntered:
+	db	". Word entered: %x",LF,CR,NULL
+.szEnterHexadecimalWord:
+	db	"Enter hexadecimal word: ",NULL
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ALIGN JUMP_ALIGN
+LibraryTests_ForDisplayLibrary:
+	CALL_DISPLAY_LIBRARY PushDisplayContext
+	call	PrintHorizontalRuler
+	call	PrintVerticalRuler
+	
+	mov		al, COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_BLACK)
+	CALL_DISPLAY_LIBRARY SetCharacterAttributeFromAL
+
+	mov		ax, CURSOR_XY(0, 1)
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	call	PrintFormattedStrings
+
+	CALL_DISPLAY_LIBRARY PopDisplayContext
+	ret
+
+
+PrintHorizontalRuler:
+	mov		ax, CURSOR_XY(0, 0)
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
+	eMOVZX	cx, al
+	mov		bx, 10<<8			; Divider 10 to BH
+.ColumnNumberLoop:
+	eMOVZX	ax, bl				; Column index to AX (0...79)
+	div		bh					; AH = 0...9, AL = attribute
+	mov		dx, ax
+	inc		ax					; Increment attribute for non-black foreground
+	CALL_DISPLAY_LIBRARY SetCharacterAttributeFromAL
+	xchg	ax, dx
+	mov		al, '0'
+	add		al, ah				; AL = '0'...'9'
+	CALL_DISPLAY_LIBRARY PrintCharacterFromAL
+	inc		bx					; Increment column index
+	loop	.ColumnNumberLoop
+	ret
+
+
+PrintVerticalRuler:
+	CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
+	eMOVZX	cx, ah				; Number of rows to CX
+	dec		ax					; Last column
+	xor		ah, ah
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+
+	dec		cx					; Decrement rows to print last row outside loop
+	mov		bx, 10<<8			; BH = 10 (divider), BL = 0 (row index)
+	mov		si, .szVerticalRulerCharacter
+.RowNumberLoop:
+	call	.PrintRowNumberFromBL
+	inc		bx					; Increment row index
+	loop	.RowNumberLoop
+
+	; Last row
+	mov		si, .szLastVerticalRulerCharacter
+.PrintRowNumberFromBL:
+	eMOVZX	ax, bl				; Row index to AX (0...24)
+	div		bh					; AH = 0...9, AL = attribute
+	add		al, COLOR_GRAY		; Start from color GRAY
+	mov		bp, sp				; Prepare BP for string formatting
+	push	ax					; Push attribute
+	eMOVZX	ax, ah
+	push	ax					; Push row index
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+
+.szVerticalRulerCharacter:
+	db	"%A%u",LF,NULL
+.szLastVerticalRulerCharacter:
+	db	"%A%u",NULL
+
+
+PrintFormattedStrings:
+	call	.PrintIntegers
+	call	.PrintHexadecimals
+	call	.PrintCharacters
+	call	.PrintStrings
+	call	.RepeatChar
+	ret
+
+.PrintIntegers:
+	mov		si, .szIntegers
+	mov		bp, sp
+	ePUSH_T	ax, COLOR_ATTRIBUTE(COLOR_RED, COLOR_BLACK)
+	ePUSH_T	ax, -32768
+	ePUSH_T	ax, -1
+	ePUSH_T	ax, 0
+	ePUSH_T	ax, 1
+	ePUSH_T	ax, 65535
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szIntegers:
+	db	"Integers -32768, -1, 0, 1, 65535:          %A|%6-d|%6-d|%6-d|%6-d|%6-u|",LF,CR,NULL
+
+.PrintHexadecimals:
+	mov		si, .szHexadecimals
+	mov		bp, sp
+	ePUSH_T	ax, COLOR_ATTRIBUTE(COLOR_RED, COLOR_BLACK)
+	ePUSH_T	ax, 0CACAh
+	ePUSH_T	ax, 0FFFFh
+	ePUSH_T	ax, 0
+	ePUSH_T	ax, 5A5Ah
+	ePUSH_T	ax, 0A5A5h
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szHexadecimals:
+	db	"Hexadecimals CACAh, FFFFh, 0, 5A5Ah, A5A5h:%A|%6-x|%6-x|%6-x|%6-x|%6-x|",LF,CR,NULL
+
+.PrintCharacters:
+	mov		si, .szCharacters
+	mov		bp, sp
+	ePUSH_T	ax, COLOR_ATTRIBUTE(COLOR_RED, COLOR_BLACK)
+	ePUSH_T	ax, 'a'
+	ePUSH_T	ax, 'B'
+	ePUSH_T	ax, 'c'
+	ePUSH_T	ax, 'D'
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szCharacters:
+	db	"Characters a, B, c, D, percent:            %A|%6c|%6c|%6c|%6c|%6%|",LF,CR,NULL
+
+.PrintStrings:
+	mov		si, .szStrings
+	mov		bp, sp
+	ePUSH_T	ax, COLOR_ATTRIBUTE(COLOR_RED, COLOR_BLACK)
+	ePUSH_T	ax, .szCSSI
+	ePUSH_T	ax, .szFar
+	push	cs
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szStrings:
+	db	"Strings ",'"',"Hello CSSI",'"'," and ",'"',"Far",'"',":            %A|%20s|%13S|",LF,CR,NULL
+.szCSSI:
+	db	"Hello CSSI",NULL
+.szFar:
+	db	"Far",NULL
+	
+.RepeatChar:
+	mov		si, .szRepeat
+	mov		bp, sp
+	ePUSH_T	ax, COLOR_ATTRIBUTE(COLOR_RED, COLOR_BLACK)
+	ePUSH_T	ax, '-'
+	ePUSH_T	ax, 36
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+.szRepeat:
+	db	"Repeating character '-':                   %A%t",LF,CR,NULL
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+LibraryTests_Sort:
+	call	.PrintWords
+	push	cs
+	pop		ds
+	mov		si, .rgwItems
+	mov		dx, 7
+	mov		cx, 2
+	mov		bx, .Comparator
+	call	Sort_ItemsFromDSSIwithCountInDXsizeInCXandComparatorInBX
+	call	.PrintWords
+	ret
+
+
+.Comparator:
+	push	ax
+	mov		ax, [si]
+	DISPLAY_DEBUG_CHARACTER 'I'
+	DISPLAY_DEBUG_WORD_AND_WAIT_ANY_KEY ax, 16
+	DISPLAY_DEBUG_CHARACTER ','
+	DISPLAY_DEBUG_WORD_AND_WAIT_ANY_KEY [es:di], 16
+	DISPLAY_DEBUG_CHARACTER ' '
+	cmp		ax, [es:di]
+	pop		ax
+	ret
+
+.PrintWords:
+	CALL_DISPLAY_LIBRARY PrintNewlineCharacters
+	mov		cx, 7
+	push	cs
+	pop		ds
+	mov		si, .rgwItems
+	mov		bx, 16
+.Loop:
+	lodsw
+	CALL_DISPLAY_LIBRARY PrintSignedWordFromAXWithBaseInBX
+	CALL_DISPLAY_LIBRARY PrintNewlineCharacters
+	loop	.Loop
+	ret
+
+
+.rgwItems:
+	dw		'['
+	dw		'n'
+	dw		'5'
+	dw		'.'
+	dw		']'
+	dw		'a'
+	dw		'A'
+
+
+
+; Section containing initialized data
+;SECTION .data
+
+g_szDialogTitle:
+	db		"This is a generic title for all dialogs.",NULL
+g_szDialogInfo:
+	db		"This is a generic information for all dialogs.",NULL
+g_szVeryLongString:
+	db		"This is a very long string containing multiple lines of text. This is needed "
+	db		"so scroll bars and message dialog can be tested. This string does not use "
+	db		"formatting so it should be simple to display this correctly. This string "
+	db		"does, however, use newline characters. Lets change line right now!",LF,CR,
+	db		"Well did it work? Let's try line feed alone",LF,"Well? "
+	db		"Now two LFs:",LF,LF,"What happened? "
+	db		"We could also see what two spaces does _  _. There was two spaces between "
+	db		"underscores. Lets try three this time _   _. Well, did they work correctly? "
+	db		"Too bad that LF, CR and BS (backspace) are the only supported control "
+	db		"characters. Others don't either work or they break line splitting. "
+	db		"This is the last sentence of this long string!",NULL
+
+g_dialogInputOutput:
+istruc DIALOG_INPUT
+	at	DIALOG_INPUT.fszTitle,	dw	g_szDialogTitle
+	at	DIALOG_INPUT.fszInfo,	dw	g_szDialogInfo
+iend
+	times	20	db	0
+
+
+; Section containing uninitialized data
+SECTION .bss
+
+STRING_BUFFER_SIZE			EQU		100
+g_szBuffer:
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/CharOutLineSplitter.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/CharOutLineSplitter.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/CharOutLineSplitter.asm	(revision 348)
@@ -0,0 +1,162 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for splitting menu lines during character output.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; CharOutLineSplitter_PrepareForPrintingTextLines
+;	Parameters:
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CharOutLineSplitter_PrepareForPrintingTextLines:
+	; Get first text line column offset to DX
+	call	CharOutLineSplitter_GetFirstBorderLineColumnOffsetToAX
+	add		al, MENU_TEXT_COLUMN_OFFSET<<1
+	xchg	dx, ax
+
+	; Get last text line column offset to AX
+	call	MenuLocation_GetMaxTextLineLengthToAX
+	shl		ax, 1			; Characters to BYTEs
+	add		ax, dx
+
+	xchg	ax, dx			; AL = First text line column offset
+	mov		ah, dl			; AH = Last text line column offset
+	CALL_DISPLAY_LIBRARY SetCharacterOutputParameterFromAX
+	ret
+
+
+;--------------------------------------------------------------------
+; CharOutLineSplitter_GetFirstBorderLineColumnOffsetToAX
+;	Parameters:
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Offset to end of text line (first border area character)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CharOutLineSplitter_GetFirstBorderLineColumnOffsetToAX:
+	call	MenuLocation_GetTitleBordersTopLeftCoordinatesToAX
+	xor		ah, ah
+	shl		ax, 1
+	ret
+
+
+;--------------------------------------------------------------------
+; CharOutLineSplitter_IsCursorAtTheEndOfTextLine
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location in video memory
+;	Returns:
+;		CF:		Set if end of text line
+;				Clear if more characters fit on current text line
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CharOutLineSplitter_IsCursorAtTheEndOfTextLine:
+	push	ax
+
+	mov		dl, [VIDEO_BDA.wColumns]
+	shl		dl, 1			; DX = bytes per row
+	mov		ax, di
+	div		dl				; AL = row index, AH = column index
+	cmp		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam+1], ah
+
+	pop		ax
+	ret
+
+
+;--------------------------------------------------------------------
+; CharOutLineSplitter_MovePartialWordToNewTextLine
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to end of text line in video memory
+;	Returns:
+;		DI:		Updated to next character for new text line
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CharOutLineSplitter_MovePartialWordToNewTextLine:
+	push	si
+	push	cx
+	push	ax
+	; Fall to .GetOffsetToPartialWordToSIandSizeToCX
+
+;--------------------------------------------------------------------
+; .GetOffsetToPartialWordToSIandSizeToCX
+;	Parameters:
+;		ES:DI:	Ptr to space before border character
+;	Returns:
+;		CX:		Number of bytes that needs to be moved
+;		ES:SI:	Ptr to beginning of partial word that needs to be moved to new line
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+.GetOffsetToPartialWordToSIandSizeToCX:
+	mov		cx, di
+	mov		si, di
+ALIGN JUMP_ALIGN
+.ScanNextCharacter:		; Space will always be found since one comes after border
+	dec		si
+	dec		si
+	cmp		BYTE [es:si], ' '
+	jne		SHORT .ScanNextCharacter
+	inc		si
+	inc		si			; SI now points one past space
+	sub		cx, si
+	; Fall to .ChangeLine
+
+;--------------------------------------------------------------------
+; .ChangeLine
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+.ChangeLine:
+	call	MenuCharOut_PrintLFCRandAdjustOffsetForStartOfLine
+	jcxz	.ReturnFromMovePartialWordToNewTextLine
+	; Fall to .MovePartialWordFromPreviousLineInESSItoNewLineInESDIwithSizeInCX
+
+;--------------------------------------------------------------------
+; .MovePartialWordFromPreviousLineInESSItoNewLineInESDIwithSizeInCX
+;	Parameters:
+;		CX:		Number of BYTEs in partial word
+;		DS:		BDA segment (zero)
+;		ES:SI:	Ptr to partial word on previous line
+;		ES:DI:	Ptr to new empty line
+;	Returns:
+;		ES:DI:	Ptr where to store next character
+;	Corrupts registers:
+;		AX, CX, DX, SI
+;--------------------------------------------------------------------
+.MovePartialWordFromPreviousLineInESSItoNewLineInESDIwithSizeInCX:
+	push	si
+	push	cx
+	WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
+	pop		cx
+	pop		si
+
+	xchg	di, si
+	shr		cx, 1		; Bytes to characters
+	mov		al, ' '
+	call	DisplayPrint_RepeatCharacterFromALwithCountInCX
+	mov		di, si
+
+.ReturnFromMovePartialWordToNewTextLine:
+	pop		ax
+	pop		cx
+	pop		si
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/Dialog.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/Dialog.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/Dialog.asm	(revision 348)
@@ -0,0 +1,296 @@
+; Project name	:	Assembly Library
+; Description	:	Common functions for many dialogs.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+;	Parameters:
+;		BX:		Offset to menu event handler
+;		DX:AX:	Optional user data
+;		DS:SI:	Ptr to DIALOG_INPUT
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		AX:		Selected item
+;	Corrupts registers:
+;		BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_DisplayWithDialogInputInDSSIandHandlerInBX:
+	push	es
+	push	ds
+	mov		di, bp								; Backup parent MENU
+	mov		cx, DIALOG_size
+	eENTER_STRUCT cx
+
+	call	Memory_ZeroSSBPwithSizeInCX
+	mov		[bp+DIALOG.fpDialogIO], si
+	mov		[bp+DIALOG.fpDialogIO+2], ds
+	mov		[bp+DIALOG.pParentMenu], di
+
+	call	MenuInit_EnterMenuWithHandlerInBXandUserDataInDXAX
+	call	Dialog_RemoveFromScreenByRedrawingParentMenu
+	call	Keyboard_RemoveAllKeystrokesFromBuffer
+
+	mov		ax, [bp+MENUINIT.wHighlightedItem]
+	eLEAVE_STRUCT DIALOG_size
+	pop		ds
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; Dialog_EventNotHandled
+;	Parameters:
+;		BX:		Menu event (anything from MENUEVENT struct)
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		CF:		Cleared since event not processed
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_EventNotHandled:
+	clc
+	ret
+
+
+;--------------------------------------------------------------------
+; Dialog_EventAnyThatClosesDialog
+; Dialog_EventExitMenu
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		CF:		Set since event processed
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_EventAnyThatClosesDialog:
+	call	MenuInit_CloseMenuWindow
+ALIGN JUMP_ALIGN
+Dialog_EventExitMenu:
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; Dialog_EventInitializeMenuinitFromDSSIforSingleItemWithHighlightedItemInAX
+;	Parameters:
+;		AX:			Index of highlighted item
+;		DS:SI:		Ptr to MENUINIT struct to initialize
+;		SS:BP:		Ptr to DIALOG
+;	Returns:
+;		DS:SI:		Ptr to initialized MENUINIT struct
+;		CF:			Set since event processed
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_EventInitializeMenuinitFromDSSIforSingleItemWithHighlightedItemInAX:
+	les		di, [bp+DIALOG.fpDialogIO]
+	mov		WORD [es:di+DIALOG_INPUT.fszItems], g_szSingleItem
+	mov		[es:di+DIALOG_INPUT.fszItems+2], cs
+	; Fall to Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX
+
+;--------------------------------------------------------------------
+; Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX
+;	Parameters:
+;		AX:			Index of highlighted item
+;		DS:SI:		Ptr to MENUINIT struct to initialize
+;		SS:BP:		Ptr to DIALOG
+;	Returns:
+;		DS:SI:		Ptr to initialized MENUINIT struct
+;		CF:			Set since event processed
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX:
+	mov		[bp+MENUINIT.wHighlightedItem], ax
+	les		di, [bp+DIALOG.fpDialogIO]
+	call	.GetWidthBasedOnParentMenuToAL
+	mov		[bp+MENUINIT.bWidth], al
+
+	lds		si, [es:di+DIALOG_INPUT.fszTitle]
+	call	ItemLineSplitter_GetLinesToAXforStringInDSSI
+	mov		[bp+MENUINIT.bTitleLines], al
+
+	lds		si, [es:di+DIALOG_INPUT.fszItems]
+	call	ItemLineSplitter_GetLinesToAXforStringInDSSI
+	mov		[bp+MENUINIT.wItems], ax
+
+	lds		si, [es:di+DIALOG_INPUT.fszInfo]
+	call	ItemLineSplitter_GetLinesToAXforStringInDSSI
+	mov		[bp+MENUINIT.bInfoLines], al
+
+	call	.GetHeightToAH				; Line counts are required
+	mov		[bp+MENUINIT.bHeight], ah
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; .GetWidthBasedOnParentMenuToAL
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		AX:		Width for dialog
+;	Corrupts registers:
+;		BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.GetWidthBasedOnParentMenuToAL:
+	mov		bx, [bp+DIALOG.pParentMenu]
+	mov		al, [ss:bx+MENUINIT.bWidth]
+	sub		al, DIALOG_DELTA_WIDTH_FROM_PARENT
+	cmp		al, DIALOG_MAX_WIDTH
+	jb		.ALlessThanDIALOG_MAX_WIDTH
+	mov		al, DIALOG_MAX_WIDTH
+ALIGN JUMP_ALIGN, ret
+.ALlessThanDIALOG_MAX_WIDTH:
+	ret
+
+
+;--------------------------------------------------------------------
+; .GetHeightToAH
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		AH:		Height for dialog
+;	Corrupts registers:
+;		AL, BX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.GetHeightToAH:
+	CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
+	xchg	bx, ax
+	mov		ah, [bp+MENUINIT.bTitleLines]
+	add		ah, [bp+MENUINIT.wItems]
+	add		ah, [bp+MENUINIT.bInfoLines]
+	add		ah, BYTE MENU_VERTICAL_BORDER_LINES
+	cmp		ah, bh
+	jb		.AHlessThanBH
+	xchg	bx, ax
+ALIGN JUMP_ALIGN
+.AHlessThanBH:
+	cmp		ah, DIALOG_MAX_HEIGHT
+	jb		.AHlessThanDIALOG_MAX_HEIGHT
+	mov		ah, DIALOG_MAX_HEIGHT
+ALIGN JUMP_ALIGN, ret
+.AHlessThanDIALOG_MAX_HEIGHT:
+	ret
+
+
+;--------------------------------------------------------------------
+; Dialog_EventRefreshTitle
+; Dialog_EventRefreshInformation
+;	Parameters:
+;		SS:BP:		Ptr to DIALOG
+;	Returns:
+;		CF:			Set since event processed
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_EventRefreshTitle:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	lds		si, [si+DIALOG_INPUT.fszTitle]
+	jmp		SHORT PrintTitleOrInfoLine
+
+ALIGN JUMP_ALIGN
+Dialog_EventRefreshInformation:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	lds		si, [si+DIALOG_INPUT.fszInfo]
+	; Fall to PrintTitleOrInfoLine
+
+ALIGN JUMP_ALIGN
+PrintTitleOrInfoLine:
+	mov		bx, ds
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromBXSI
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; Dialog_EventRefreshItemFromCX
+;	Parameters:
+;		CX:			Item to refresh
+;		SS:BP:		Ptr to DIALOG
+;	Returns:
+;		CF:			Set since event processed
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_EventRefreshItemFromCX:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	lds		si, [si+DIALOG_INPUT.fszItems]
+	call	ItemLineSplitter_GetLineToDSSIandLengthToCXfromStringInDSSIwithIndexInCX
+	jnc		SHORT .LineNotFound
+
+	mov		bx, ds
+	CALL_DISPLAY_LIBRARY PrintCharBufferFromBXSIwithLengthInCX
+.LineNotFound:
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; Dialog_RemoveFromScreenByRedrawingParentMenu
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Dialog_RemoveFromScreenByRedrawingParentMenu:
+	mov		si, [bp+DIALOG.pParentMenu]	; SS:SI points to parent MENU
+	call	.GetParentTitleBorderCoordinatesToDX
+	call	MenuLocation_GetTitleBordersTopLeftCoordinatesToAX
+	cmp		ah, dh		; Dialog taller than parent?
+	jnb		SHORT .RedrawWholeParentWindow
+	; Fall to .RedrawDialogAreaAndWholeParentWindow
+
+;--------------------------------------------------------------------
+; .RedrawDialogAreaAndWholeParentWindow
+; .RedrawWholeParentWindow
+;	Parameters:
+;		SS:SI:	Ptr to parent MENU
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+.RedrawDialogAreaAndWholeParentWindow:
+	push	si
+	call	MenuBorders_AdjustDisplayContextForDrawingBorders
+	pop		si
+	mov		al, SCREEN_BACKGROUND_ATTRIBUTE
+	CALL_DISPLAY_LIBRARY SetCharacterAttributeFromAL
+	mov		ax, [bp+MENUINIT.wWidthAndHeight]
+	CALL_DISPLAY_LIBRARY ClearAreaWithHeightInAHandWidthInAL
+	; Fall to .RedrawWholeParentWindow
+
+ALIGN JUMP_ALIGN
+.RedrawWholeParentWindow:
+	push	bp
+	mov		bp, si
+	call	MenuInit_RefreshMenuWindow
+	pop		bp
+	ret
+
+;--------------------------------------------------------------------
+; .GetParentTitleBorderCoordinatesToDX
+;	Parameters:
+;		SS:SI:	Ptr to parent MENU
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		DL:		Parent border column (X)
+;		DH:		Parent border row (Y)
+;	Corrupts:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.GetParentTitleBorderCoordinatesToDX:
+	xchg	si, bp
+	call	MenuLocation_GetTitleBordersTopLeftCoordinatesToAX
+	xchg	bp, si
+	xchg	dx, ax
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogDrive.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogDrive.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogDrive.asm	(revision 348)
@@ -0,0 +1,127 @@
+; File name		:	DialogDrive.asm
+; Project name	:	Assembly Library
+; Created date	:	22.10.2010
+; Last update	:	18.11.2010
+; Author		:	Tomi Tilli
+; Description	:	Displays drive dialog.
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogDrive_GetDriveWithIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DRIVE_DIALOG_IO
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogDrive_GetDriveWithIoInDSSI:
+	mov		bx, DriveEventHandler
+	mov		BYTE [si+DRIVE_DIALOG_IO.bUserCancellation], TRUE
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; DriveEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DriveEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.InitializeMenuinitFromDSSI:
+	xor		ax, ax
+	call	Dialog_EventInitializeMenuinitFromDSSIforSingleItemWithHighlightedItemInAX
+	call	Drive_GetFlagsForAvailableDrivesToDXAX
+	mov		[bp+MENU.dwUserData], ax
+	mov		[bp+MENU.dwUserData+2], dx
+
+	call	Bit_GetSetCountToCXfromDXAX
+	mov		[bp+MENUINIT.wItems], cx
+
+	dec		cx			; Items initialized to one. Ignore it.
+	add		cl, [bp+MENUINIT.bHeight]
+	CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
+	MIN_U	cl, ah
+	mov		[bp+MENUINIT.bHeight], cl
+	ret
+
+
+ALIGN JUMP_ALIGN
+.ItemSelectedFromCX:
+	call	ConvertDriveLetterToBLfromItemIndexInCX
+	lds		si, [bp+DIALOG.fpDialogIO]
+	mov		BYTE [si+DRIVE_DIALOG_IO.bUserCancellation], FALSE
+	mov		[si+DRIVE_DIALOG_IO.cReturnDriveLetter], bl
+	sub		bl, 'A'
+	mov		[si+DRIVE_DIALOG_IO.bReturnDriveNumber], bl
+	jmp		MenuInit_CloseMenuWindow
+
+
+ALIGN JUMP_ALIGN
+.RefreshItemFromCX:
+	push	bp
+
+	call	ConvertDriveLetterToBLfromItemIndexInCX
+	mov		bp, sp
+	push	bx
+	mov		si, g_szDriveFormat
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+
+	pop		bp
+	stc
+	ret
+
+
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	.InitializeMenuinitFromDSSI
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	.ItemSelectedFromCX
+	at	MENUEVENT.KeyStrokeInAX,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	Dialog_EventRefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	.RefreshItemFromCX
+iend
+
+
+;--------------------------------------------------------------------
+; ConvertDriveLetterToBLfromItemIndexInCX
+;	Parameters:
+;		CX:		Item index
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		BL:		Drive letter
+;	Corrupts registers:
+;		AX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ConvertDriveLetterToBLfromItemIndexInCX:
+	inc		cx			; Index to count
+	mov		bl, 'A'-1
+	mov		ax, [bp+MENU.dwUserData]
+	mov		dx, [bp+MENU.dwUserData+2]
+ALIGN JUMP_ALIGN
+.CheckNextBit:
+	inc		bx			; Increment drive letter
+	shr		dx, 1
+	rcr		ax, 1
+	jnc		SHORT .CheckNextBit
+	loop	.CheckNextBit
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogFile.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogFile.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogFile.asm	(revision 348)
@@ -0,0 +1,765 @@
+; Project name	:	Assembly Library
+; Description	:	Displays file dialog.
+
+
+CURRENTDIR_CHARACTERS	EQU		002Eh
+UPDIR_CHARACTERS		EQU		2E2Eh
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogFile_GetFileNameWithIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to FILE_DIALOG_IO
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogFile_GetFileNameWithIoInDSSI:
+	mov		bx, FileEventHandler
+	mov		BYTE [si+FILE_DIALOG_IO.bUserCancellation], TRUE
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; FileEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FileEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.ItemSelectedFromCX:
+	call	LoadItemStringBufferToESDI
+	call	Registers_CopyESDItoDSSI
+	call	ItemLineSplitter_GetLineToDSSIandLengthToCXfromStringInDSSIwithIndexInCX
+	jmp		ParseSelectionFromItemLineInDSSI
+
+
+ALIGN JUMP_ALIGN
+.RefreshInformation:
+	call	GetInfoLinesToCXandDialogFlagsToAX
+	mov		si, [cs:.rgszInfoStringLookup]
+	xor		bx, bx
+	xchg	dx, ax
+ALIGN JUMP_ALIGN
+.InfoLineLoop:
+	shr		dl, 1
+	jnc		SHORT .CheckNextFlag
+	mov		si, [cs:bx+.rgszInfoStringLookup]
+	push	bx
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	pop		bx
+ALIGN JUMP_ALIGN
+.CheckNextFlag:
+	inc		bx
+	inc		bx
+	loop	.InfoLineLoop
+	stc						; Event processed
+	ret
+
+
+ALIGN JUMP_ALIGN
+.RefreshItemFromCX:
+	call	LoadItemStringBufferToESDI
+	mov		ax, FILE_STRING_LENGTH
+	xchg	ax, cx
+	mul		cx
+	add		di, ax
+	mov		si, di
+	mov		bx, es
+	dec		cx				; Do not print LF at the end of file string
+	CALL_DISPLAY_LIBRARY PrintCharBufferFromBXSIwithLengthInCX
+	stc
+	ret
+
+
+ALIGN WORD_ALIGN
+.rgszInfoStringLookup:
+	dw		g_szChangeDrive
+	dw		g_szSelectDirectory
+	dw		g_szCreateNew
+
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	InitializeMenuinitFromSSBP
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	.ItemSelectedFromCX
+	at	MENUEVENT.KeyStrokeInAX,				dw	HandleFunctionKeyFromAH
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	.RefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	.RefreshItemFromCX
+iend
+
+
+;--------------------------------------------------------------------
+; ReInitializeMenuinitFromSSBP
+; InitializeMenuinitFromSSBP
+;	Parameters:
+;		SS:BP:		Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ReInitializeMenuinitFromSSBP:
+	call	DisplayLoadingMessageInInformationArea
+InitializeMenuinitFromSSBP:
+	call	LoadItemStringBufferToESDI
+	call	CreateStringFromCurrentDirectoryContentsToESDI
+	call	LoadItemStringBufferToESDI
+	call	SortDirectoryContentsStringFromESDIwithCountInCX
+	call	RemoveLastLFandTerminateESDIwithNull
+
+	call	Registers_CopySSBPtoDSSI
+	xor		ax, ax
+	call	Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX
+	call	GetInfoLinesToCXandDialogFlagsToAX
+	mov		[bp+MENUINIT.bInfoLines], cl
+	CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
+	mov		[bp+MENUINIT.bHeight], ah				; Always max height
+	mov		WORD [bp+MENU.wFirstVisibleItem], 0
+	ret
+
+
+;--------------------------------------------------------------------
+; LoadItemStringBufferToESDI
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		ES:DI:	Ptr to item string buffer
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+LoadItemStringBufferToESDI:
+	les		di, [bp+DIALOG.fpDialogIO]
+	les		di, [es:di+FILE_DIALOG_IO.fszItemBuffer]
+	ret
+
+
+;--------------------------------------------------------------------
+; CreateStringFromCurrentDirectoryContentsToESDI
+;	Parameters:
+;		ES:DI:	Buffer where to create item string
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		CX:		Number of files or directories found
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CreateStringFromCurrentDirectoryContentsToESDI:
+	mov		bx, di
+	CALL_DISPLAY_LIBRARY PushDisplayContext
+	mov		cx, -1
+	CALL_DISPLAY_LIBRARY PrepareOffScreenBufferInESBXwithLengthInCX	; ES:DI now points to buffer
+
+	lds		si, [bp+DIALOG.fpDialogIO]
+	eMOVZX	cx, [si+FILE_DIALOG_IO.bFileAttributes]
+	lds		si, [si+FILE_DIALOG_IO.fpFileFilterString]
+	call	Directory_UpdateDTAForFirstMatchForDSSIwithAttributesInCX
+
+	call	.ClearDLifInRootDirectory
+	call	Directory_GetDiskTransferAreaAddressToDSSI
+	xor		cx, cx			; Clear file/directory count
+	call	.FindMatchingFilesAndPrintThemToOffScreenBuffer
+
+	CALL_DISPLAY_LIBRARY PopDisplayContext
+	ret
+
+;--------------------------------------------------------------------
+; .ClearDLifInRootDirectory
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;		ES:DI:	Ptr to destination string buffer
+;	Returns:
+;		DL:		Cleared if in root directory
+;				Set if in any other directory
+;	Corrupts registers:
+;		AX, SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ClearDLifInRootDirectory:
+	call	Registers_CopyESDItoDSSI
+	call	Directory_WriteCurrentPathToDSSI
+	mov		dl, [si]
+	ret
+
+;--------------------------------------------------------------------
+; .FindMatchingFilesAndPrintThemToOffScreenBuffer
+;	Parameters:
+;		CX:		Initial directory count
+;		DL:		Zero if root directory selected
+;		DS:SI:	Ptr to DTA with first matching file
+;	Returns:
+;		CX:		Incremented by number of files/directories found
+;	Corrupts registers:
+;		AX, BX, DX, DI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.FindMatchingFilesAndPrintThemToOffScreenBuffer:
+	call	AppendFileFromDTAinDSSItoOffScreenBuffer
+	call	Directory_UpdateDTAForNextMatchUsingPreviousParameters
+	jnc		SHORT .FindMatchingFilesAndPrintThemToOffScreenBuffer
+	ret
+
+
+;--------------------------------------------------------------------
+; AppendFileFromDTAinDSSItoOffScreenBuffer
+;	Parameters:
+;		CX:		Files/directores found
+;		DL:		Zero if root directory selected
+;		DS:SI:	Ptr to DTA containing file information
+;	Returns:
+;		CX:		Incremented by number of files/directories found
+;	Corrupts registers:
+;		AX, BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AppendFileFromDTAinDSSItoOffScreenBuffer:
+	call	.FilterCurrentDirectory			; We never want "."
+	call	.FilterUpDirectoryWhenInRoot	; No ".." when in root directory
+	inc		cx								; Nothing filtered so increment files/directories
+
+	push	bp
+	push	si
+	push	dx
+	push	cx
+	call	.FormatFileOrDirectoryToBufferFromDTAinDSSI
+	pop		cx
+	pop		dx
+	pop		si
+	pop		bp
+	ret
+
+;--------------------------------------------------------------------
+; .FilterCurrentDirectory
+; .FilterUpDirectoryWhenInRoot
+;	Parameters:
+;		DL:		Zero if root directory selected
+;		DS:SI:	Ptr to DTA containing file information
+;	Returns:
+;		Nothing
+;		Returns from AppendFileToBufferInESDIfromDtaInDSSI when filtering
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.FilterCurrentDirectory:
+	cmp		WORD [si+DTA.szFile], CURRENTDIR_CHARACTERS
+	je		SHORT .DoFilter
+	ret
+
+ALIGN JUMP_ALIGN
+.FilterUpDirectoryWhenInRoot:
+	test	dl, dl			; Set ZF if root directory selected
+	jnz		SHORT .ReturnWithoutFiltering
+	cmp		WORD [si+DTA.szFile], UPDIR_CHARACTERS
+	jne		SHORT .ReturnWithoutFiltering
+.DoFilter:
+	add		sp, BYTE 2		; Remove return address from stack
+ALIGN JUMP_ALIGN, ret
+.ReturnWithoutFiltering:
+	ret
+
+;--------------------------------------------------------------------
+; .FormatFileOrDirectoryToBufferFromDTAinDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DTA containing file information
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI, BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.FormatFileOrDirectoryToBufferFromDTAinDSSI:
+	mov		bp, sp
+	lea		ax, [si+DTA.szFile]
+
+	test	BYTE [si+DTA.bFileAttributes], FLG_FILEATTR_DIRECTORY
+	jnz		SHORT .FormatDirectory
+	; Fall to .FormatFile
+
+;--------------------------------------------------------------------
+; .FormatFile
+;	Parameters:
+;		BP:		SP before pushing formatting parameters
+;		DS:AX:	Far pointer to file name
+;		DS:SI:	Ptr to DTA containing file information
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+.FormatFile:
+	xchg	si, ax
+	call	String_ConvertDSSItoLowerCase
+	xchg	ax, si
+
+	; Push parameters for file name
+	push	ax				; Push file name offset
+	push	ds				; Push file name segment
+
+	; Push parameters for file size
+	mov		ax, [si+DTA.dwFileSize]
+	mov		dx, [si+DTA.dwFileSize+2]
+	xor		bx, bx
+	xor		cx, cx
+	call	Size_GetSizeToAXAndCharToDLfromBXDXAXwithMagnitudeInCX
+	mov		cl, 'i'
+	cmp		dl, ' '
+	eCMOVE	cl, dl
+	push	ax
+	push	dx
+	push	cx
+
+	; Format to buffer
+	mov		si, g_szFileFormat
+	jmp		SHORT .FormatStringInCSSIandReturn
+
+;--------------------------------------------------------------------
+; .FormatDirectory
+;	Parameters:
+;		BP:		SP before pushing formatting parameters
+;		DS:AX:	Far pointer to directory name
+;		DS:SI:	Ptr to DTA containing file information
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.FormatDirectory:
+	push	ax				; Push directory name offset
+	push	ds				; Push directory name segment
+	mov		ax, g_szSub
+	cmp		WORD [si+DTA.szFile], UPDIR_CHARACTERS
+	eCMOVE	ax, g_szUp
+	push	ax
+	mov		si, g_szDirectoryFormat
+ALIGN JUMP_ALIGN
+.FormatStringInCSSIandReturn:
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+
+
+;--------------------------------------------------------------------
+; SortDirectoryContentsStringFromESDIwithCountInCX
+;	Parameters:
+;		CX:		Number of files and directories
+;		ES:DI:	Buffer containing directory contents string
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		ES:DI:	Ptr to end of directory contents string
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SortDirectoryContentsStringFromESDIwithCountInCX:
+	call	Registers_CopyESDItoDSSI
+
+	; Add directory contents string length to DI
+	mov		ax, FILE_STRING_LENGTH
+	push	ax
+	mul		cx
+	add		di, ax
+
+	mov		dx, cx
+	pop		cx
+	mov		bx, .FileStringComparator
+	jmp		Sort_ItemsFromDSSIwithCountInDXsizeInCXandComparatorInBX
+
+;--------------------------------------------------------------------
+; .FileStringComparator
+;	Parameters:
+;		CX:		Item size in bytes
+;		DS:SI:	Ptr to first item to compare
+;		ES:DI:	Ptr to second item to compare
+;	Returns:
+;		FLAGS:	Signed comparison between first and second item
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.FileStringComparator:
+	push	di
+	push	si
+	push	cx
+	push	bx
+
+	mov		bx, FILE_STRING_LENGTH-2			; Zero BH
+	cmp		WORD [si], UPDIR_CHARACTERS
+	je		SHORT .ForceValueFromDSSItoBeLess
+	mov		bl, [si+bx]
+	cmp		bl, [es:di+FILE_STRING_LENGTH-2]	; 'B' for files, 'R' for directories
+	jne		SHORT .ForceValueFromDSSItoBeMoreOrLess
+	repe cmpsb									; Two directories or two files
+
+ALIGN JUMP_ALIGN
+.ReturnFromComparison:
+	pop		bx
+	pop		cx
+	pop		si
+	pop		di
+	ret
+ALIGN JUMP_ALIGN
+.ForceValueFromDSSItoBeMoreOrLess:
+	ja		SHORT .ForceValueFromDSSItoBeLess	; Directory in SI, file in DI
+	xchg	bl, bh
+	; Fall to ForceValueFromDSSItoBeLess
+ALIGN JUMP_ALIGN
+.ForceValueFromDSSItoBeLess:
+	cmp		bh, bl
+	jmp		SHORT .ReturnFromComparison
+
+
+;--------------------------------------------------------------------
+; RemoveLastLFandTerminateESDIwithNull
+;	Parameters:
+;		ES:DI:	Ptr to end of buffer to terminate
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RemoveLastLFandTerminateESDIwithNull:
+	dec		di
+	xor		ax, ax
+	stosb
+	ret
+
+
+;--------------------------------------------------------------------
+; GetInfoLinesToCXandDialogFlagsToAX
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		AX:		Dialog flags
+;		CX:		Number of info lines to be displayed
+;	Corrupts registers:
+;		SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetInfoLinesToCXandDialogFlagsToAX:
+	xor		ax, ax
+	call	GetDialogFlagsToAL
+	jmp		Bit_GetSetCountToCXfromAX
+
+;--------------------------------------------------------------------
+; GetDialogFlagsToAL
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		AL:		Dialog flags
+;	Corrupts registers:
+;		SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetDialogFlagsToAL:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	mov		al, [si+FILE_DIALOG_IO.bDialogFlags]
+	ret
+
+
+;--------------------------------------------------------------------
+; ParseSelectionFromItemLineInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to char buffer containing file or directory to be selected
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ParseSelectionFromItemLineInDSSI:
+	mov		ax, [si]
+	cmp		ax, UPDIR_CHARACTERS
+	je		SHORT .ChangeToUpdir
+	call	Char_IsUpperCaseLetterInAL
+	jc		SHORT .ParseAndChangeToSubdirInDSSI
+	call	Char_IsDecimalDigitInAL
+	jc		SHORT .ParseAndChangeToSubdirInDSSI	; Assume subdir and check for errors
+	; Fall to .ParseAndSelectFileFromDSSI
+
+;--------------------------------------------------------------------
+; .ParseAndSelectFileFromDSSI
+;	Parameters:
+;		DS:SI:	NULL terminated string selected from dialog
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing (exits dialog)
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+.ParseAndSelectFileFromDSSI:
+	les		di, [bp+DIALOG.fpDialogIO]
+	add		di, BYTE FILE_DIALOG_IO.szFile
+	mov		cx, FILENAME_BUFFER_SIZE-1
+	call	Memory_CopyCXbytesFromDSSItoESDI
+	xor		ax, ax
+	stosb						; Terminate with NULL
+	jmp		SHORT CloseFileDialogAfterSuccessfulSelection
+
+;--------------------------------------------------------------------
+; .ChangeToUpdir
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ChangeToUpdir:
+	push	cs
+	pop		ds
+	mov		si, g_szUpdir
+	jmp		SHORT .ChangeDirectoryToDSSI
+
+;--------------------------------------------------------------------
+; .ParseAndChangeToSubdirInDSSI
+;	Parameters:
+;		DS:SI:	NULL terminated string selected from dialog
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ParseAndChangeToSubdirInDSSI:
+	mov		BYTE [si+12], NULL	; Terminate with NULL (unnecessary spaces do not matter)
+.ChangeDirectoryToDSSI:
+	call	Directory_ChangeToPathFromDSSI
+	jc		SHORT .ParseAndSelectFileFromDSSI	; Must have been a file starting with number
+	; Fall to RefreshFilesToDisplay
+
+;--------------------------------------------------------------------
+; RefreshFilesToDisplay
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RefreshFilesToDisplay:
+	call	ReInitializeMenuinitFromSSBP
+	jmp		MenuInit_RefreshMenuWindow
+
+
+;--------------------------------------------------------------------
+; HandleFunctionKeyFromAH
+;	Parameters:
+;		AH:		Scancode for function key
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI, BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HandleFunctionKeyFromAH:
+	call	GetDialogFlagsToAL
+	cmp		ah, KEY_FILEDIALOG_NEW_FILE_OR_DIR
+	je		SHORT HandleFunctionKeyForCreatingNewFileOrDirectory
+	cmp		ah, KEY_FILEDIALOG_SELECT_DIRECTORY
+	je		SHORT HandleFunctionKeyForSelectingDirectoryInsteadOfFile
+	cmp		ah, KEY_FILEDIALOG_CHANGE_DRIVE
+	je		SHORT HandleFunctionKeyForDriveChange
+ReturnWithoutHandlingKeystroke:
+	clc		; Event not processed
+	ret
+
+
+;--------------------------------------------------------------------
+; HandleFunctionKeyForCreatingNewFileOrDirectory
+;	Parameters:
+;		AL:		File dialog flags
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Closes file dialog
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HandleFunctionKeyForCreatingNewFileOrDirectory:
+	test	al, FLG_FILEDIALOG_NEW
+	jz		SHORT ReturnWithoutHandlingKeystroke
+
+	mov		cx, STRING_DIALOG_IO_size
+	call	Memory_ReserveCXbytesFromStackToDSSI
+	call	.InitializeStringDialogIoInDSSIforInputtingFileName
+
+	CALL_MENU_LIBRARY GetStringWithIoInDSSI
+	mov		al, [si+STRING_DIALOG_IO.bUserCancellation]
+	add		sp, BYTE STRING_DIALOG_IO_size
+	test	al, al		; User cancellation?
+	jnz		SHORT ReturnWithoutHandlingKeystroke
+	jmp		CloseFileDialogAfterSuccessfulSelection
+
+ALIGN JUMP_ALIGN
+.InitializeStringDialogIoInDSSIforInputtingFileName:
+	call	InitializeNullStringsToDialogInputInDSSI
+	mov		WORD [si+DIALOG_INPUT.fszTitle], g_szEnterNewFileOrDirectory
+	mov		WORD [si+STRING_DIALOG_IO.fnCharFilter], NULL
+	mov		WORD [si+STRING_DIALOG_IO.wBufferSize], FILENAME_BUFFER_SIZE
+	les		ax, [bp+DIALOG.fpDialogIO]
+	add		ax, BYTE FILE_DIALOG_IO.szFile
+	mov		[si+STRING_DIALOG_IO.fpReturnBuffer], ax
+	mov		[si+STRING_DIALOG_IO.fpReturnBuffer+2], es
+	ret
+
+
+;--------------------------------------------------------------------
+; HandleFunctionKeyForSelectingDirectoryInsteadOfFile
+;	Parameters:
+;		AL:		File dialog flags
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Closes file dialog
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HandleFunctionKeyForSelectingDirectoryInsteadOfFile:
+	test	al, FLG_FILEDIALOG_DIRECTORY
+	jz		SHORT ReturnWithoutHandlingKeystroke
+	; Fall to CloseFileDialogAfterSuccessfulSelection
+
+;--------------------------------------------------------------------
+; CloseFileDialogAfterSuccessfulSelection
+;	Parameters:
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing (exits dialog)
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CloseFileDialogAfterSuccessfulSelection:
+	lds		di, [bp+DIALOG.fpDialogIO]
+	mov		BYTE [di+FILE_DIALOG_IO.bUserCancellation], FALSE
+	jmp		MenuInit_CloseMenuWindow
+
+
+;--------------------------------------------------------------------
+; HandleFunctionKeyForDriveChange
+;	Parameters:
+;		AL:		File dialog flags
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HandleFunctionKeyForDriveChange:
+	test	al, FLG_FILEDIALOG_DRIVES
+	jz		SHORT ReturnWithoutHandlingKeystroke
+
+	call	DisplayLoadingMessageInInformationArea
+	mov		cx, DRIVE_DIALOG_IO_size
+	call	Memory_ReserveCXbytesFromStackToDSSI
+	call	.DisplayDriveSelectionDialogWithIoInDSSI
+	call	.ChangeDriveToUserSelectionFromIoInDSSI
+	add		sp, BYTE DRIVE_DIALOG_IO_size
+	ret
+
+;--------------------------------------------------------------------
+; .DisplayDriveSelectionDialogWithIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to uninitialized DRIVE_DIALOG_IO
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		DS:SI:	Ptr to DRIVE_DIALOG_IO
+;	Corrupts registers:
+;		AX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.DisplayDriveSelectionDialogWithIoInDSSI:
+	call	InitializeNullStringsToDialogInputInDSSI
+	mov		WORD [si+DIALOG_INPUT.fszTitle], g_szSelectNewDrive
+	CALL_MENU_LIBRARY GetDriveWithIoInDSSI
+	ret
+
+;--------------------------------------------------------------------
+; .ChangeDriveToUserSelectionFromIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DRIVE_DIALOG_IO
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ChangeDriveToUserSelectionFromIoInDSSI:
+	cmp		BYTE [si+DRIVE_DIALOG_IO.bUserCancellation], FALSE
+	jne		SHORT .UserCancelledDriveChange
+
+	mov		dl, [si+DRIVE_DIALOG_IO.bReturnDriveNumber]
+	call	Drive_SetDefaultFromDL
+	jmp		RefreshFilesToDisplay
+.UserCancelledDriveChange:
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayLoadingMessageInInformationArea
+;	Parameters:
+;		SS:BP:		Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayLoadingMessageInInformationArea:
+	call	MenuText_ClearInformationArea
+	call	MenuText_PrepareToDrawInformationArea
+	mov		si, g_szLoadingPleaseWait
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	ret
+
+
+;--------------------------------------------------------------------
+; InitializeNullStringsToDialogInputInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DIALOG_INPUT
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+InitializeNullStringsToDialogInputInDSSI:
+	mov		ax, g_szNull
+	mov		[si+DIALOG_INPUT.fszTitle], ax
+	mov		[si+DIALOG_INPUT.fszTitle+2], cs
+	mov		[si+DIALOG_INPUT.fszItems], ax
+	mov		[si+DIALOG_INPUT.fszItems+2], cs
+	mov		[si+DIALOG_INPUT.fszInfo], ax
+	mov		[si+DIALOG_INPUT.fszInfo+2], cs
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogMessage.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogMessage.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogMessage.asm	(revision 348)
@@ -0,0 +1,115 @@
+; File name		:	DialogMessage.asm
+; Project name	:	Assembly Library
+; Created date	:	6.8.2010
+; Last update	:	18.11.2010
+; Author		:	Tomi Tilli
+; Description	:	Displays message dialog.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogMessage_DisplayMessageWithInputInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DIALOG_INPUT
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogMessage_DisplayMessageWithInputInDSSI:
+	mov		bx, MessageEventHandler
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; MessageEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MessageEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.InitializeMenuinitFromDSSI:
+	or		BYTE [bp+MENU.bFlags], FLG_MENU_USER_HANDLES_SCROLLING | FLG_MENU_NOHIGHLIGHT
+	xor		ax, ax		; Cannot be NO_ITEM_HIGHLIGHTED because of scrolling
+	jmp		Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX
+
+
+ALIGN JUMP_ALIGN
+.KeyStrokeInAX:
+	call	ProcessMessageScrollingKeysFromAX
+	stc
+	ret
+
+
+ALIGN WORD_ALIGN
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	.InitializeMenuinitFromDSSI
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	Dialog_EventAnyThatClosesDialog
+	at	MENUEVENT.KeyStrokeInAX,				dw	.KeyStrokeInAX
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	Dialog_EventRefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	Dialog_EventRefreshItemFromCX
+iend
+
+
+;--------------------------------------------------------------------
+; ProcessMessageScrollingKeysFromAX
+;	Parameters
+;		AL:		ASCII character
+;		AH:		BIOS scan code
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ProcessMessageScrollingKeysFromAX:
+	cmp		ah, MENU_KEY_UP
+	je		SHORT .DecrementLines
+	cmp		ah, MENU_KEY_DOWN
+	je		SHORT .IncrementLines
+	jmp		MenuLoop_ProcessScrollingKeysFromAX
+
+ALIGN JUMP_ALIGN
+.DecrementLines:
+	cmp		WORD [bp+MENUINIT.wHighlightedItem], BYTE 0
+	je		SHORT .AlreadyAtTheTopOrBottom
+
+	mov		ax, [bp+MENU.wFirstVisibleItem]
+	mov		[bp+MENUINIT.wHighlightedItem], ax
+	mov		ah, MENU_KEY_UP
+	jmp		MenuLoop_ProcessScrollingKeysFromAX
+
+ALIGN JUMP_ALIGN
+.IncrementLines:
+	mov		ax, [bp+MENUINIT.wItems]
+	dec		ax						; Last possible item to highlight
+	cmp		[bp+MENUINIT.wHighlightedItem], ax
+	jae		SHORT .AlreadyAtTheTopOrBottom
+
+	call	MenuScrollbars_GetLastVisibleItemOnPageToAX
+	mov		[bp+MENUINIT.wHighlightedItem], ax
+	mov		ah, MENU_KEY_DOWN
+	jmp		MenuLoop_ProcessScrollingKeysFromAX
+
+ALIGN JUMP_ALIGN
+.AlreadyAtTheTopOrBottom:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogProgress.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogProgress.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogProgress.asm	(revision 348)
@@ -0,0 +1,301 @@
+; Project name	:	Assembly Library
+; Description	:	Displays progress bar dialog and starts progress task.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogProgress_GetStringWithIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to PROGRESS_DIALOG_IO
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogProgress_StartProgressTaskWithIoInDSSIandParamInDXAX:
+	mov		bx, ProgressEventHandler
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; DialogProgress_SetProgressValueFromAX
+;	Parameters
+;		AX:		Progress bar value to set
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogProgress_SetProgressValueFromAX:
+	push	ds
+
+	lds		si, [bp+DIALOG.fpDialogIO]
+	mov		bx, [si+PROGRESS_DIALOG_IO.wMaxProgressValue]
+	cmp		ax, bx
+	jb		SHORT .AXlessThanBX
+	mov		ax, bx
+	jmp		SHORT .UpdateProgressBar
+ALIGN JUMP_ALIGN
+.AXlessThanBX:
+	mov		bx, ax
+	sub		bx, [si+PROGRESS_DIALOG_IO.wCurrentProgressValue]
+	cmp		bx, [si+PROGRESS_DIALOG_IO.wProgressPerCharacter]
+	jb		SHORT .ReturnWithoutUpdate
+.UpdateProgressBar:
+	mov		[si+PROGRESS_DIALOG_IO.wCurrentProgressValue], ax
+	xor		ax, ax
+	call	MenuText_RefreshItemFromAX
+	call	MenuText_RefreshInformation
+ALIGN JUMP_ALIGN
+.ReturnWithoutUpdate:
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; ProgressEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ProgressEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.InitializeMenuinitFromDSSI:
+	mov		ax, NO_ITEM_HIGHLIGHTED
+	call	Dialog_EventInitializeMenuinitFromDSSIforSingleItemWithHighlightedItemInAX
+	lds		si, [bp+DIALOG.fpDialogIO]
+	call	TimerTicks_ReadFromBdaToAX
+	mov		[si+PROGRESS_DIALOG_IO.wStartTimeTicks], ax
+
+	; 0 = 65536 but it needs to be adjusted to 65535 prevent division by zero
+	cmp		WORD [si+PROGRESS_DIALOG_IO.wMaxProgressValue], BYTE 0
+	jne		SHORT CalculateProgressNeededBeforeUpdatingCharacter
+	dec		WORD [si+PROGRESS_DIALOG_IO.wMaxProgressValue]
+	jmp		SHORT CalculateProgressNeededBeforeUpdatingCharacter
+
+
+ALIGN JUMP_ALIGN
+.IdleProcessing:
+	call	MenuInit_GetUserDataToDSSI
+	les		di, [bp+DIALOG.fpDialogIO]
+	push	bp
+	call	[es:di+PROGRESS_DIALOG_IO.fnTaskWithParamInDSSI]
+	pop		bp
+	call	MenuInit_CloseMenuWindow
+	stc
+	ret
+
+
+ALIGN JUMP_ALIGN
+.RefreshItemFromCX:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	call	DrawProgressBarFromDialogIoInDSSI
+	stc
+	ret
+
+
+ALIGN JUMP_ALIGN
+.RefreshInformation:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	call	TimerTicks_ReadFromBdaToAX
+	sub		ax, [si+PROGRESS_DIALOG_IO.wStartTimeTicks]
+	xchg	dx, ax
+	call	DrawTimeElapsedFromDX
+	call	DrawTimeLeftFromProgressDialogIoInDSSIwithTimeElapsedInDX
+	stc
+	ret
+
+
+ALIGN WORD_ALIGN
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	.InitializeMenuinitFromDSSI
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	.IdleProcessing
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	Dialog_EventNotHandled
+	at	MENUEVENT.KeyStrokeInAX,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	.RefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	.RefreshItemFromCX
+iend
+
+
+;--------------------------------------------------------------------
+; CalculateProgressNeededBeforeUpdatingCharacter
+;	Parameters:
+;		DS:SI:	Ptr to PROGRESS_DIALOG_IO
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		CF:		Set since event handled
+;	Corrupts:
+;		AX, BX, DX, SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CalculateProgressNeededBeforeUpdatingCharacter:
+	call	MenuLocation_GetMaxTextLineLengthToAX
+	call	GetProgressLengthToBXfromProgressDialogIoInDSSI
+	xchg	ax, bx
+	xor		dx, dx
+	div		bx
+	mov		[si+PROGRESS_DIALOG_IO.wProgressPerCharacter], ax
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; DrawProgressBarFromDialogIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to PROGRESS_DIALOG_IO
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, BX, CX, DX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DrawProgressBarFromDialogIoInDSSI:
+	; Get full chars to CX and empty chars to DX
+	call	MenuLocation_GetMaxTextLineLengthToAX
+	mov		cx, ax
+	mul		WORD [si+PROGRESS_DIALOG_IO.wCurrentProgressValue]
+	call	GetProgressLengthToBXfromProgressDialogIoInDSSI
+	div		bx
+	xchg	cx, ax		; AX = Text line length, CX = Number of full chars
+	sub		ax, cx
+	xchg	dx, ax		; DX = Number of empty chars
+
+	mov		al, PROGRESS_COMPLETE_CHARACTER
+	call	.RepeatProgressCharacterCXtimesFromAL
+
+	mov		cx, dx
+	mov		al, PROGRESS_INCOMPLETE_CHARACTER
+	; Fall to .RepeatProgressCharacterCXtimesFromAL
+
+;--------------------------------------------------------------------
+; .RepeatProgressCharacterCXtimesFromAL
+;	Parameters:
+;		AL:		Progress bar character to repeat
+;		CX:		Number of times to repeat the progress character
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, CX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.RepeatProgressCharacterCXtimesFromAL:
+	jcxz	.NothingToRepeat
+	CALL_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
+ALIGN JUMP_ALIGN, ret
+.NothingToRepeat:
+	ret
+
+
+;--------------------------------------------------------------------
+; GetProgressLengthToBXfromProgressDialogIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to PROGRESS_DIALOG_IO
+;	Returns:
+;		BX:		Progress length
+;	Corrupts:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetProgressLengthToBXfromProgressDialogIoInDSSI:
+	mov		bx, [si+PROGRESS_DIALOG_IO.wMaxProgressValue]
+	sub		bx, [si+PROGRESS_DIALOG_IO.wMinProgressValue]
+	ret
+
+
+;--------------------------------------------------------------------
+; DrawTimeElapsedFromDX
+;	Parameters:
+;		DX:		Ticks elapsed
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, BX, CX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DrawTimeElapsedFromDX:
+	push	si
+	push	dx
+
+	mov		si, g_szTimeElapsed
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	call	FormatTicksFromDX
+
+	pop		dx
+	pop		si
+	ret
+
+
+;--------------------------------------------------------------------
+; DrawTimeLeftFromProgressDialogIoInDSSIwithTimeElapsedInDX
+;	Parameters:
+;		DX:		Ticks elapsed
+;		DS:SI:	Ptr to PROGRESS_DIALOG_IO
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DrawTimeLeftFromProgressDialogIoInDSSIwithTimeElapsedInDX:
+	push	si
+	mov		si, g_szTimeLeft
+	CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
+	pop		si
+
+	mov		cx, [si+PROGRESS_DIALOG_IO.wCurrentProgressValue]
+	mov		ax, [si+PROGRESS_DIALOG_IO.wMaxProgressValue]
+	sub		ax, cx
+	mul		dx			; Progress left * elapsed time
+
+	sub		cx, [si+PROGRESS_DIALOG_IO.wMinProgressValue]
+	jz		SHORT .PreventDivisionByZero
+	div		cx			; AX = Estimated ticks left
+	xchg	dx, ax
+	SKIP2B	f	; cmp ax, <next instruction>
+.PreventDivisionByZero:
+	xor		dx, dx
+	; Fall to FormatTicksFromDX
+
+
+;--------------------------------------------------------------------
+; FormatTicksFromDX
+;	Parameters:
+;		DX:		Ticks to format
+;	Returns:
+;		Nothing
+;	Corrupts:
+;		AX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+FormatTicksFromDX:
+	push	bp
+
+	mov		bp, sp
+	mov		si, g_szTimeFormat
+	call	TimerTicks_GetMinutesToAXfromTicksInDX
+	push	ax
+	call	TimerTicks_GetSecondsToAXfromTicksInDX
+	push	ax
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+
+	pop		bp
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogSelection.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogSelection.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogSelection.asm	(revision 348)
@@ -0,0 +1,61 @@
+; File name		:	DialogSelection.asm
+; Project name	:	Assembly Library
+; Created date	:	13.8.2010
+; Last update	:	18.11.2010
+; Author		:	Tomi Tilli
+; Description	:	Displays selection dialog.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogSelection_GetSelectionToAXwithInputInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to DIALOG_INPUT
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogSelection_GetSelectionToAXwithInputInDSSI:
+	mov		bx, SelectionEventHandler
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; SelectionEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SelectionEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.InitializeMenuinitFromDSSI:
+	xor		ax, ax
+	jmp		Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX
+
+
+ALIGN WORD_ALIGN
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	.InitializeMenuinitFromDSSI
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	Dialog_EventAnyThatClosesDialog
+	at	MENUEVENT.KeyStrokeInAX,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	Dialog_EventRefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	Dialog_EventRefreshItemFromCX
+iend
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogString.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogString.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogString.asm	(revision 348)
@@ -0,0 +1,117 @@
+; File name		:	DialogString.asm
+; Project name	:	Assembly Library
+; Created date	:	12.8.2010
+; Last update	:	18.11.2010
+; Author		:	Tomi Tilli
+; Description	:	Displays word input dialog.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogString_GetStringWithIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to STRING_DIALOG_IO
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogString_GetStringWithIoInDSSI:
+	mov		bx, StringEventHandler
+	mov		BYTE [si+STRING_DIALOG_IO.bUserCancellation], TRUE
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; StringEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+StringEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.InitializeMenuinitFromDSSI:
+	xor		ax, ax
+	jmp		Dialog_EventInitializeMenuinitFromDSSIforSingleItemWithHighlightedItemInAX
+
+
+ALIGN JUMP_ALIGN
+.IdleProcessing:
+	xor		cx, cx						; Item 0 is used as input line
+	call	MenuText_AdjustDisplayContextForDrawingItemFromCX
+	call	GetStringFromUser
+	call	MenuInit_CloseMenuWindow
+	stc
+	ret
+
+
+ALIGN WORD_ALIGN
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	.InitializeMenuinitFromDSSI
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	.IdleProcessing
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	Dialog_EventNotHandled
+	at	MENUEVENT.KeyStrokeInAX,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	Dialog_EventRefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	Dialog_EventNotHandled
+iend
+
+
+;--------------------------------------------------------------------
+; GetStringFromUser
+;	Parameters
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing (User input stored to STRING_DIALOG_IO)
+;	Corrupts registers:
+;		AX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetStringFromUser:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	mov		cx, [si+STRING_DIALOG_IO.wBufferSize]
+	les		di, [si+STRING_DIALOG_IO.fpReturnBuffer]
+	call	.GetCharacterFilterFunctionToDX
+
+	call	Keyboard_ReadUserInputtedStringToESDIWhilePrinting
+	jz		SHORT .UserCancellation
+
+	mov		BYTE [si+STRING_DIALOG_IO.bUserCancellation], FALSE
+	mov		[si+STRING_DIALOG_IO.wReturnLength], cx
+.UserCancellation:
+	ret
+
+;--------------------------------------------------------------------
+; .GetCharacterFilterFunctionToDX
+;	Parameters
+;		DS:SI:	Ptr to STRING_DIALOG_IO
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		CS:DX:	Ptr to character filter function
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.GetCharacterFilterFunctionToDX:
+	mov		dx, [si+STRING_DIALOG_IO.fnCharFilter]
+	test	dx, dx
+	jnz		SHORT .ReturnFilterFunctionInDX
+	mov		dx, Char_CharIsValid
+ALIGN JUMP_ALIGN, ret
+.ReturnFilterFunctionInDX:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogWord.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogWord.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/DialogWord.asm	(revision 348)
@@ -0,0 +1,128 @@
+; File name		:	DialogWord.asm
+; Project name	:	Assembly Library
+; Created date	:	10.8.2010
+; Last update	:	18.11.2010
+; Author		:	Tomi Tilli
+; Description	:	Displays word input dialog.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; DialogWord_GetWordWithIoInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to WORD_DIALOG_IO
+;		SS:BP:	Ptr to parent MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DialogWord_GetWordWithIoInDSSI:
+	mov		bx, WordEventHandler
+	mov		BYTE [si+WORD_DIALOG_IO.bUserCancellation], TRUE
+	jmp		Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
+
+
+;--------------------------------------------------------------------
+; WordEventHandler
+;	Common parameters for all events:
+;		BX:			Menu event (anything from MENUEVENT struct)
+;		SS:BP:		Ptr to DIALOG
+;	Common return values for all events:
+;		CF:			Set if event processed
+;					Cleared if event not processed
+;	Corrupts registers:
+;		All
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+WordEventHandler:
+	jmp		[cs:bx+.rgfnEventHandlers]
+
+
+ALIGN JUMP_ALIGN
+.InitializeMenuinitFromDSSI:
+	xor		ax, ax
+	jmp		Dialog_EventInitializeMenuinitFromDSSIforSingleItemWithHighlightedItemInAX
+
+
+ALIGN JUMP_ALIGN
+.IdleProcessing:
+	xor		cx, cx						; Item 0 is used as input line
+	call	MenuText_AdjustDisplayContextForDrawingItemFromCX
+	call	GetWordFromUser
+	call	MenuInit_CloseMenuWindow
+	stc
+	ret
+
+
+ALIGN WORD_ALIGN
+.rgfnEventHandlers:
+istruc MENUEVENT
+	at	MENUEVENT.InitializeMenuinitFromDSSI,	dw	.InitializeMenuinitFromDSSI
+	at	MENUEVENT.ExitMenu,						dw	Dialog_EventExitMenu
+	at	MENUEVENT.IdleProcessing,				dw	.IdleProcessing
+	at	MENUEVENT.ItemHighlightedFromCX,		dw	Dialog_EventNotHandled
+	at	MENUEVENT.ItemSelectedFromCX,			dw	Dialog_EventNotHandled
+	at	MENUEVENT.KeyStrokeInAX,				dw	Dialog_EventNotHandled
+	at	MENUEVENT.RefreshTitle,					dw	Dialog_EventRefreshTitle
+	at	MENUEVENT.RefreshInformation,			dw	Dialog_EventRefreshInformation
+	at	MENUEVENT.RefreshItemFromCX,			dw	Dialog_EventNotHandled
+iend
+
+
+;--------------------------------------------------------------------
+; GetWordFromUser
+;	Parameters
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing (User input stored to WORD_DIALOG_IO)
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetWordFromUser:
+	lds		si, [bp+DIALOG.fpDialogIO]
+	eMOVZX	bx, [si+WORD_DIALOG_IO.bNumericBase]
+ALIGN JUMP_ALIGN
+.GetUserInputIntilValidOrCancelled:
+	call	Keyboard_ReadUserInputtedWordWhilePrinting
+	jz		SHORT .UserCancellation
+
+	cmp		ax, [si+WORD_DIALOG_IO.wMin]
+	jb		SHORT .InputtedWordNotInRange
+	cmp		ax, [si+WORD_DIALOG_IO.wMax]
+	ja		SHORT .InputtedWordNotInRange
+
+	mov		[si+WORD_DIALOG_IO.bUserCancellation], bh	; Zero = FALSE
+	mov		[si+WORD_DIALOG_IO.wReturnWord], ax
+.UserCancellation:
+	ret
+
+.InputtedWordNotInRange:
+	call	Keyboard_PlayBellForUnwantedKeystroke
+	call	.ClearInputtedWordFromDialog
+	jmp		SHORT .GetUserInputIntilValidOrCancelled
+
+;--------------------------------------------------------------------
+; .ClearInputtedWordFromDialog
+;	Parameters
+;		SS:BP:	Ptr to DIALOG
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX, DX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ClearInputtedWordFromDialog:
+	CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
+	xchg	dx, ax
+
+	mov		al, ' '
+	mov		cx, 5
+	CALL_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
+
+	xchg	ax, dx
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/ItemLineSplitter.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/ItemLineSplitter.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/ItemLineSplitter.asm	(revision 348)
@@ -0,0 +1,143 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for splitting strings to item lines.
+
+struc ITEM_LINE_SPLITTER
+	.wMaxTextLineLength	resb	2
+	.wLineToFind		resb	2
+	.wStartOfLine		resb	2
+endstruc
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; ItemLineSplitter_GetLinesToAXforStringInDSSI
+;	Parameters:
+;		DS:SI:	Ptr to string
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Number of lines on string
+;	Corrupts registers:
+;		BX, CX, DX, SI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ItemLineSplitter_GetLinesToAXforStringInDSSI:
+	push	di
+
+	call	MenuLocation_GetMaxTextLineLengthToAX
+	eENTER_STRUCT	ITEM_LINE_SPLITTER_size
+	mov		[bp+ITEM_LINE_SPLITTER.wMaxTextLineLength], ax
+	mov		WORD [bp+ITEM_LINE_SPLITTER.wLineToFind], -1
+
+	xor		bx, bx		; Line index
+	mov		di, si		; Start of first word
+	mov		dx, ProcessCharacterFromStringToSplit
+	call	StringProcess_DSSIwithFunctionInDX
+
+	lea		ax, [bx+1]
+	eLEAVE_STRUCT	ITEM_LINE_SPLITTER_size
+	pop		di
+	ret
+
+
+;--------------------------------------------------------------------
+; ItemLineSplitter_GetLineToDSSIandLengthToCXfromStringInDSSIwithIndexInCX
+;	Parameters:
+;		CX:		Index of line to search for
+;		DS:SI:	Ptr to string
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CX:		Line length
+;		DS:SI:	Ptr to beginning of line
+;		CF:		Set if wanted line was found
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ItemLineSplitter_GetLineToDSSIandLengthToCXfromStringInDSSIwithIndexInCX:
+	push	di
+
+	call	MenuLocation_GetMaxTextLineLengthToAX
+	eENTER_STRUCT	ITEM_LINE_SPLITTER_size
+	mov		[bp+ITEM_LINE_SPLITTER.wMaxTextLineLength], ax
+	mov		[bp+ITEM_LINE_SPLITTER.wLineToFind], cx
+	mov		[bp+ITEM_LINE_SPLITTER.wStartOfLine], si
+
+	xor		bx, bx		; Line index
+	mov		di, si		; Start of first word
+	mov		dx, ProcessCharacterFromStringToSplit
+	call	StringProcess_DSSIwithFunctionInDX
+
+	mov		si, [bp+ITEM_LINE_SPLITTER.wStartOfLine]
+	jc		SHORT .ReturnLineInDSSIandLengthInCX
+	call	String_GetLengthFromDSSItoCX	; Last or invalid line. Just return last line.
+
+ALIGN JUMP_ALIGN
+.ReturnLineInDSSIandLengthInCX:
+	eLEAVE_STRUCT	ITEM_LINE_SPLITTER_size
+	pop		di
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; Character processing callback function prototype for StringProcess_DSSIwithFunctionInBX.
+; ProcessCharacterFromStringToSplit
+;	Parameters:
+;		AL:			Character to process
+;		BX:			Line index
+;		CX:			Number of characters processed (Characters on line so far)
+;		DS:SI:		Ptr to next character
+;		DS:DI:		Start of current word
+;		SS:BP:		Ptr to ITEM_LINE_SPLITTER
+;	Returns:
+;		CF:			Clear to continue with next character
+;					Set to stop processing
+;		BX:			Line index
+;		CX:			Characters on line so far
+;		DS:DI:		Start of current word
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ProcessCharacterFromStringToSplit:
+	cmp		al, ' '
+	ja		SHORT .CheckLineLength
+	mov		di, si				; DS:DI now points start of new word
+	je		SHORT .CheckLineLength
+
+	cmp		al, LF
+	je		SHORT .ChangeToNextLine
+	cmp		al, CR
+	jne		SHORT .IgnoreUnsupportedControlCharacter
+	xor		cx, cx				; Carriage return so reset line length so far
+
+ALIGN JUMP_ALIGN
+.CheckLineLength:
+	cmp		[bp+ITEM_LINE_SPLITTER.wMaxTextLineLength], cx
+	jb		SHORT .ChangeToNextLine
+	ret		; With CF cleared
+
+ALIGN JUMP_ALIGN
+.ChangeToNextLine:
+	cmp		bx, [bp+ITEM_LINE_SPLITTER.wLineToFind]
+	je		SHORT .WantedLineFound
+
+	inc		bx					; Increment line
+	xor		cx, cx				; Zero character counter (and clear CF)
+	mov		si, di				; Start from complete word
+	mov		[bp+ITEM_LINE_SPLITTER.wStartOfLine], di
+	ret
+
+ALIGN JUMP_ALIGN
+.IgnoreUnsupportedControlCharacter:
+	dec		cx
+	clc
+	ret
+
+ALIGN JUMP_ALIGN
+.WantedLineFound:
+	lea		cx, [di-1]
+	sub		cx, [bp+ITEM_LINE_SPLITTER.wStartOfLine]
+	stc
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/StringsForDialogs.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/StringsForDialogs.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Dialog/StringsForDialogs.asm	(revision 348)
@@ -0,0 +1,43 @@
+; File name		:	StringsForDialogs.asm
+; Project name	:	Assembly Library
+; Created date	:	14.9.2010
+; Last update	:	23.10.2010
+; Author		:	Tomi Tilli
+; Description	:	Strings used by dialogs.
+
+; Strings for Progress Dialog
+g_szTimeElapsed:		db	"Time elapsed  :",NULL
+g_szTimeLeft:			db	"Estimated left:",NULL
+g_szTimeFormat:			db	" %2-u min %2-u sec",LF,CR,NULL
+
+; Strings for Drive Dialog
+g_szDriveFormat:		db	"%c:",NULL
+
+; Strings for File Dialog
+g_szChangeDrive:		db	"F2 Change Drive",LF,CR,NULL
+g_szSelectDirectory:	db	"F3 Select Current Directory",LF,CR,NULL
+g_szCreateNew:			db	"F4 Input new File or Directory",NULL
+
+g_szSelectNewDrive:
+	db		"Select new drive.",NULL
+g_szLoadingPleaseWait:
+	db		"Loading. Please wait...",NULL
+
+g_szEnterNewFileOrDirectory:
+	db		"Enter name for new file or directory.",NULL
+
+FILE_STRING_LENGTH		EQU		(24+1)	; +1 = LF in directory contents string
+g_szFileFormat:
+	db		"%16S%4-u %c%cB",LF,NULL
+g_szDirectoryFormat:
+	db		"%16S%s-DIR",LF,NULL
+g_szSub:
+	db		ANGLE_QUOTE_RIGHT,"SUB",NULL
+g_szUp:
+	db		ANGLE_QUOTE_LEFT," UP",NULL
+
+g_szSingleItem:			; Used by Dialog.asm for single item line
+g_szUpdir:
+	db		".."
+g_szNull:
+	db		NULL
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Menu.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Menu.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/Menu.asm	(revision 348)
@@ -0,0 +1,65 @@
+; Project name	:	Assembly Library
+; Description	:	Menu Library functions for CALL_MENU_LIBRARY macro
+;					that users should use to make library call.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuFunctionFromDI
+;	Parameters:
+;		DI:		Function to call (MENU_LIB.functionName)
+;		BP:		Menu handle
+;		Others:	Depends on function to call
+;	Returns:
+;		Depends on function to call
+;	Corrupts registers:
+;		AX (unless used as a return register), DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Menu_FunctionFromDI:
+	push	si
+	push	dx
+	push	cx
+	push	bx
+	call	di
+	pop		bx
+	pop		cx
+	pop		dx
+	pop		si
+	ret
+
+
+	%define DisplayWithHandlerInBXandUserDataInDXAX			MenuInit_DisplayMenuWithHandlerInBXandUserDataInDXAX
+	;%define Close											MenuInit_CloseMenuWindow				; Special case in CALL_MENU_LIBRARY
+	%define RefreshWindow									MenuInit_RefreshMenuWindow
+
+	;%define SetUserDataFromDSSI							MenuInit_SetUserDataFromDSSI			; Special case in CALL_MENU_LIBRARY
+	;%define GetUserDataToDSSI								MenuInit_GetUserDataToDSSI				; Special case in CALL_MENU_LIBRARY
+
+	;%define SetTitleHeightFromAL							MenuInit_SetTitleHeightFromAL			; Special case in CALL_MENU_LIBRARY
+	%define ClearTitleArea									MenuText_ClearTitleArea
+	%define RefreshTitle									MenuText_RefreshTitle
+
+	%define HighlightItemFromAX								MenuInit_HighlightItemFromAX
+	;%define SetTotalItemsFromAX							MenuInit_SetTotalItemsFromAX			; Special case in CALL_MENU_LIBRARY
+	%define RefreshItemFromAX								MenuText_RefreshItemFromAX
+
+	;%define SetInformationHeightFromAL						MenuInit_SetInformationHeightFromAL		; Special case in CALL_MENU_LIBRARY
+	%define ClearInformationArea							MenuText_ClearInformationArea
+	%define RefreshInformation								MenuText_RefreshInformation
+
+	%define StartSelectionTimeoutWithTicksInAX				MenuTime_StartSelectionTimeoutWithTicksInAX
+
+%ifdef INCLUDE_MENU_DIALOGS
+	%define StartProgressTaskWithIoInDSSIandParamInDXAX		DialogProgress_StartProgressTaskWithIoInDSSIandParamInDXAX
+	%define SetProgressValueFromAX							DialogProgress_SetProgressValueFromAX
+
+	%define DisplayMessageWithInputInDSSI					DialogMessage_DisplayMessageWithInputInDSSI
+	%define GetSelectionToAXwithInputInDSSI					DialogSelection_GetSelectionToAXwithInputInDSSI
+	%define GetWordWithIoInDSSI								DialogWord_GetWordWithIoInDSSI
+	%define GetStringWithIoInDSSI							DialogString_GetStringWithIoInDSSI
+	%define GetFileNameWithIoInDSSI							DialogFile_GetFileNameWithIoInDSSI
+	%define GetDriveWithIoInDSSI							DialogDrive_GetDriveWithIoInDSSI
+%endif
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuAttributes.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuAttributes.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuAttributes.asm	(revision 348)
@@ -0,0 +1,107 @@
+; Project name	:	Assembly Library
+; Description	:	Finds suitable character attribute for
+;					color, B/W and monochrome displays.
+
+; Struct containing border characters for different types of menu window lines
+struc ATTRIBUTE_CHARS
+	.cBordersAndBackground	resb	1
+	.cShadow				resb	1
+	.cTitle:
+	.cInformation			resb	1
+	.cItem					resb	1
+	.cHighlightedItem		resb	1
+	.cHurryTimeout			resb	1
+	.cNormalTimeout			resb	1
+endstruc
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuAttribute_SetToDisplayContextFromTypeInSI
+;	Parameters
+;		SI:		Attribute type (from ATTRIBUTE_CHARS)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuAttribute_SetToDisplayContextFromTypeInSI:
+	call	MenuAttribute_GetToAXfromTypeInSI
+	CALL_DISPLAY_LIBRARY SetCharacterAttributeFromAL
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuAttribute_GetToAXfromTypeInSI
+;	Parameters
+;		SI:		Attribute type (from ATTRIBUTE_CHARS)
+;	Returns:
+;		AX:		Wanted attribute
+;	Corrupts registers:
+;		SI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuAttribute_GetToAXfromTypeInSI:
+	push	ds
+
+	LOAD_BDA_SEGMENT_TO	ds, ax, !
+	mov		al, [VIDEO_BDA.bMode]		; Load BIOS display mode (0, 1, 2, 3 or 7)
+	cmp		al, 7
+	je		SHORT .LoadMonoAttribute
+	test	al, 1						; Even modes (0 and 2) are B/W
+	jnz		SHORT .LoadColorAttribute
+
+.LoadBlackAndWhiteAttribute:
+	add		si, .rgcBlackAndWhiteAttributes
+	jmp		SHORT .LoadAttributeAndReturn
+
+ALIGN JUMP_ALIGN
+.LoadMonoAttribute:
+	add		si, .rgcMonochromeAttributes
+	jmp		SHORT .LoadAttributeAndReturn
+
+ALIGN JUMP_ALIGN
+.LoadColorAttribute:
+	add		si, .rgcColorAttributes
+.LoadAttributeAndReturn:
+	cs lodsb							; Load from [CS:SI] to AL
+
+	pop		ds
+	ret
+
+
+.rgcColorAttributes:
+istruc ATTRIBUTE_CHARS
+	at	ATTRIBUTE_CHARS.cBordersAndBackground,	db	COLOR_ATTRIBUTE(COLOR_YELLOW, COLOR_BLUE)
+	at	ATTRIBUTE_CHARS.cShadow,				db	COLOR_ATTRIBUTE(COLOR_GRAY, COLOR_BLACK)
+	at	ATTRIBUTE_CHARS.cTitle,					db	COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_BLUE)
+	at	ATTRIBUTE_CHARS.cItem,					db	COLOR_ATTRIBUTE(COLOR_WHITE, COLOR_BLUE)
+	at	ATTRIBUTE_CHARS.cHighlightedItem,		db	COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_CYAN)
+	at	ATTRIBUTE_CHARS.cHurryTimeout,			db	COLOR_ATTRIBUTE(COLOR_RED, COLOR_BLUE) | FLG_COLOR_BLINK
+	at	ATTRIBUTE_CHARS.cNormalTimeout,			db	COLOR_ATTRIBUTE(COLOR_GREEN, COLOR_BLUE)
+iend
+
+.rgcBlackAndWhiteAttributes:	; Only COLOR_WHITE, COLOR_BRIGHT_WHITE and COLOR_BLACK should be used
+istruc ATTRIBUTE_CHARS
+	at	ATTRIBUTE_CHARS.cBordersAndBackground,	db	COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_BLACK)
+	at	ATTRIBUTE_CHARS.cShadow,				db	COLOR_ATTRIBUTE(COLOR_GRAY, COLOR_BLACK)
+	at	ATTRIBUTE_CHARS.cTitle,					db	COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_BLACK)
+	at	ATTRIBUTE_CHARS.cItem,					db	COLOR_ATTRIBUTE(COLOR_WHITE, COLOR_BLACK)
+	at	ATTRIBUTE_CHARS.cHighlightedItem,		db	COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_WHITE)
+	at	ATTRIBUTE_CHARS.cHurryTimeout,			db	COLOR_ATTRIBUTE(COLOR_BRIGHT_WHITE, COLOR_BLACK) | FLG_COLOR_BLINK
+	at	ATTRIBUTE_CHARS.cNormalTimeout,			db	COLOR_ATTRIBUTE(COLOR_WHITE, COLOR_BLACK)
+iend
+
+.rgcMonochromeAttributes:
+istruc ATTRIBUTE_CHARS
+	at	ATTRIBUTE_CHARS.cBordersAndBackground,	db	MONO_BRIGHT
+	at	ATTRIBUTE_CHARS.cShadow,				db	MONO_REVERSE_DARK
+	at	ATTRIBUTE_CHARS.cTitle,					db	MONO_BRIGHT
+	at	ATTRIBUTE_CHARS.cItem,					db	MONO_NORMAL
+	at	ATTRIBUTE_CHARS.cHighlightedItem,		db	MONO_REVERSE
+	at	ATTRIBUTE_CHARS.cHurryTimeout,			db	MONO_BRIGHT_BLINK
+	at	ATTRIBUTE_CHARS.cNormalTimeout,			db	MONO_NORMAL
+iend
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuBorders.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuBorders.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuBorders.asm	(revision 348)
@@ -0,0 +1,437 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for drawing menu borders.
+
+; Struct containing border characters for different types of menu window lines
+struc BORDER_CHARS
+	.cLeft		resb	1
+	.cMiddle	resb	1
+	.cRight		resb	1
+endstruc
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuBorders_RefreshAll
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuBorders_RefreshAll:
+%ifndef USE_186
+	call	MenuBorders_AdjustDisplayContextForDrawingBorders
+	call	MenuBorders_GetNumberOfMiddleCharactersToDX
+	call	RefreshTitleBorders
+	call	RefreshItemBorders
+	call	RefreshInformationBorders
+	call	DrawBottomBorderLine
+	jmp		DrawBottomShadowLine
+%else
+	push	DrawBottomShadowLine
+	push	DrawBottomBorderLine
+	push	RefreshInformationBorders
+	push	RefreshItemBorders
+	push	RefreshTitleBorders
+	push	MenuBorders_GetNumberOfMiddleCharactersToDX
+	jmp		MenuBorders_AdjustDisplayContextForDrawingBorders
+%endif
+
+
+;--------------------------------------------------------------------
+; MenuBorders_RedrawBottomBorderLine
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuBorders_RedrawBottomBorderLine:
+	call	MenuBorders_AdjustDisplayContextForDrawingBorders
+	call	MenuLocation_GetBottomBordersTopLeftCoordinatesToAX
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	call	MenuBorders_GetNumberOfMiddleCharactersToDX
+	jmp		SHORT DrawBottomBorderLine
+
+
+;--------------------------------------------------------------------
+; MenuBorders_RefreshItemBorders
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+MenuBorders_RefreshItemBorders:
+	call	MenuBorders_AdjustDisplayContextForDrawingBorders
+	call	MenuLocation_GetItemBordersTopLeftCoordinatesToAX
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+
+	call	MenuBorders_GetNumberOfMiddleCharactersToDX
+	jmp		SHORT RefreshItemBorders
+%endif
+
+
+;--------------------------------------------------------------------
+; MenuBorders_AdjustDisplayContextForDrawingBorders
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuBorders_AdjustDisplayContextForDrawingBorders:
+	mov		bl, ATTRIBUTES_ARE_USED
+	mov		ax, MenuCharOut_MenuTeletypeOutput
+	CALL_DISPLAY_LIBRARY SetCharOutputFunctionFromAXwithAttribFlagInBL
+
+	call	CharOutLineSplitter_GetFirstBorderLineColumnOffsetToAX
+	CALL_DISPLAY_LIBRARY SetCharacterOutputParameterFromAX
+
+	call	MenuLocation_GetTitleBordersTopLeftCoordinatesToAX
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+
+	mov		si, ATTRIBUTE_CHARS.cBordersAndBackground
+	jmp		MenuAttribute_SetToDisplayContextFromTypeInSI
+
+
+;--------------------------------------------------------------------
+; MenuBorders_GetNumberOfMiddleCharactersToDX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		DX:		Number of middle border characters when drawing border lines
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuBorders_GetNumberOfMiddleCharactersToDX:
+	eMOVZX	dx, [bp+MENUINIT.bWidth]
+	sub		dx, BYTE MENU_HORIZONTAL_BORDER_LINES
+	ret
+
+
+;--------------------------------------------------------------------
+; RefreshTitleBorders
+;	Parameters
+;		DX:		Number of times to repeat middle character
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RefreshTitleBorders:
+	call	DrawTopBorderLine
+	eMOVZX	cx, [bp+MENUINIT.bTitleLines]
+	jmp		SHORT DrawTextBorderLinesByCXtimes
+
+;--------------------------------------------------------------------
+; RefreshInformationBorders
+;	Parameters
+;		DX:		Number of times to repeat middle character
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RefreshInformationBorders:
+	call	DrawSeparationBorderLine
+	eMOVZX	cx, [bp+MENUINIT.bInfoLines]
+	jmp		SHORT DrawTextBorderLinesByCXtimes
+
+;--------------------------------------------------------------------
+; RefreshItemBorders
+;	Parameters
+;		DX:		Number of times to repeat middle character
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+RefreshItemBorders:
+	call	DrawSeparationBorderLine
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	; Fall to DrawTextBorderLinesByCXtimes
+
+;--------------------------------------------------------------------
+; DrawTextBorderLinesByCXtimes
+;	Parameters
+;		CX:		Number of border lines to draw
+;		DX:		Number of times to repeat middle character
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX, SI, DI
+;--------------------------------------------------------------------
+DrawTextBorderLinesByCXtimes:
+	jcxz	.NoBorderLinesToDraw
+ALIGN JUMP_ALIGN
+.DrawBordersWithFunctionInBX:
+	call	DrawTextBorderLine
+	loop	.DrawBordersWithFunctionInBX
+.NoBorderLinesToDraw:
+	ret
+
+
+;--------------------------------------------------------------------
+; DrawTopBorderLine
+; DrawSeparationBorderLine
+; DrawBottomBorderLine
+; DrawTimeoutCounterOverBottomBorderLine
+; DrawBottomShadowLine
+; DrawTextBorderLine
+;	Parameters
+;		DX:		Number of times to repeat middle character
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DrawTopBorderLine:
+	mov		si, g_rgbTopBorderCharacters
+	call	PrintBorderCharactersFromCSSI
+	jmp		SHORT PrintNewlineToEndBorderLine
+
+ALIGN JUMP_ALIGN
+DrawSeparationBorderLine:
+	mov		si, g_rgbSeparationBorderCharacters
+	jmp		SHORT PrintBorderCharactersFromCSSIandShadowCharacter
+
+ALIGN JUMP_ALIGN
+DrawBottomBorderLine:
+	mov		si, g_rgbBottomBorderCharacters
+	test	BYTE [bp+MENU.bFlags], FLG_MENU_TIMEOUT_COUNTDOWN
+	jz		SHORT PrintBorderCharactersFromCSSIandShadowCharacter
+
+	call	DrawTimeoutCounterString
+	sub		dx, BYTE MENU_TIMEOUT_STRING_CHARACTERS
+	mov		si, g_BottomBorderWithTimeoutCharacters
+	call	PrintBorderCharactersFromCSSIandShadowCharacter
+	add		dx, BYTE MENU_TIMEOUT_STRING_CHARACTERS
+	ret
+
+ALIGN JUMP_ALIGN
+DrawBottomShadowLine:
+	CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
+	inc		ax			; Move one column left
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	inc		dx			; Increment repeat count...
+	inc		dx			; ...for both corner characters
+	call	PrintShadowCharactersByDXtimes
+	dec		dx			; Restore...
+	dec		dx			; ...DX
+	ret
+
+ALIGN JUMP_ALIGN
+DrawTextBorderLine:
+	mov		si, g_rgbTextBorderCharacters
+	; Fall to PrintBorderCharactersFromCSSIandShadowCharacter
+
+;--------------------------------------------------------------------
+; PrintBorderCharactersFromCSSIandShadowCharacter
+;	Parameters
+;		DX:		Number of times to repeat middle character
+;		CS:SI:	Ptr to BORDER_CHARS
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PrintBorderCharactersFromCSSIandShadowCharacter:
+	call	PrintBorderCharactersFromCSSI
+	push	dx
+	mov		dx, 1
+	call	PrintShadowCharactersByDXtimes
+	pop		dx
+	; Fall to PrintNewlineToEndBorderLine
+
+;--------------------------------------------------------------------
+; PrintNewlineToEndBorderLine
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PrintNewlineToEndBorderLine:
+	CALL_DISPLAY_LIBRARY PrintNewlineCharacters
+	ret
+
+
+;--------------------------------------------------------------------
+; PrintShadowCharactersByDXtimes
+;	Parameters
+;		DX:		Number of shadow characters to print
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PrintShadowCharactersByDXtimes:
+	CALL_DISPLAY_LIBRARY PushDisplayContext
+
+	mov		si, ATTRIBUTE_CHARS.cShadow
+	call	MenuAttribute_SetToDisplayContextFromTypeInSI
+
+	push	bx
+	mov		bl, ATTRIBUTES_ARE_USED
+	mov		ax, FAST_OUTPUT_WITH_ATTRIBUTE_ONLY
+	CALL_DISPLAY_LIBRARY SetCharOutputFunctionFromAXwithAttribFlagInBL
+	pop		bx
+
+	call	MenuBorders_PrintMultipleBorderCharactersFromAL	; AL does not matter
+
+	CALL_DISPLAY_LIBRARY PopDisplayContext
+	ret
+
+
+;--------------------------------------------------------------------
+; PrintBorderCharactersFromCSSI
+;	Parameters
+;		DX:		Number of times to repeat middle character
+;		CS:SI:	Ptr to BORDER_CHARS
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PrintBorderCharactersFromCSSI:
+	cs lodsb		; Load from [cs:si+BORDER_CHARS.cLeft] to AL
+	call	MenuBorders_PrintSingleBorderCharacterFromAL
+
+	cs lodsb		; Load from [cs:si+BORDER_CHARS.cMiddle] to AL
+	call	MenuBorders_PrintMultipleBorderCharactersFromAL
+
+	cs lodsb		; Load from [cs:si+BORDER_CHARS.cRight] to AL
+	; Fall to MenuBorders_PrintSingleBorderCharacterFromAL
+
+;--------------------------------------------------------------------
+; MenuBorders_PrintSingleBorderCharacterFromAL
+; MenuBorders_PrintMultipleBorderCharactersFromAL
+;	Parameters
+;		AL:		Character to print
+;		DX:		Repeat count (MenuBorders_PrintMultipleBorderCharactersFromAL)
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuBorders_PrintSingleBorderCharacterFromAL:
+	CALL_DISPLAY_LIBRARY PrintCharacterFromAL
+	ret
+
+ALIGN JUMP_ALIGN
+MenuBorders_PrintMultipleBorderCharactersFromAL:
+	push	cx
+	mov		cx, dx
+	CALL_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
+	pop		cx
+	ret
+
+
+;--------------------------------------------------------------------
+; DrawTimeoutCounterString
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DrawTimeoutCounterString:
+	call	MenuTime_GetTimeoutSecondsLeftToAX
+	; Fall to .PrintTimeoutStringWithSecondsInAX
+
+;--------------------------------------------------------------------
+; .PrintTimeoutStringWithSecondsInAX
+;	Parameters
+;		AX:		Seconds to print
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, SI, DI
+;--------------------------------------------------------------------
+.PrintTimeoutStringWithSecondsInAX:
+	; Get attribute to AX
+	xchg	di, ax
+	mov		si, ATTRIBUTE_CHARS.cNormalTimeout
+	cmp		di, BYTE MENU_TIMEOUT_SECONDS_FOR_HURRY
+	eCMOVB	si, ATTRIBUTE_CHARS.cHurryTimeout
+	call	MenuAttribute_GetToAXfromTypeInSI
+
+	push	bp
+	mov		bp, sp
+	mov		si, g_szSelectionTimeout
+	push	ax			; Push attribute
+	push	di			; Push seconds
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	pop		bp
+	ret
+
+; Lookup tables for border characters
+g_rgbTopBorderCharacters:
+istruc BORDER_CHARS
+	at	BORDER_CHARS.cLeft,		db	DOUBLE_TOP_LEFT_CORNER
+	at	BORDER_CHARS.cMiddle,	db	DOUBLE_HORIZONTAL
+	at	BORDER_CHARS.cRight,	db	DOUBLE_TOP_RIGHT_CORNER
+iend
+
+g_rgbSeparationBorderCharacters:
+istruc BORDER_CHARS
+	at	BORDER_CHARS.cLeft,		db	DOUBLE_VERTICAL_TO_RIGHT_SINGLE
+	at	BORDER_CHARS.cMiddle,	db	SINGLE_HORIZONTAL
+	at	BORDER_CHARS.cRight,	db	DOUBLE_VERTICAL_TO_LEFT_SINGLE
+iend
+
+g_rgbBottomBorderCharacters:
+istruc BORDER_CHARS
+	at	BORDER_CHARS.cLeft,		db	DOUBLE_BOTTOM_LEFT_CORNER
+	at	BORDER_CHARS.cMiddle,	db	DOUBLE_HORIZONTAL
+	at	BORDER_CHARS.cRight,	db	DOUBLE_BOTTOM_RIGHT_CORNER
+iend
+
+g_BottomBorderWithTimeoutCharacters:
+istruc BORDER_CHARS
+	at	BORDER_CHARS.cLeft,		db	DOUBLE_RIGHT_HORIZONTAL_TO_SINGLE_VERTICAL
+	at	BORDER_CHARS.cMiddle,	db	DOUBLE_HORIZONTAL
+	at	BORDER_CHARS.cRight,	db	DOUBLE_BOTTOM_RIGHT_CORNER
+iend
+
+g_rgbTextBorderCharacters:
+istruc BORDER_CHARS
+	at	BORDER_CHARS.cLeft,		db	DOUBLE_VERTICAL
+	at	BORDER_CHARS.cMiddle,	db	' '
+	at	BORDER_CHARS.cRight,	db	DOUBLE_VERTICAL
+iend
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuCharOut.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuCharOut.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuCharOut.asm	(revision 348)
@@ -0,0 +1,66 @@
+; Project name	:	Assembly Library
+; Description	:	Character out function for printing withing menu window.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuCharOut_MenuTeletypeOutputWithAutomaticLineChange
+; MenuCharOut_MenuTeletypeOutput
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to video memory where to output
+;		[DISPLAY_CONTEXT.wCharOutParam]:
+;				Low byte  = First column offset (after CR)
+;				High byte = Last column offset (when using automatic line change)
+;	Returns:
+;		DI:		Incremented for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuCharOut_MenuTeletypeOutputWithAutomaticLineChange:
+	call	CharOutLineSplitter_IsCursorAtTheEndOfTextLine
+	jnc		SHORT MenuCharOut_MenuTeletypeOutput
+	cmp		al, ' '
+	jb		SHORT ReturnSinceNoNeedToStartLineWithControlCharacter
+	call	CharOutLineSplitter_MovePartialWordToNewTextLine
+	; Fall to MenuCharOut_MenuTextTeletypeOutputWithAttribute
+
+ALIGN JUMP_ALIGN
+MenuCharOut_MenuTeletypeOutput:
+	cmp		al, CR
+	je		SHORT PrintCRandAdjustOffsetForStartOfLine
+	jmp		DisplayCharOut_TeletypeOutputWithAttribute
+
+
+;--------------------------------------------------------------------
+; MenuCharOut_PrintLFCRandAdjustOffsetForStartOfLine
+; PrintCRandAdjustOffsetForStartOfLine
+;	Parameters:
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to cursor location
+;		[DISPLAY_CONTEXT.wCharOutParam]:
+;				Low byte  = First column offset (after CR)
+;				High byte = Last column offset (when using automatic line change)
+;	Returns:
+;		ES:DI:	Ptr to beginning of new line
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuCharOut_PrintLFCRandAdjustOffsetForStartOfLine:
+	mov		al, LF
+	call	DisplayCharOut_BiosTeletypeOutput
+	; Fall to PrintCRandAdjustOffsetForStartOfLine
+
+ALIGN JUMP_ALIGN
+PrintCRandAdjustOffsetForStartOfLine:
+	mov		al, CR
+	call	DisplayCharOut_BiosTeletypeOutput
+	eMOVZX	ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.wCharOutParam]
+	add		di, ax
+ReturnSinceNoNeedToStartLineWithControlCharacter:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuEvent.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuEvent.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuEvent.asm	(revision 348)
@@ -0,0 +1,187 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for initializing menu system.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuEvent_InitializeMenuinit
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		DS:SI:	Ptr to MENU with MENUINIT initialized from user handler
+;		CF:		Set if event processed
+;				Cleared if event not processed
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_InitializeMenuinit:
+	push	ss
+	pop		ds
+	mov		si, bp
+	mov		bl, MENUEVENT_InitializeMenuinitFromDSSI
+	jmp		SHORT MenuEvent_SendFromBX
+
+
+;--------------------------------------------------------------------
+; MenuEvent_ExitMenu
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set to exit from menu
+;				Cleared to cancel exit
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_ExitMenu:
+	mov		bl, MENUEVENT_ExitMenu
+	jmp		SHORT MenuEvent_SendFromBX
+
+
+%ifdef MENUEVENT_IDLEPROCESSING_ENABLE
+;--------------------------------------------------------------------
+; MenuEvent_IdleProcessing
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if event processed
+;				Cleared if event not processed
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_IdleProcessing:
+	mov		bl, MENUEVENT_IdleProcessing
+	jmp		SHORT MenuEvent_SendFromBX
+%endif
+
+;--------------------------------------------------------------------
+; MenuEvent_RefreshTitle
+; MenuEvent_RefreshInformation
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;		Cursor will be positioned to beginning of window
+;	Returns:
+;		CF:		Set if event processed
+;				Cleared if event not processed
+;	Corrupts registers:
+;		AX, CX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_RefreshTitle:
+	mov		bl, MENUEVENT_RefreshTitle
+	SKIP2B	cx	; mov cx, <next instruction>
+
+MenuEvent_RefreshInformation:
+	mov		bl, MENUEVENT_RefreshInformation
+	mov		cx, [bp+MENUINIT.wHighlightedItem]
+	jmp		SHORT MenuEvent_SendFromBX
+
+
+;--------------------------------------------------------------------
+; MenuEvent_RefreshItemFromCX
+;	Parameters
+;		CX:		Index of item to refresh
+;		SS:BP:	Ptr to MENU
+;		Cursor has been positioned to the beginning of item line
+;	Returns:
+;		CF:		Set if event processed
+;				Cleared if event not processed
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_RefreshItemFromCX:
+	mov		bl, MENUEVENT_RefreshItemFromCX
+	jmp		SHORT MenuEvent_SendFromBX
+
+
+;--------------------------------------------------------------------
+; MenuEvent_HighlightItemFromCX
+;	Parameters
+;		CX:		Index of item to highlight
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_HighlightItemFromCX:
+	mov		dx, cx
+	xchg	dx, [bp+MENUINIT.wHighlightedItem]
+	push	dx
+
+	mov		bl, MENUEVENT_ItemHighlightedFromCX
+	call	MenuEvent_SendFromBX
+
+	pop		ax
+	call	MenuText_RefreshItemFromAX
+	mov		ax, [bp+MENUINIT.wHighlightedItem]
+	jmp		MenuText_RefreshItemFromAX
+
+
+;--------------------------------------------------------------------
+; MenuEvent_KeyStrokeInAX
+;	Parameters
+;		AL:		ASCII character for the key
+;		AH:		Keyboard library scan code for the key
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if event processed
+;				Cleared if event not processed
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_KeyStrokeInAX:
+	mov		bl, MENUEVENT_KeyStrokeInAX
+	SKIP2B	dx	; mov dx, <next instruction>
+
+
+;--------------------------------------------------------------------
+; MenuEvent_ItemSelectedFromCX
+;	Parameters
+;		CX:		Index of selected item
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if event processed
+;				Cleared if event not processed
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+MenuEvent_ItemSelectedFromCX:
+	mov		bl, MENUEVENT_ItemSelectedFromCX
+	; Fall to MenuEvent_SendFromBX
+
+
+;--------------------------------------------------------------------
+; MenuEvent_SendFromBX
+;	Parameters
+;		BL:					Menu event to send
+;		SS:BP:				Ptr to MENU
+;		Other registers:	Event specific parameters
+;	Returns:
+;		AX, DX:				Event specific return values
+;		CF:					Set if event processed
+;							Cleared if event not processed
+;	Corrupts registers:
+;		BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuEvent_SendFromBX:
+	push	es
+	push	ds
+	push	di
+	push	si
+	push	cx
+	xor		bh, bh
+	call	[bp+MENU.fnEventHandler]
+	pop		cx
+	pop		si
+	pop		di
+	pop		ds
+	pop		es
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuInit.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuInit.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuInit.asm	(revision 348)
@@ -0,0 +1,203 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for initializing menu system.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuInit_DisplayMenuWithHandlerInBXandUserDataInDXAX
+;	Parameters
+;		DX:AX:	User specified data
+;		BX:		Menu event handler
+;	Returns:
+;		AX:		Index of selected item or NO_ITEM_SELECTED
+;	Corrupts registers:
+;		All except segments
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuInit_DisplayMenuWithHandlerInBXandUserDataInDXAX:
+	push	es
+	push	ds
+	LOAD_BDA_SEGMENT_TO ds, cx, !
+	push	WORD [BDA.wVidCurShape]
+	mov		cl, MENU_size
+	eENTER_STRUCT cx
+
+	call	Memory_ZeroSSBPwithSizeInCX
+	call	MenuInit_EnterMenuWithHandlerInBXandUserDataInDXAX
+	mov		dx, [bp+MENUINIT.wHighlightedItem]
+
+	eLEAVE_STRUCT MENU_size
+	pop		ax
+	CALL_DISPLAY_LIBRARY SetCursorShapeFromAX
+	CALL_DISPLAY_LIBRARY SynchronizeDisplayContextToHardware
+	xchg	ax, dx			; Return highlighted item in AX
+	pop		ds
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuInit_EnterMenuWithHandlerInBXandUserDataInDXAX
+;	Parameters
+;		DX:AX:	User specified data
+;		BX:		Menu event handler
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except SS:BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuInit_EnterMenuWithHandlerInBXandUserDataInDXAX:
+	mov		[bp+MENU.fnEventHandler], bx
+	mov		[bp+MENU.dwUserData], ax
+	mov		[bp+MENU.dwUserData+2], dx
+
+	mov		ax, CURSOR_HIDDEN
+	CALL_DISPLAY_LIBRARY SetCursorShapeFromAX
+	call	MenuEvent_InitializeMenuinit	; User initialization
+%ifndef USE_186
+	call	MenuInit_RefreshMenuWindow
+	jmp		MenuLoop_Enter
+%else
+	push	MenuLoop_Enter
+	; Fall to MenuInit_RefreshMenuWindow
+%endif
+
+
+;--------------------------------------------------------------------
+; MenuInit_RefreshMenuWindow
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuInit_RefreshMenuWindow:
+	call	MenuBorders_RefreshAll			; Draw borders
+	call	MenuText_RefreshTitle			; Draw title strings
+	call	MenuText_RefreshAllItems		; Draw item strings
+	jmp		MenuText_RefreshInformation		; Draw information strings
+
+
+;--------------------------------------------------------------------
+; MenuInit_CloseMenuIfExitEventAllows
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+MenuInit_CloseMenuIfExitEventAllows:
+	call	MenuEvent_ExitMenu
+	jc		SHORT MenuInit_CloseMenuWindow
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; MenuInit_CloseMenuWindow
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuInit_CloseMenuWindow:
+	or		BYTE [bp+MENU.bFlags], FLG_MENU_EXIT
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuInit_HighlightItemFromAX
+;	Parameters
+;		AX:		Item to highlight
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuInit_HighlightItemFromAX:
+	sub		ax, [bp+MENUINIT.wHighlightedItem]
+	jmp		MenuScrollbars_MoveHighlightedItemByAX
+
+;--------------------------------------------------------------------
+; MenuInit_GetHighlightedItemToAX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Index of highlighted item or NO_ITEM_HIGHLIGHTED
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+MenuInit_GetHighlightedItemToAX:
+	mov		ax, [bp+MENUINIT.wHighlightedItem]
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; MenuInit_SetTitleHeightFromAL
+; MenuInit_SetInformationHeightFromAL
+; MenuInit_SetTotalItemsFromAX
+;	Parameters
+;		AX/AL:	Parameter
+;		SS:BP:		Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+MenuInit_SetTitleHeightFromAL:
+	mov		[bp+MENUINIT.bTitleLines], al
+	ret
+
+ALIGN JUMP_ALIGN
+MenuInit_SetInformationHeightFromAL:
+	mov		[bp+MENUINIT.bInfoLines], al
+	ret
+
+ALIGN JUMP_ALIGN
+MenuInit_SetTotalItemsFromAX:
+	mov		[bp+MENUINIT.wItems], ax
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; MenuInit_SetUserDataFromDSSI
+; MenuInit_GetUserDataToDSSI
+;	Parameters
+;		DS:SI:	User data (MenuInit_SetUserDataFromDSSI)
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		DS:SI:	User data (MenuInit_GetUserDataToDSSI)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+MenuInit_SetUserDataFromDSSI:
+	mov		[bp+MENU.dwUserData], si
+	mov		[bp+MENU.dwUserData+2], ds
+	ret
+
+ALIGN JUMP_ALIGN
+MenuInit_GetUserDataToDSSI:
+	lds		si, [bp+MENU.dwUserData]
+	ret
+%endif
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuLocation.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuLocation.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuLocation.asm	(revision 348)
@@ -0,0 +1,118 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for calculation menu window dimensions.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuLocation_GetTextCoordinatesToAXforItemInAX
+;	Parameters
+;		AX:		Item index
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AL:		Column (X)
+;		AH:		Row (Y)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuLocation_GetTextCoordinatesToAXforItemInAX:
+	sub		ax, [bp+MENU.wFirstVisibleItem]		; Item to line
+	xchg	al, ah								; Line to AH, clear AL
+	add		ax, (MENU_TEXT_ROW_OFFSET<<8) | MENU_TEXT_COLUMN_OFFSET
+	SKIP2B	f	; cmp ax, <next instruction>
+	; Fall to MenuLocation_GetItemBordersTopLeftCoordinatesToAX
+
+;--------------------------------------------------------------------
+; MenuLocation_GetItemBordersTopLeftCoordinatesToAX
+; MenuLocation_GetTitleTextTopLeftCoordinatesToAX
+; MenuLocation_GetTitleBordersTopLeftCoordinatesToAX
+; MenuLocation_GetInformationTextTopLeftCoordinatesToAX
+; MenuLocation_GetBottomBordersTopLeftCoordinatesToAX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AL:		Column (X)
+;		AH:		Row (Y)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+MenuLocation_GetItemBordersTopLeftCoordinatesToAX:
+	xor		ax, ax
+	jmp		SHORT AddItemBordersTopLeftCoordinatesToAX
+
+ALIGN JUMP_ALIGN
+MenuLocation_GetTitleTextTopLeftCoordinatesToAX:
+	mov		ax, (MENU_TEXT_ROW_OFFSET<<8) | MENU_TEXT_COLUMN_OFFSET
+	SKIP2B	f	; cmp ax, <next instruction>
+MenuLocation_GetTitleBordersTopLeftCoordinatesToAX:
+	xor		ax, ax
+	jmp		SHORT MenuLocation_AddTitleBordersTopLeftCoordinatesToAX
+
+ALIGN JUMP_ALIGN
+MenuLocation_GetInformationTextTopLeftCoordinatesToAX:
+	mov		ax, (MENU_TEXT_ROW_OFFSET<<8) | MENU_TEXT_COLUMN_OFFSET
+	jmp		SHORT AddInformationBordersTopLeftCoordinatesToAX
+
+ALIGN JUMP_ALIGN
+MenuLocation_GetBottomBordersTopLeftCoordinatesToAX:
+	xor		ax, ax
+	; Fall to .AddBottomBordersTopLeftCoordinatesToAX
+
+;--------------------------------------------------------------------
+; .AddBottomBordersTopLeftCoordinatesToAX
+; AddInformationBordersTopLeftCoordinatesToAX
+; AddItemBordersTopLeftCoordinatesToAX
+; MenuLocation_AddTitleBordersTopLeftCoordinatesToAX
+;	Parameters
+;		AX:		Zero of offset
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AL:		Column (X)
+;		AH:		Row (Y)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+.AddBottomBordersTopLeftCoordinatesToAX:
+	stc							; Compensate for Information top border
+	adc		ah, [bp+MENUINIT.bInfoLines]
+ALIGN JUMP_ALIGN
+AddInformationBordersTopLeftCoordinatesToAX:
+	push	cx
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	inc		cx					; Compensate for Items top border
+	add		ah, cl
+	pop		cx
+ALIGN JUMP_ALIGN
+AddItemBordersTopLeftCoordinatesToAX:
+	stc							; Compensate for Title top border
+	adc		ah, [bp+MENUINIT.bTitleLines]
+ALIGN JUMP_ALIGN
+MenuLocation_AddTitleBordersTopLeftCoordinatesToAX:
+	push	di
+	push	ax
+	CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
+	sub		al, [bp+MENUINIT.bWidth]
+	sub		ah, [bp+MENUINIT.bHeight]
+	shr		al, 1
+	shr		ah, 1
+	pop		di					; Old AX to DI
+	add		ax, di				; Add old AX to menu top left coordinates
+	pop		di
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuLocation_GetMaxTextLineLengthToAX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Maximum text line length in characters
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuLocation_GetMaxTextLineLengthToAX:
+	eMOVZX	ax, [bp+MENUINIT.bWidth]
+	sub		ax, BYTE MENU_HORIZONTAL_BORDER_LINES + MENU_TEXT_COLUMN_OFFSET
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuLoop.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuLoop.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuLoop.asm	(revision 348)
@@ -0,0 +1,191 @@
+; Project name	:	Assembly Library
+; Description	:	Menu loop for waiting keystrokes.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuLoop_Enter
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuLoop_Enter:
+	call	KeystrokeProcessing
+	call	TimeoutProcessing
+%ifdef MENUEVENT_IDLEPROCESSING_ENABLE
+	call	MenuEvent_IdleProcessing	; User idle processing
+%endif
+	test	BYTE [bp+MENU.bFlags], FLG_MENU_EXIT
+	jz		SHORT MenuLoop_Enter
+	ret
+
+
+;--------------------------------------------------------------------
+; KeystrokeProcessing
+; TimeoutProcessing
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except SS:BP
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+KeystrokeProcessing:
+	call	Keyboard_GetKeystrokeToAX
+	jnz		SHORT ProcessKeystrokeFromAX
+NoKeystrokeToProcess:
+	ret
+
+ALIGN JUMP_ALIGN
+TimeoutProcessing:
+	call	MenuTime_UpdateSelectionTimeout
+	jnc		NoKeystrokeToProcess
+	mov		al, CR	; Fake ENTER to select item
+	; Fall to ProcessKeystrokeFromAX
+
+
+;--------------------------------------------------------------------
+; ProcessKeystrokeFromAX
+;	Parameters
+;		AL:		ASCII character
+;		AH:		BIOS scan code
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ProcessKeystrokeFromAX:
+	xchg	cx, ax
+	call	MenuTime_StopSelectionTimeout
+	xchg	ax, cx
+	call	.ProcessMenuSystemKeystrokeFromAX
+	jc		SHORT NoKeystrokeToProcess
+	jmp		MenuEvent_KeyStrokeInAX
+
+;--------------------------------------------------------------------
+; .ProcessMenuSystemKeystrokeFromAX
+;	Parameters
+;		AL:		ASCII character
+;		AH:		BIOS scan code
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if keystroke processed
+;				Cleared if keystroke not processed
+;		AL:		ASCII character (if CF cleared)
+;		AH:		BIOS scan code (if CF cleared)
+;	Corrupts registers:
+;		BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ProcessMenuSystemKeystrokeFromAX:
+	cmp		al, ESC
+	je		SHORT .LeaveMenuWithoutSelectingItem
+	cmp		al, CR
+	je		SHORT .SelectItem
+
+	test	BYTE [bp+MENU.bFlags], FLG_MENU_USER_HANDLES_SCROLLING
+	jz		SHORT MenuLoop_ProcessScrollingKeysFromAX
+	ret		; Return with CF cleared since keystroke not processed
+
+ALIGN JUMP_ALIGN
+.LeaveMenuWithoutSelectingItem:
+	call	MenuEvent_ExitMenu
+	jnc		SHORT .CancelMenuExit
+	call	MenuInit_CloseMenuWindow
+	mov		WORD [bp+MENUINIT.wHighlightedItem], NO_ITEM_HIGHLIGHTED
+.CancelMenuExit:
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.SelectItem:
+	mov		cx, [bp+MENUINIT.wHighlightedItem]
+	call	MenuEvent_ItemSelectedFromCX
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuLoop_ProcessScrollingKeysFromAX
+;	Parameters
+;		AL:		ASCII character
+;		AH:		BIOS scan code
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if keystroke processed
+;				Cleared if keystroke not processed
+;		AL:		ASCII character (if CF cleared)
+;		AH:		BIOS scan code (if CF cleared)
+;	Corrupts registers:
+;		BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuLoop_ProcessScrollingKeysFromAX:
+	xchg	ah, al
+	cmp		al, MENU_KEY_PGUP
+	je		SHORT .ChangeToPreviousPage
+	cmp		al, MENU_KEY_PGDN
+	je		SHORT .ChangeToNextPage
+	cmp		al, MENU_KEY_HOME
+	je		SHORT .SelectFirstItem
+	cmp		al, MENU_KEY_END
+	je		SHORT .SelectLastItem
+
+	cmp		al, MENU_KEY_UP
+	je		SHORT .DecrementSelectedItem
+	cmp		al, MENU_KEY_DOWN
+	je		SHORT .IncrementSelectedItem
+	clc		; Clear CF since keystroke not processed
+	xchg	ah, al
+	ret
+
+ALIGN JUMP_ALIGN
+.ChangeToPreviousPage:
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	xchg	ax, cx
+	neg		ax
+	mov		cx, [bp+MENUINIT.wHighlightedItem]
+	add		cx, ax
+	jge		SHORT .MoveHighlightedItemByAX	; No rotation for PgUp
+	; Fall to .SelectFirstItem
+ALIGN JUMP_ALIGN
+.SelectFirstItem:
+	mov		ax, [bp+MENUINIT.wHighlightedItem]
+	neg		ax
+	jmp		SHORT .MoveHighlightedItemByAX
+
+ALIGN JUMP_ALIGN
+.ChangeToNextPage:
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	xchg	ax, cx
+	mov		cx, [bp+MENUINIT.wHighlightedItem]
+	add		cx, ax
+	cmp		cx, [bp+MENUINIT.wItems]
+	jb		SHORT .MoveHighlightedItemByAX	; No rotation for PgDn
+	; Fall to .SelectLastItem
+ALIGN JUMP_ALIGN
+.SelectLastItem:
+	stc
+	mov		ax, [bp+MENUINIT.wItems]
+	sbb		ax, [bp+MENUINIT.wHighlightedItem]
+	jmp		SHORT .MoveHighlightedItemByAX
+
+ALIGN JUMP_ALIGN
+.DecrementSelectedItem:
+	mov		ax, -1
+	SKIP2B	cx	; mov cx, <next instruction>
+.IncrementSelectedItem:
+	mov		al, 1	; AH is already 0
+ALIGN JUMP_ALIGN
+.MoveHighlightedItemByAX:
+	call	MenuScrollbars_MoveHighlightedItemByAX
+	stc
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuScrollbars.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuScrollbars.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuScrollbars.asm	(revision 348)
@@ -0,0 +1,251 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for drawing scroll bars over menu borders.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuScrollbars_AreScrollbarsNeeded
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if scroll bars are needed
+;				Cleared if no scroll bars needed
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_AreScrollbarsNeeded:
+	xchg	ax, cx
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	cmp		cx, [bp+MENUINIT.wItems]		; Set CF if max visible < total items
+	xchg	cx, ax
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuScrollbars_GetScrollCharacterToALForLineInDI
+;	Parameters
+;		DI:		Index of item line to draw
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AL:		Scroll track or thumb character
+;	Corrupts registers:
+;		AH, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_GetScrollCharacterToALForLineInDI:
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	; Get first thumb line to AX
+	mov		ax, [bp+MENU.wFirstVisibleItem]
+	call	.CalculateFirstOrLastThumbLineToAX
+
+	cmp		di, ax				; Before first thumb line?
+	jb		SHORT .ReturnTrackCharacter
+	call	.GetLastThumbLineToAX
+	cmp		ax, di				; After last thumb line?
+ALIGN JUMP_ALIGN
+.ReturnTrackCharacter:
+	mov		al, SCROLL_TRACK_CHARACTER
+	jb		SHORT .Return
+	mov		al, SCROLL_THUMB_CHARACTER
+ALIGN JUMP_ALIGN, ret
+.Return:
+	ret
+
+;--------------------------------------------------------------------
+; .GetLastThumbLineToAX
+;	Parameters
+;		CX:		Max visible items on page
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Item line for last thumb character
+;	Corrupts registers:
+;		CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.GetLastThumbLineToAX:
+	call	MenuScrollbars_GetLastVisibleItemOnPageToAX
+	; Fall to .CalculateFirstOrLastThumbLineToAX
+
+;--------------------------------------------------------------------
+; .CalculateFirstOrLastThumbLineToAX
+;	Parameters
+;		AX:		Index of first or last visible item on page
+;		CX:		Max visible items on page
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Item line for first thumb character
+;	Corrupts registers:
+;		CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.CalculateFirstOrLastThumbLineToAX:
+	mul		cx
+	div		WORD [bp+MENUINIT.wItems]
+	ret		; (Visible items on page * First visible item on page) / total items
+
+
+;--------------------------------------------------------------------
+; MenuScrollbars_MoveHighlightedItemByAX
+;	Parameters
+;		AX:		Signed offset to new item to be highlighted
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_MoveHighlightedItemByAX:
+	mov		cx, [bp+MENUINIT.wHighlightedItem]
+	add		cx, ax
+	; Fall to .RotateItemInCX
+
+;--------------------------------------------------------------------
+; .RotateItemInCX
+;	Parameters
+;		CX:		Possibly under of overflown item to be rotated
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CX:		Valid item index
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+;.RotateItemInCX:
+	mov		dx, [bp+MENUINIT.wItems]
+	test	cx, cx
+	js		SHORT .RotateNegativeItemInCX
+	sub		cx, dx
+	jae		SHORT .ScrollPageForNewItemInCX
+
+ALIGN JUMP_ALIGN
+.RotateNegativeItemInCX:
+	add		cx, dx
+	; Fall to .ScrollPageForNewItemInCX
+
+;--------------------------------------------------------------------
+; .ScrollPageForNewItemInCX
+;	Parameters
+;		CX:		New item to be highlighted
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ScrollPageForNewItemInCX:
+	call	MenuScrollbars_IsItemInCXonVisiblePage
+	jc		SHORT .HighlightNewItemOnCX
+
+	mov		dx, [bp+MENU.wFirstVisibleItem]
+	sub		dx, [bp+MENUINIT.wHighlightedItem]
+
+	; Get MaxFirstVisibleItem to AX
+	push	cx
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	mov		ax, [bp+MENUINIT.wItems]
+	sub		ax, cx
+	pop		cx
+
+	add		dx, cx
+	jns		.DXisPositive
+	cwd		; This won't work if MaxFirstVisibleItem > 32767
+
+ALIGN JUMP_ALIGN
+.DXisPositive:
+	cmp		ax, dx
+	jb		.AXisLessThanDX
+	xchg	dx, ax
+
+ALIGN JUMP_ALIGN
+.AXisLessThanDX:
+	mov		[bp+MENU.wFirstVisibleItem], ax
+	call	MenuText_RefreshAllItems
+
+ALIGN JUMP_ALIGN
+.HighlightNewItemOnCX:
+	jmp		MenuEvent_HighlightItemFromCX
+
+
+;--------------------------------------------------------------------
+; MenuScrollbars_IsItemInCXonVisiblePage
+;	Parameters
+;		CX:		Item whose visibility is to be checked
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if item is on visible page
+;				Cleared if item is not on visible page
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_IsItemInCXonVisiblePage:
+	cmp		[bp+MENU.wFirstVisibleItem], cx
+	ja		SHORT .ItemIsNotVisible
+
+	call	MenuScrollbars_GetLastVisibleItemOnPageToAX
+	cmp		cx, ax
+	ja		SHORT .ItemIsNotVisible
+	stc		; Item is visible
+ALIGN JUMP_ALIGN, ret
+.ItemIsNotVisible:
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuScrollbars_GetLastVisibleItemOnPageToAX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Index of last visible item on page
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_GetLastVisibleItemOnPageToAX:
+	xchg	cx, ax
+	call	MenuScrollbars_GetActualVisibleItemsOnPageToCX
+	xchg	ax, cx
+	dec		ax
+	add		ax, [bp+MENU.wFirstVisibleItem]
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuScrollbars_GetActualVisibleItemsOnPageToCX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CX:		Currently visible items
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_GetActualVisibleItemsOnPageToCX:
+	call	MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+	cmp		cx, [bp+MENUINIT.wItems]
+	jb		SHORT .Return
+	mov		cx, [bp+MENUINIT.wItems]
+ALIGN JUMP_ALIGN, ret
+.Return:
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuScrollbars_GetMaxVisibleItemsOnPageToCX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CX:		Maximum number of visible items
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuScrollbars_GetMaxVisibleItemsOnPageToCX:
+	eMOVZX	cx, [bp+MENUINIT.bHeight]
+	sub		cl, [bp+MENUINIT.bTitleLines]
+	sub		cl, [bp+MENUINIT.bInfoLines]
+	sub		cl, MENU_VERTICAL_BORDER_LINES
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuText.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuText.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuText.asm	(revision 348)
@@ -0,0 +1,262 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for drawing menu texts by the user.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuText_ClearTitleArea
+; MenuText_ClearInformationArea
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+MenuText_ClearTitleArea:
+	CALL_DISPLAY_LIBRARY PushDisplayContext		; Save cursor coordinates
+	call	PrepareToDrawTitleArea
+	mov		cl, [bp+MENUINIT.bTitleLines]
+	jmp		SHORT MenuText_ClearInformationArea.ClearCLlinesOfText
+%endif
+		
+ALIGN JUMP_ALIGN
+MenuText_ClearInformationArea:
+	CALL_DISPLAY_LIBRARY PushDisplayContext		; Save cursor coordinates
+	call	MenuText_PrepareToDrawInformationArea
+	mov		cl, [bp+MENUINIT.bInfoLines]
+.ClearCLlinesOfText:
+	mov		al, [bp+MENUINIT.bWidth]
+	sub		al, MENU_HORIZONTAL_BORDER_LINES+(MENU_TEXT_COLUMN_OFFSET/2)
+	mul		cl
+	xchg	cx, ax
+	mov		al, ' '
+	CALL_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
+	CALL_DISPLAY_LIBRARY PopDisplayContext
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuText_RefreshTitle
+; MenuText_RefreshInformation
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuText_RefreshTitle:
+	cmp		BYTE [bp+MENUINIT.bTitleLines], 0
+	jz		SHORT NothingToRefresh
+	call	PrepareToDrawTitleArea
+	jmp		MenuEvent_RefreshTitle
+
+ALIGN JUMP_ALIGN
+MenuText_RefreshInformation:
+	cmp		BYTE [bp+MENUINIT.bInfoLines], 0
+	jz		SHORT NothingToRefresh
+	call	MenuText_PrepareToDrawInformationArea
+	jmp		MenuEvent_RefreshInformation
+
+;--------------------------------------------------------------------
+; PrepareToDrawTitleArea
+; PrepareToDrawInformationArea
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PrepareToDrawTitleArea:
+	mov		si, ATTRIBUTE_CHARS.cTitle
+	call	MenuLocation_GetTitleTextTopLeftCoordinatesToAX
+	jmp		SHORT FinishPreparationsToDrawTitleOrInformationArea
+
+ALIGN JUMP_ALIGN
+MenuText_PrepareToDrawInformationArea:
+	mov		si, ATTRIBUTE_CHARS.cInformation
+	call	MenuLocation_GetInformationTextTopLeftCoordinatesToAX
+FinishPreparationsToDrawTitleOrInformationArea:
+	mov		dx, MenuCharOut_MenuTeletypeOutputWithAutomaticLineChange
+	jmp		SHORT AdjustDisplayContextForDrawingTextsAtCoordsInAXwithAttrTypeInSIandCharOutFunctionInDX
+
+
+;--------------------------------------------------------------------
+; MenuText_RefreshAllItems
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuText_RefreshAllItems:
+	push	cx
+
+	call	MenuScrollbars_GetActualVisibleItemsOnPageToCX
+	mov		ax, [bp+MENU.wFirstVisibleItem]
+ALIGN JUMP_ALIGN
+.ItemRefreshLoop:
+	call	MenuText_RefreshItemFromAX
+	inc		ax
+	loop	.ItemRefreshLoop
+
+	pop		cx
+NothingToRefresh:
+	ret
+
+;--------------------------------------------------------------------
+; MenuText_RefreshItemFromAX
+;	Parameters
+;		AX:		Item to refresh
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuText_RefreshItemFromAX:
+	push	cx
+	push	ax
+
+	xchg	cx, ax
+	call	MenuScrollbars_IsItemInCXonVisiblePage
+	jnc		SHORT .InvalidItem
+	call	MenuText_AdjustDisplayContextForDrawingItemFromCX
+	call	ClearPreviousItem
+	call	MenuEvent_RefreshItemFromCX
+	call	DrawScrollbarCharacterForItemInCXifNecessary
+.InvalidItem:
+	pop		ax
+	pop		cx
+	ret
+
+;--------------------------------------------------------------------
+; MenuText_AdjustDisplayContextForDrawingItemFromCX
+;	Parameters
+;		CX:		Item to refresh
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuText_AdjustDisplayContextForDrawingItemFromCX:
+	mov		ax, cx
+	call	GetItemTextAttributeTypeToSIforItemInCX
+	call	MenuLocation_GetTextCoordinatesToAXforItemInAX
+	mov		dx, MenuCharOut_MenuTeletypeOutput
+	; Fall to AdjustDisplayContextForDrawingTextsAtCoordsInAXwithAttrTypeInSIandCharOutFunctionInDX
+
+;--------------------------------------------------------------------
+; AdjustDisplayContextForDrawingTextsAtCoordsInAXwithAttrTypeInSIandCharOutFunctionInDX
+;	Parameters
+;		AX:		Cursor coordinates to set
+;		DX:		Character output function
+;		SI:		Attribute type (from ATTRIBUTE_CHARS)
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AdjustDisplayContextForDrawingTextsAtCoordsInAXwithAttrTypeInSIandCharOutFunctionInDX:
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+
+	xchg	ax, dx
+	mov		bl, ATTRIBUTES_ARE_USED
+	CALL_DISPLAY_LIBRARY SetCharOutputFunctionFromAXwithAttribFlagInBL
+
+	call	CharOutLineSplitter_PrepareForPrintingTextLines
+	jmp		MenuAttribute_SetToDisplayContextFromTypeInSI
+
+
+;--------------------------------------------------------------------
+; ClearPreviousItem
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ClearPreviousItem:
+	CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
+	xchg	bx, ax
+
+	call	MenuBorders_GetNumberOfMiddleCharactersToDX
+	sub		dx, BYTE MENU_TEXT_COLUMN_OFFSET
+	mov		al, [cs:g_rgbTextBorderCharacters+BORDER_CHARS.cMiddle]
+	call	MenuBorders_PrintMultipleBorderCharactersFromAL
+
+	xchg	ax, bx
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+	ret
+
+
+;--------------------------------------------------------------------
+; GetItemTextAttributeTypeToSIforItemInCX
+;	Parameters
+;		CX:		Item to refresh
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		SI:		Text attribute type (ATTRIBUTE_CHARS)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetItemTextAttributeTypeToSIforItemInCX:
+	mov		si, ATTRIBUTE_CHARS.cItem
+	test	BYTE [bp+MENU.bFlags], FLG_MENU_NOHIGHLIGHT
+	jnz		SHORT .ReturnAttributeTypeInSI
+
+	cmp		cx, [bp+MENUINIT.wHighlightedItem]
+	jne		SHORT .ReturnAttributeTypeInSI
+	sub		si, BYTE ATTRIBUTE_CHARS.cItem - ATTRIBUTE_CHARS.cHighlightedItem
+ALIGN JUMP_ALIGN, ret
+.ReturnAttributeTypeInSI:
+	ret
+
+
+;--------------------------------------------------------------------
+; DrawScrollbarCharacterForItemInCXifNecessary
+;	Parameters
+;		CX:		Item to refresh
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DrawScrollbarCharacterForItemInCXifNecessary:
+	call	MenuScrollbars_AreScrollbarsNeeded
+	jc		SHORT .DrawScrollbarCharacter
+	ret
+
+ALIGN JUMP_ALIGN
+.DrawScrollbarCharacter:
+	call	MenuBorders_AdjustDisplayContextForDrawingBorders
+	mov		ax, cx
+
+	call	MenuLocation_GetTextCoordinatesToAXforItemInAX
+	add		al, [bp+MENUINIT.bWidth]
+	sub		al, MENU_TEXT_COLUMN_OFFSET*2
+	CALL_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
+
+	mov		di, cx
+	sub		di, [bp+MENU.wFirstVisibleItem]		; Item to line
+	call	MenuScrollbars_GetScrollCharacterToALForLineInDI
+	jmp		MenuBorders_PrintSingleBorderCharacterFromAL
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuTime.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuTime.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Menu/MenuTime.asm	(revision 348)
@@ -0,0 +1,124 @@
+; Project name	:	Assembly Library
+; Description	:	Menu timeouts other time related functions.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MenuTime_StartSelectionTimeoutWithTicksInAX
+;	Parameters
+;		AX:		Timeout ticks
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuTime_StartSelectionTimeoutWithTicksInAX:
+	push	ds
+	call	PointDSBXtoTimeoutCounter
+	call	TimerTicks_InitializeTimeoutFromAX
+	or		BYTE [bp+MENU.bFlags], FLG_MENU_TIMEOUT_COUNTDOWN
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuTime_StopSelectionTimeout
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuTime_StopSelectionTimeout:
+	test	BYTE [bp+MENU.bFlags], FLG_MENU_TIMEOUT_COUNTDOWN
+	jz		SHORT TimeoutAlreadyStopped
+	and		BYTE [bp+MENU.bFlags], ~FLG_MENU_TIMEOUT_COUNTDOWN
+	jmp		MenuBorders_RedrawBottomBorderLine
+
+
+;--------------------------------------------------------------------
+; MenuTime_UpdateSelectionTimeout
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		CF:		Set if timeout
+;				Cleared if time left
+;	Corrupts registers:
+;		AX, BX, SI, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuTime_UpdateSelectionTimeout:
+	test	BYTE [bp+MENU.bFlags], FLG_MENU_TIMEOUT_COUNTDOWN
+	jz		SHORT .ReturnSinceTimeoutDisabled
+
+	push	ds
+	call	PointDSBXtoTimeoutCounter
+	call	TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
+	pop		ds
+	jnc		SHORT .RedrawSinceNoTimeout
+	and		BYTE [bp+MENU.bFlags], ~FLG_MENU_TIMEOUT_COUNTDOWN
+	stc
+	ret
+
+ALIGN JUMP_ALIGN
+.RedrawSinceNoTimeout:
+	call	MenuBorders_RedrawBottomBorderLine
+	clc
+.ReturnSinceTimeoutDisabled:
+TimeoutAlreadyStopped:
+	ret
+
+
+;--------------------------------------------------------------------
+; MenuTime_GetTimeoutSecondsLeftToAX
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		AX:		Seconds until timeout
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MenuTime_GetTimeoutSecondsLeftToAX:
+	push	ds
+	push	dx
+	push	cx
+	push	bx
+
+	call	PointDSBXtoTimeoutCounter
+	call	TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
+	jc		SHORT .TimeoutHasOccurredSoMakeSureTicksAreNotBelowZero
+
+	xchg	dx, ax
+	call	TimerTicks_GetSecondsToAXfromTicksInDX
+	SKIP2B	f	; cmp ax, <next instruction>
+.TimeoutHasOccurredSoMakeSureTicksAreNotBelowZero:
+	xor		ax, ax
+
+	pop		bx
+	pop		cx
+	pop		dx
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; PointDSBXtoTimeoutCounter
+;	Parameters
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		DS:BX:	Ptr to timeout counter
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+PointDSBXtoTimeoutCounter:
+	push	ss
+	pop		ds
+	lea		bx, [bp+MENU.wTimeoutCounter]
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Serial/SerialServer.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Serial/SerialServer.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Serial/SerialServer.asm	(revision 348)
@@ -0,0 +1,452 @@
+; Project name	:	Assembly Library
+; Description	:	Serial Server Support
+
+%include "SerialServer.inc"
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; SerialServer_SendReceive:
+;	Parameters:
+;       DX:		Packed I/O port and baud rate
+;		ES:SI:	Ptr to buffer (for data transfer commands)
+;		SS:BP:	Ptr to SerialServer_Command structure
+;	Returns:
+;		AH:		INT 13h Error Code
+;       CX:     Number of 512-byte blocks transferred
+;		CF:		Cleared if success, Set if error
+;	Corrupts registers:
+;		AL, BX, CX, DX
+;--------------------------------------------------------------------
+SerialServer_SendReceive:
+
+		push	si
+		push	di
+		push	bp
+
+;
+; Unpack I/O port and baud from DPT
+;		Port to DX for the remainder of the routine (+/- different register offsets)
+;		Baud in CH until UART initialization is complete
+;
+		mov		ch,dh
+		xor		dh,dh
+		eSHL_IM	dx, 2			; shift from one byte to two
+
+		mov		al,[bp+SerialServer_Command.bSectorCount]
+		mov		ah,[bp+SerialServer_Command.bCommand]
+
+;
+; Command byte and sector count live at the top of the stack, pop/push are used to access
+;
+		push	ax				; save sector count for return value
+		push	ax				; working copy on the top of the stack
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS	; DF already cleared in Int13h.asm
+		cld
+%endif
+
+;----------------------------------------------------------------------
+;
+; Initialize UART
+;
+; We do this each time since DOS (at boot) or another program may have
+; decided to reprogram the UART
+;
+		mov		bl,dl			; setup BL with proper values for read/write loops (BH comes later)
+
+		mov		al,83h
+		add		dl,Serial_UART_lineControl
+		out		dx,al
+
+		mov		al,ch
+		mov		dl,bl			; divisor low
+		out		dx,al
+
+		xor		ax,ax
+		inc		dx				; divisor high
+		push	dx
+		out		dx,al
+
+		mov		al,047h
+		inc		dx				;  fifo
+		out		dx,al
+
+		mov		al,03h
+		inc		dx				;  linecontrol
+		out		dx,al
+
+		mov		al,0bh
+		inc		dx				;  modemcontrol
+		out		dx,al
+
+		inc		dx				;  linestatus (no output now, just setting up BH for later use)
+		mov		bh,dl
+
+		pop		dx				; base, interrupts disabled
+		xor		ax,ax
+		out		dx,al
+
+;----------------------------------------------------------------------
+;
+; Send Command
+;
+; Sends first six bytes of IDEREGS_AND_INTPACK as the command
+;
+		push	es				; save off real buffer location
+		push	si
+
+		mov		si,bp			; point to IDEREGS for command dispatch;
+		push	ss
+		pop		es
+
+		mov		di,0ffffh		; initialize checksum for write
+		mov		bp,di
+
+		mov		cx,4			; writing 3 words (plus 1)
+
+		cli						; interrupts off...
+
+		call	SerialServer_WriteProtocol.entry
+
+		pop		di				; restore real buffer location (note change from SI to DI)
+								; Buffer is primarily referenced through ES:DI throughout, since
+								; we need to store (read sector) faster than we read (write sector)
+		pop		es
+
+		pop		ax				; load command byte (done before call to .nextSector on subsequent iterations)
+		push	ax
+
+%ifndef SERIALSERVER_NO_ZERO_SECTOR_COUNTS
+		test	al,al			; if no sectors to be transferred, wait for the ACK checksum on the command
+		jz		.zeroSectors
+%endif
+
+;
+; Top of the read/write loop, one iteration per sector
+;
+.nextSector:
+		mov		si,0ffffh		; initialize checksum for read or write
+		mov		bp,si
+
+		mov		cx,0101h		; writing 256 words (plus 1)
+
+		shr		ah,1			; command byte, are we doing a write?
+		jnc		.readEntry
+
+		xchg	si,di			; swap pointer and checksum, will be re-swap'ed in WriteProtocol
+		call	SerialServer_WriteProtocol.entry
+
+.zeroSectors:
+		inc		cx				; CX = 1 now (0 out of WriteProtocol)
+		jmp		.readEntry
+
+;----------------------------------------------------------------------
+;
+; Timeout
+;
+; To save code space, we use the contents of DL to decide which byte in the word to return for reading.
+;
+.readTimeout:
+		push	ax				; not only does this push preserve AX (which we need), but it also
+								; means the stack has the same number of bytes on it as when we are
+								; sending a packet, important for error cleanup and exit
+		mov		ah,1
+		call	SerialServer_WaitAndPoll_Read
+		pop		ax
+		test	dl,1
+		jz		.readByte1Ready
+		jmp		.readByte2Ready
+
+;----------------------------------------------------------------------------
+;
+; Read Block (without interrupts, used when there is a FIFO, high speed)
+;
+; NOTE: This loop is very time sensitive.  Literally, another instruction
+; cannot be inserted into this loop without us falling behind at high
+; speed (460.8K baud) on a 4.77Mhz 8088, making it hard to receive
+; a full 512 byte block.
+;
+.readLoop:
+		stosw					; store word in caller's data buffer
+
+		add		bp, ax			; update Fletcher's checksum
+		adc		bp, 0
+		add		si, bp
+		adc		si, 0
+
+.readEntry:
+		mov		dl,bh
+		in		al,dx
+		shr		al,1			; data ready (byte 1)?
+		mov		dl,bl			; get ready to read data
+		jnc		.readTimeout	; nope not ready, update timeouts
+
+;
+; Entry point after initial timeout.  We enter here so that the checksum word
+; is not stored (and is left in AX after the loop is complete).
+;
+.readByte1Ready:
+		in		al, dx			; read data byte 1
+
+		mov		ah, al			; store byte in ah for now
+
+;
+; note the placement of this reset of dl to bh, and that it is
+; before the return, which is assymetric with where this is done
+; above for byte 1.  The value of dl is used by the timeout routine
+; to know which byte to return to (.read_byte1_ready or
+; .read_byte2_ready)
+;
+		mov		dl,bh
+
+		in		al,dx
+		shr		al,1			; data ready (byte 2)?
+		jnc		.readTimeout
+.readByte2Ready:
+		mov		dl,bl
+		in		al, dx			; read data byte 2
+
+		xchg	al, ah			; ah was holding byte 1, reverse byte order
+
+		loop	.readLoop
+
+		sti						; interrupts back on ASAP, between packets
+
+;
+; Compare checksums
+;
+		xchg	ax,bp
+		xor		ah,al
+		mov		cx,si
+		xor		cl,ch
+		mov		al,cl
+		cmp		ax,bp
+		jnz		SerialServer_OutputWithParameters_Error
+
+		pop		ax				; sector count and command byte
+		dec		al				; decrement sector count
+		push	ax				; save
+		jz		SerialServer_OutputWithParameters_ReturnCodeInAL
+
+		cli						; interrupts back off for ACK byte to host
+								; (host could start sending data immediately)
+		out		dx,al			; ACK with next sector number
+
+		jmp		short .nextSector
+
+;---------------------------------------------------------------------------
+;
+; Cleanup, error reporting, and exit
+;
+
+;
+; Used in situations where a call is underway, such as with SerialServer_WaitAndPoll
+;
+ALIGN JUMP_ALIGN
+SerialServer_OutputWithParameters_ErrorAndPop4Words:
+		add		sp,8
+;;; fall-through
+
+ALIGN JUMP_ALIGN
+SerialServer_OutputWithParameters_Error:
+;----------------------------------------------------------------------
+;
+; Clear read buffer
+;
+; In case there are extra characters or an error in the FIFO, clear it out.
+; In theory the initialization of the UART registers above should have
+; 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
+		in		al,dx
+		mov		dl,bl
+		test	al,08fh
+		jz		.clearBufferComplete
+		test	al,1
+		in		al,dx
+		loopnz	.clearBuffer			; note ZF from test above
+
+.clearBufferComplete:
+		mov		al, 3			;  error return code and CF (low order bit)
+
+ALIGN JUMP_ALIGN
+SerialServer_OutputWithParameters_ReturnCodeInAL:
+%if 0
+		sti						;  all paths here will already have interrupts turned back on
+%endif
+		mov		ah, al			;  for success, AL will already be zero
+
+		pop		bx				;  recover "ax" (command and count) from stack
+		pop		cx				;  recover saved sector count
+		xor		ch, ch
+		sub		cl, bl			; subtract off the number of sectors that remained
+
+		pop		bp
+		pop		di
+		pop		si
+
+		shr		ah, 1			; shift down return code and CF
+
+		ret
+
+;--------------------------------------------------------------------
+; SerialServer_WriteProtocol
+;
+; NOTE: As with its read counterpart, this loop is very time sensitive.
+; Although it will still function, adding additional instructions will
+; impact the write throughput, especially on slower machines.
+;
+;	Parameters:
+;		ES:SI:	Ptr to buffer
+;		CX:		Words to write, plus 1
+;		BP/DI:	Initialized for Checksum (-1 in each)
+;		DH:		I/O Port high byte
+;		BX:		LineStatus Register address (BH) and Receive/Transmit Register address (BL)
+;	Returns:
+;		BP/SI:	Checksum for written bytes, compared against ACK from server in .readLoop
+;		CX:     Zero
+;		DL:		Receive/Transmit Register address
+;		ES:DI:  Ptr to buffer
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SerialServer_WriteProtocol:
+.writeLoop:
+		es lodsw				; fetch next word
+
+		out		dx,al			; output first byte
+
+		add		bp,ax			; update checksum
+		adc		bp,0
+		add		di,bp
+		adc		di,0
+
+		mov		dl,bh			; transmit buffer empty?
+		in		al,dx
+		test	al,20h
+		jz		.writeTimeout2	; nope, use our polling routine
+
+.writeByte2Ready:
+		mov		dl,bl
+		mov		al,ah			; output second byte
+		out		dx,al
+
+.entry:
+		mov		dl,bh			; transmit buffer empty?
+		in		al,dx
+		test	al,20h
+		mov		dl,bl
+		jz		.writeTimeout1	; nope, use our polling routine
+
+.writeByte1Ready:
+		loop	.writeLoop
+
+		mov		ax,di			; fold Fletcher's checksum and output
+		xor		al,ah
+		out		dx,al			; byte 1
+
+		call	SerialServer_WaitAndPoll_Write
+
+		mov		ax,bp
+		xor		al,ah
+		out		dx,al			; byte 2
+
+		xchg	si,di			; preserve checksum word in si, move pointer back to di
+
+		ret
+
+.writeTimeout2:
+		mov		dl,ah			; need to preserve AH, but don't need DL (will be reset upon return)
+		call	SerialServer_WaitAndPoll_Write
+		mov		ah,dl
+		jmp		.writeByte2Ready
+
+.writeTimeout1:
+		ePUSH_T	ax, .writeByte1Ready	; return address for ret at end of SC_writeTimeout2
+;;; fall-through
+
+;--------------------------------------------------------------------
+; SerialServer_WaitAndPoll
+;
+;	Parameters:
+;		AH:		UART_LineStatus bit to test (20h for write, or 1h for read)
+;               One entry point fills in AH with 20h for write
+;		DX:		Port address (OK if already incremented to UART_lineStatus)
+;       BX:
+;       Stack:	2 words on the stack below the command/count word
+;	Returns:
+;       Returns when desired UART_LineStatus bit is cleared
+;       Jumps directly to error exit if timeout elapses (and cleans up stack)
+;	Corrupts registers:
+;       AX
+;--------------------------------------------------------------------
+
+SerialServer_WaitAndPoll_SoftDelayTicks   EQU   20
+
+ALIGN JUMP_ALIGN
+SerialServer_WaitAndPoll_Write:
+		mov		ah,20h
+;;; fall-through
+
+ALIGN JUMP_ALIGN
+SerialServer_WaitAndPoll_Read:
+		push	cx
+		push	dx
+
+;
+; We first poll in a tight loop, interrupts off, for the next character to come in/be sent
+;
+		xor		cx,cx
+.readTimeoutLoop:
+		mov		dl,bh
+		in		al,dx
+		test	al,ah
+		jnz		.readTimeoutComplete
+		loop	.readTimeoutLoop
+
+;
+; If that loop completes, then we assume there is a long delay involved, turn interrupts back on
+; and wait for a given number of timer ticks to pass.
+;
+		sti
+		mov		cl,SerialServer_WaitAndPoll_SoftDelayTicks
+%ifndef SERIALSERVER_TIMER_LOCATION
+		call	Timer_InitializeTimeoutWithTicksInCL
+%else
+		push	ax
+		push	bx
+		mov		ax,SerialServer_WaitAndPoll_SoftDelayTicks
+		mov		bx,SERIALSERVER_TIMER_LOCATION
+		call	TimerTicks_InitializeTimeoutFromAX
+		pop		bx
+		pop		ax
+%endif
+
+.WaitAndPoll:
+%ifndef SERIALSERVER_TIMER_LOCATION
+		call	Timer_SetCFifTimeout
+%else
+		push	ax
+		push	bx
+		mov		bx,SERIALSERVER_TIMER_LOCATION
+		call	TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
+		pop		bx
+		pop		ax
+%endif
+		jc		SerialServer_OutputWithParameters_ErrorAndPop4Words
+		in		al,dx
+		test	al,ah
+		jz		.WaitAndPoll
+		cli
+
+.readTimeoutComplete:
+		pop		dx
+		pop		cx
+		ret
+
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Serial/SerialServerScan.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Serial/SerialServerScan.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Serial/SerialServerScan.asm	(revision 348)
@@ -0,0 +1,141 @@
+; Project name	:	Assembly Library
+; Description	:	Serial Server Support, Scan for Server
+;
+; This functionality is broken out from SerialServer as it may only be needed during
+; initialization to find a server, and then could be discarded, (for example the case
+; of a TSR).
+
+%include "SerialServer.inc"
+		
+; Section containing code
+SECTION .text
+		
+;--------------------------------------------------------------------
+; SerialServerScan_ScanForServer:	
+;	Parameters:
+;       BH:		Drive Select byte for Drive and Head Select Register
+;               0xAx: Scan for drive, low nibble indicates drive
+;               0x0:  Scan for Server, independent of drives
+;		DX:		Port and Baud to Scan for
+;				0: Scan a known set of ports and bauds
+;		ES:SI:	Ptr to buffer for return
+;	Returns:
+;		CF:		Cleared if success, Set if error
+;	Corrupts registers:
+;		AL, BX, CX, DX, DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SerialServerScan_ScanForServer:		
+		mov		cx, 1			; one sector, not scanning (default)
+
+		test	dx, dx
+		jnz		short SerialServerScan_CheckForServer_PortAndBaudInDX
+
+		mov		di,.scanPortAddresses-1
+		mov		ch,1			;  tell server that we are scanning
+
+.nextPort:
+		inc		di				; load next port address
+		xor		dh, dh
+		mov		dl,[cs:di]
+		eSHL_IM	dx, 2			; shift from one byte to two
+		stc						; setup error code for exit
+		jz		.error
+
+;
+; Test for COM port presence, write to and read from registers
+;
+		push	dx
+		add		dl,Serial_UART_lineControl
+		mov		al, 09ah
+		out		dx, al
+		in		al, dx
+		pop		dx
+		cmp		al, 09ah
+		jnz		.nextPort
+
+		mov		al, 0ch
+		out		dx, al
+		in		al, dx
+		cmp		al, 0ch
+		jnz		.nextPort
+
+;
+; 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:
+		shr		dh,1
+		jz		.nextPort
+		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	SerialServerScan_CheckForServer_PortAndBaudInDX
+		jc		.nextBaud
+
+.error:	
+		ret
+
+.scanPortAddresses: db	SERIAL_COM7_IOADDRESS >> 2
+					db	SERIAL_COM6_IOADDRESS >> 2
+					db	SERIAL_COM5_IOADDRESS >> 2
+					db	SERIAL_COM4_IOADDRESS >> 2
+					db	SERIAL_COM3_IOADDRESS >> 2
+					db	SERIAL_COM2_IOADDRESS >> 2
+					db	SERIAL_COM1_IOADDRESS >> 2
+					db	0
+		
+
+;--------------------------------------------------------------------
+; SerialServer_CheckForServer_PortAndBaudInDX:
+;	Parameters:
+;       BH:		Drive Select byte for Drive and Head Select Register
+;               0xAx: Scan for drive, low nibble indicates drive
+;               0x0:  Scan for Server, independent of drives
+;		DX:		Baud and Port
+;		CH:		1: We are doing a scan for the serial server
+;               0: We are working off a specific port given by the user
+;		CL:		1, for one sector to read
+;		ES:SI:	Ptr to buffer for return
+;	Returns:
+;		AH:		INT 13h Error Code
+;		CF:		Cleared if success, Set if error
+;	Corrupts registers:
+;		AL, BX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SerialServerScan_CheckForServer_PortAndBaudInDX:
+		push	bp				; setup fake SerialServer_Command
+
+		push	dx				; send port baud and rate, returned in inquire packet
+								; (and possibly returned in the drive identification string)
+
+		push	cx				; send number of sectors, and if it is on a scan or not
+
+		mov		bl,SerialServer_Command_Inquire			; protocol command onto stack with bh
+		push	bx
+
+		mov		bp,sp
+		
+		call	SerialServer_SendReceive
+
+		pop		bx
+		pop		cx
+		pop		dx
+		pop		bp
+
+		ret
+
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/String/Char.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/String/Char.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/String/Char.asm	(revision 348)
@@ -0,0 +1,215 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for handling characters.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; This macro can only be used within this source file!!!
+; IS_BETWEEN_IMMEDIATES
+;	Parameters:
+;		%1:		Value to check
+;		%2:		First accepted value in range
+;		%3:		Last accepted value in range
+;	Returns:
+;		CF:		Set if character is range
+;				(Jumps to Char_CharIsNotValid if before range)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro IS_BETWEEN_IMMEDIATES 3
+	cmp		%1, %2
+	jb		SHORT Char_CharIsNotValid
+	cmp		%1, (%3)+1				; Set CF if %1 is lesser
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Char_IsLowerCaseLetterInAL
+;	Parameters:
+;		AL:		Character to check
+;	Returns:
+;		CF:		Set if character is lower case letter ('a'...'z')
+;				Cleared if character is not lower case letter
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Char_IsLowerCaseLetterInAL:
+	IS_BETWEEN_IMMEDIATES al, 'a', 'z'
+	ret
+
+;--------------------------------------------------------------------
+; Char_IsUpperCaseLetterInAL
+;	Parameters:
+;		AL:		Character to check
+;	Returns:
+;		CF:		Set if character is upper case letter ('A'...'Z')
+;				Cleared if character is not upper case letter
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Char_IsUpperCaseLetterInAL:
+	IS_BETWEEN_IMMEDIATES al, 'A', 'Z'
+	ret
+%endif
+
+;--------------------------------------------------------------------
+; Char_IsHexadecimalDigitInAL
+;	Parameters:
+;		AL:		Character to check
+;	Returns:
+;		AL:		Character converted to lower case
+;		CF:		Set if character is decimal digit ('0'...'F')
+;				Cleared if character is not decimal digit
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Char_IsHexadecimalDigitInAL:
+	call	Char_IsDecimalDigitInAL
+	jc		SHORT Char_CharIsValid
+	call	Char_ALtoLowerCaseLetter
+	IS_BETWEEN_IMMEDIATES al, 'a', 'f'
+	ret
+%endif
+
+;--------------------------------------------------------------------
+; Char_IsDecimalDigitInAL
+;	Parameters:
+;		AL:		Character to check
+;	Returns:
+;		CF:		Set if character is decimal digit ('0'...'9')
+;				Cleared if character is not decimal digit
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef MODULE_STRINGS_COMPRESSED
+ALIGN JUMP_ALIGN
+Char_IsDecimalDigitInAL:
+	IS_BETWEEN_IMMEDIATES al, '0', '9'
+	ret
+%endif
+
+;--------------------------------------------------------------------
+; Char_ConvertIntegerToALfromDigitInALwithBaseInBX
+;	Parameters:
+;		AL:		Character to convert
+;		BX:		Numeric base (10 or 16)
+;	Returns:
+;		AL:		Character converted to integer
+;		CF:		Set if character was valid
+;				Cleared if character was invalid
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Char_ConvertIntegerToALfromDigitInALwithBaseInBX:
+	push	dx
+	call	Char_GetFilterFunctionToDXforNumericBaseInBX
+	call	dx						; Converts to lower case
+	pop		dx
+	jnc		SHORT Char_CharIsNotValid
+
+	cmp		al, '9'					; Decimal digit
+	jbe		SHORT .ConvertToDecimalDigit
+	sub		al, 'a'-'0'-10			; Convert to hexadecimal integer
+ALIGN JUMP_ALIGN
+.ConvertToDecimalDigit:
+	sub		al, '0'					; Convert to decimal integer
+	; Fall to Char_CharIsValid
+%endif
+
+;--------------------------------------------------------------------
+; Char_CharIsValid
+; Char_CharIsNotValid
+;	Parameters:
+;		Nothing
+;	Returns:
+;		CF:		Set for Char_CharIsValid
+;				Cleared for Char_CharIsNotValid
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Char_CharIsValid:
+	stc
+	ret
+%endif
+
+ALIGN JUMP_ALIGN
+Char_CharIsNotValid:
+	clc
+	ret
+
+
+;--------------------------------------------------------------------
+; Char_ALtoLowerCaseLetter
+;	Parameters:
+;		AL:		Character to convert
+;	Returns:
+;		AL:		Character with possible conversion
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Char_ALtoLowerCaseLetter:
+	call	Char_IsUpperCaseLetterInAL	; Is upper case character?
+	jmp		SHORT Char_ALtoUpperCaseLetter.CheckCF
+%endif
+
+;--------------------------------------------------------------------
+; Char_ALtoUpperCaseLetter
+;	Parameters:
+;		AL:		Character to convert
+;	Returns:
+;		AL:		Character with possible conversion
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Char_ALtoUpperCaseLetter:
+	call	Char_IsLowerCaseLetterInAL	; Is lower case character?
+.CheckCF:
+	jnc		SHORT Char_ChangeCaseInAL.Return
+	; Fall to Char_ChangeCaseInAL
+
+;--------------------------------------------------------------------
+; Char_ChangeCaseInAL
+;	Parameters:
+;		AL:		Character to convert (must be A-Z or a-z)
+;	Returns:
+;		AL:		Character converted
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+Char_ChangeCaseInAL:
+	xor		al, 32
+.Return:
+	ret
+
+;--------------------------------------------------------------------
+; Char_GetFilterFunctionToDXforNumericBaseInBX
+;	Parameters
+;		BX:		Numeric base (10 or 16)
+;	Returns:
+;		CS:DX:	Ptr to character filter function
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Char_GetFilterFunctionToDXforNumericBaseInBX:
+	mov		dx, Char_IsDecimalDigitInAL
+	cmp		bl, 10
+	je		SHORT .Return
+	mov		dx, Char_IsHexadecimalDigitInAL
+.Return:
+	ret
+%endif
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/String/String.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/String/String.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/String/String.asm	(revision 348)
@@ -0,0 +1,115 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for handling characters.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; String_ConvertDSSItoLowerCase
+;	Parameters:
+;		DS:SI:	Ptr to string to convert
+;	Returns:
+;		CX:		Number of characters processed
+;		SI:		Updated
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+String_ConvertDSSItoLowerCase:
+	push	dx
+	push	ax
+
+	mov		dx, StringProcess_ConvertToLowerCase
+	call	StringProcess_DSSIwithFunctionInDX
+
+	pop		ax
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; String_ConvertWordToAXfromStringInDSSIwithBaseInBX
+;	Parameters:
+;		BX:		Numeric base (10 or 16)
+;		DS:SI:	Ptr to string to convert
+;	Returns:
+;		AX:		Word converted from string
+;		CX:		Number of characters processed
+;		SI:		Updated
+;		CF:		Cleared if successful
+;				Set if error during conversion
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+String_ConvertWordToAXfromStringInDSSIwithBaseInBX:
+	push	di
+	push	dx
+
+	xor		di, di
+	mov		dx, StringProcess_ConvertToWordInDIWithBaseInBX
+	call	StringProcess_DSSIwithFunctionInDX
+	xchg	ax, di
+
+	pop		dx
+	pop		di
+	ret
+
+
+;--------------------------------------------------------------------
+; String_CopyDSSItoESDIandGetLengthToCX
+;	Parameters:
+;		DS:SI:	Ptr to source NULL terminated string
+;		ES:DI:	Ptr to destination buffer
+;	Returns:
+;		CX:		Number of characters copied
+;		SI,DI:	Updated by CX characters
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+String_CopyDSSItoESDIandGetLengthToCX:
+	push	ax
+
+	xor		cx, cx
+ALIGN JUMP_ALIGN
+.CopyNextCharacter:
+	lodsb						; Load from DS:SI to AL
+	test	al, al				; NULL to end string?
+	jz		SHORT .EndOfString
+	stosb						; Store from AL to ES:DI
+	inc		cx					; Increment number of characters written
+	jmp		SHORT .CopyNextCharacter
+
+ALIGN JUMP_ALIGN
+.EndOfString:
+	pop		ax
+	ret
+
+
+;--------------------------------------------------------------------
+; String_GetLengthFromDSSItoCX
+;	Parameters:
+;		DS:SI:	Ptr to NULL terminated string
+;	Returns:
+;		CX:		String length in characters
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+String_GetLengthFromDSSItoCX:
+	push	ax
+	push	si
+
+	call	Registers_ExchangeDSSIwithESDI
+	xor		ax, ax		; Find NULL
+	mov		cx, -1		; Full segment if necessary
+	repne scasb
+	mov		cx, di
+	call	Registers_ExchangeDSSIwithESDI
+
+	pop		si
+	stc
+	sbb		cx, si		; Subtract NULL
+	pop		ax
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/String/StringProcess.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/String/StringProcess.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/String/StringProcess.asm	(revision 348)
@@ -0,0 +1,102 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for processing characters in a string.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Character processing callback function prototype for StringProcess_DSSIwithFunctionInDX.
+;	Parameters:
+;		AL:			Character to process
+;		CX:			Character number (index for next character)
+;		DS:SI:		Ptr to next character
+;		BX,DI,ES:	Free to use by processing function
+;	Returns:
+;		CF:			Clear to continue with next character
+;					Set to stop processing
+;		BX,DI,ES:	Free to use by processing function
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+
+
+;--------------------------------------------------------------------
+; StringProcess_DSSIwithFunctionInDX
+;	Parameters:
+;		DX:		Character processing function
+;		DS:SI:	Ptr to NULL terminated string to convert
+;	Returns:
+;		CX:		Number of characters processed
+;		CF:		Clear if all characters processed
+;				Set if terminated by processing function
+;	Corrupts registers:
+;		Nothing (processing function can corrupt BX,DI,ES)
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+StringProcess_DSSIwithFunctionInDX:
+	push	si
+	push	ax
+
+	xor		cx, cx
+ALIGN JUMP_ALIGN
+.ProcessNextCharacter:
+	lodsb
+	test	al, al				; NULL to end string
+	jz		SHORT .EndOfString	; Return with CF cleared
+	inc		cx
+	call	dx
+	jnc		SHORT .ProcessNextCharacter
+
+ALIGN JUMP_ALIGN
+.EndOfString:
+	pop		ax
+	pop		si
+	ret
+
+
+;--------------------------------------------------------------------
+; StringProcess_ConvertToLowerCase (callback function for StringProcess_DSSIwithFunctionInDX)
+;	Parameters:
+;		AL:		Character to convert to lower case
+;		DS:SI:	Ptr to next character
+;	Returns:
+;		CF:		Clear to continue processing
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+StringProcess_ConvertToLowerCase:
+	call	Char_ALtoLowerCaseLetter
+	mov		[si-1], al
+	clc
+	ret
+
+
+;--------------------------------------------------------------------
+; StringProcess_ConvertToWordInDIWithBaseInBX (callback function for StringProcess_DSSIwithFunctionInDX)
+;	Parameters:
+;		AL:		Character to convert to lower case
+;		BX:		Numeric base (2, 10 or 16)
+;	Returns:
+;		CF:		Clear to continue processing
+;				Set if error
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+StringProcess_ConvertToWordInDIWithBaseInBX:
+	call	Char_ConvertIntegerToALfromDigitInALwithBaseInBX
+	cmc
+	jc		SHORT .InvalidCharacter
+	push	dx
+
+	xor		ah, ah		; Digit converted to integer now in AX
+	xchg	ax, di
+	mul		bx			; Old WORD *= base
+	jc		SHORT .Overflow
+	add		di, ax		; Add old WORD to new integer
+
+.Overflow:
+	pop		dx
+.InvalidCharacter:
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/Delay.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/Delay.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/Delay.asm	(revision 348)
@@ -0,0 +1,63 @@
+; Project name	:	Assembly Library
+; Description	:	Delay functions.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Delay is always at least one millisecond since
+; RTC resolution is 977 microsecs.
+;
+; Delay_MicrosecondsFromAX
+;	Parameters:
+;		AX:		Number of microsecs to wait
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Delay_MicrosecondsFromAX:
+	push	dx
+	push	cx
+
+	xor		cx, cx
+	xchg	dx, ax							; Microsecs now in CX:DX
+	mov		ah, EVENT_WAIT					; Event Wait
+	int		BIOS_SYSTEM_INTERRUPT_15h
+	sti										; XT BIOSes return with interrupt disabled
+
+	pop		cx
+	pop		dx
+	mov		ax, 1							; Prepare to wait 1 timer tick
+	jc		SHORT Delay_TimerTicksFromAX	; Event Wait was unsupported or busy
+	ret
+
+
+;--------------------------------------------------------------------
+; First tick might take 0...54.9 ms and remaining ticks
+; will occur at 54.9 ms intervals.
+;
+; Delay_TimerTicksFromAX
+;	Parameters:
+;		AX:		Number of timer ticks to wait
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Delay_TimerTicksFromAX:
+	push	dx
+
+	sti							; Make sure that interrupts are enabled
+	xchg	dx, ax
+	call	TimerTicks_ReadFromBdaToAX
+	add		dx, ax				; DX = end time
+.WaitLoop:
+	call	TimerTicks_ReadFromBdaToAX
+	cmp		ax, dx
+	jb		SHORT .WaitLoop		; Loop until end time is reached
+
+	pop		dx
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/SystemTimer.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/SystemTimer.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/SystemTimer.asm	(revision 348)
@@ -0,0 +1,46 @@
+; Project name	:	Assembly Library
+; Description	:	Functions to operate with
+;					8254 Programmable Interval Timer.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; SystemTimer_IntializePreciseEventTimer
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SystemTimer_IntializePreciseEventTimer:
+	STOP_PRECISE_EVENT_TIMER
+	OUTPUT_COUNTER_COMMAND_TO TIMER_2, READ_OR_WRITE_LSB_THEN_MSB, MODE_0_SINGLE_TIMEOUT, BINARY_COUNTER
+	xor		ax, ax
+	WRITE_COUNT_FROM_AX_TO TIMER_2
+	ret
+
+
+;--------------------------------------------------------------------
+; This is how to use precise event timer:
+; 1. Call SystemTimer_IntializePreciseEventTimer
+; 2. Use START_PRECISE_EVENT_TIMER macro to start timer
+; 3. Use STOP_PRECISE_EVENT_TIMER to stop timer (optional)
+; 4. Call SystemTimer_GetPreciseEventTimerTicksToAX to get event duration
+;
+; SystemTimer_GetPreciseEventTimerTicksToAX
+;	Parameters:
+;		Nothing
+;	Returns:
+;		AX:		Event duration in timer ticks
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SystemTimer_GetPreciseEventTimerTicksToAX:
+	OUTPUT_COUNTER_COMMAND_TO TIMER_2, LATCH, MODE_0_SINGLE_TIMEOUT, BINARY_COUNTER
+	READ_COUNT_TO_AX_FROM TIMER_2
+	neg		ax					; 0 - count (Mode 0 counts toward zero)
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/TimerTicks.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/TimerTicks.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Time/TimerTicks.asm	(revision 348)
@@ -0,0 +1,150 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for system timer related operations.
+
+; System timer ticks 18.2 times per second = 54.9 ms / tick
+TICKS_PER_HOUR			EQU		65520
+TICKS_PER_MINUTE		EQU		1092
+TICKS_PER_SECOND		EQU		18
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; TimerTicks_GetHoursToAXfromTicksInDXAX
+; TimerTicks_GetMinutesToAXfromTicksInDX
+; TimerTicks_GetSecondsToAXfromTicksInDX
+;	Parameters
+;		DX(:AX):	Timer ticks to convert
+;	Returns:
+;		AX:			Hours, minutes or seconds
+;		DX:			Remainder ticks
+;	Corrupts registers:
+;		CX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+TimerTicks_GetHoursToAXfromTicksInDXAX:
+	mov		cx, TICKS_PER_HOUR
+	div		cx		; Divide DX:AX by CX, Hours to AX, remainder ticks to DX
+	ret
+
+ALIGN JUMP_ALIGN
+TimerTicks_GetMinutesToAXfromTicksInDX:
+	xor		ax, ax
+	xchg	ax, dx	; Ticks now in DX:AX
+	mov		cx, TICKS_PER_MINUTE
+	div		cx		; Divide DX:AX by CX, Minutes to AX, remainder ticks to DX
+	ret
+%endif
+
+ALIGN JUMP_ALIGN
+TimerTicks_GetSecondsToAXfromTicksInDX:
+	xchg	ax, dx	; Ticks now in AX
+	mov		cl, TICKS_PER_SECOND
+	div		cl		; Divide AX by CL, Seconds to AL, remainder ticks to AH
+	xor		dx, dx
+	xchg	dl, ah	; Seconds in AX, remainder in DX
+	ret
+
+
+;--------------------------------------------------------------------
+; First tick might take 0...54.9 ms and remaining ticks
+; will occur at 54.9 ms intervals. Use delay of two (or more) ticks to
+; ensure at least 54.9 ms timeout.
+;
+; TimerTicks_InitializeTimeoutFromAX
+;	Parameters:
+;		AX:			Timeout ticks (54.9 ms) before timeout
+;		DS:BX:		Ptr to timeout variable WORD
+;	Returns:
+;		[DS:BX]:	Initialized for TimerTicks_SetCarryIfTimeoutFromDSBX
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+TimerTicks_InitializeTimeoutFromAX:
+	mov		[bx], ax					; Store timeout ticks
+	call	TimerTicks_ReadFromBdaToAX
+	add		[bx], ax					; [bx] now contains end time for timeout
+	ret
+
+
+;--------------------------------------------------------------------
+; TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
+;	Parameters:
+;		DS:BX:		Ptr to timeout variable WORD
+;	Returns:
+;		AX:			Number of ticks left before timeout
+;		CF:			Set if timeout
+;					Cleared if time left
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+TimerTicks_GetTimeoutTicksLeftToAXfromDSBX:
+	push	dx
+	mov		dx, [bx]
+	call	TimerTicks_ReadFromBdaToAX
+	xchg	ax, dx
+	sub		ax, dx		; AX = End time - current time
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; TimerTicks_GetElapsedToAXandResetDSBX
+;	Parameters
+;		DS:BX:		Ptr to WORD containing previous reset time
+;	Returns:
+;		AX:			54.9 ms ticks elapsed since last reset
+;		[DS:BX]:	Reset to latest time
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+TimerTicks_GetElapsedToAXandResetDSBX:
+	call	TimerTicks_ReadFromBdaToAX
+	push	ax
+	sub		ax, [bx]
+	pop		WORD [bx]			; Latest time to [DS:BX]
+	ret
+%endif
+
+;--------------------------------------------------------------------
+; TimerTicks_GetElapsedToAXfromDSBX
+;	Parameters
+;		DS:BX:		Ptr to WORD containing previous update time
+;	Returns:
+;		AX:			54.9 ms ticks elapsed since initializing [DS:BX]
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+TimerTicks_GetElapsedToAXfromDSBX:
+	call	TimerTicks_ReadFromBdaToAX
+	sub		ax, [bx]
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; TimerTicks_ReadFromBdaToAX
+;	Parameters
+;		Nothing
+;	Returns:
+;		AX:		System time in 54.9 ms ticks
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+TimerTicks_ReadFromBdaToAX:
+	push	ds
+
+	LOAD_BDA_SEGMENT_TO	ds, ax
+	mov		ax, [BDA.dwTimerTicks]	; Read low WORD only
+
+	pop		ds
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/TimerTest.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/TimerTest.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/TimerTest.asm	(revision 348)
@@ -0,0 +1,187 @@
+; Project name	:	Assembly Library
+; Description	:	Tests for Assembly Library.
+
+; Include .inc files
+%define INCLUDE_DISPLAY_LIBRARY
+%define INCLUDE_TIME_LIBRARY
+%include "AssemblyLibrary.inc"	; Assembly Library. Must be included first!
+
+
+; Section containing code
+SECTION .text
+
+; Program first instruction.
+CPU 486
+ORG	100h						; Code starts at offset 100h (DOS .COM)
+Start:
+	jmp		BusMeasurements_Start
+
+; Include library sources
+%include "AssemblyLibrary.asm"
+
+%macro MOV_TIMING_LOOP 1
+	xor		bx, bx					; Offset for memory transfers
+	mov		dx, OFFSET_TO_NEXT_WORD	; Must be at least 32 (Pentium Cache Line size)
+	wbinvd							; Flush and invalidate internal cache
+	cli								; Disable interrupts
+	START_PRECISE_EVENT_TIMER
+ALIGN 8
+%%ReadNextWord:
+	mov		ax, %1					; 2 bytes
+	add		bx, dx					; 2 bytes
+	jnc		SHORT %%ReadNextWord	; 2 bytes
+	STOP_PRECISE_EVENT_TIMER
+	sti
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Program start
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+BusMeasurements_Start:
+	CALL_DISPLAY_LIBRARY InitializeDisplayContext
+	xor		ax, ax
+	mov		ds, ax
+
+	call	MeasureRegAndMemMovDurationDifferenceToAX
+	call	GetBusCycleTimeToAXfromRegAndMemMovDurationDifferenceInAX
+	call	GetBusClockRateFromCycleTimeInAX
+	mov		si, g_szBusMeasurements
+	call	PrintBusMeasurements
+
+	call	AssumeVlbCycleTimeToAXfromBusCycleTimeInCX
+	call	GetBusClockRateFromCycleTimeInAX
+	mov		si, g_szVlbAssumption
+	call	PrintBusMeasurements
+
+	; Exit to DOS
+	mov 	ax, 4C00h			; Exit to DOS
+	int 	21h
+
+
+
+;--------------------------------------------------------------------
+; MeasureRegAndMemMovDurationDifferenceToAX
+;	Parameters:
+;		DS:		Segment for memory read tests
+;	Returns:
+;		AX:		Difference in register and memory access durations
+;				(Precise Event Timer Ticks)
+;	Corrupts registers:
+;		BX, CX, DX
+;--------------------------------------------------------------------
+MeasureRegAndMemMovDurationDifferenceToAX:
+	call	SystemTimer_IntializePreciseEventTimer
+
+	MOV_TIMING_LOOP	bx
+	call	SystemTimer_GetPreciseEventTimerTicksToAX
+	xchg	cx, ax		; Duration now in CX
+
+	MOV_TIMING_LOOP [bx]
+	call	SystemTimer_GetPreciseEventTimerTicksToAX
+	sub		ax, cx		; AX = Difference in durations
+	sub		ax, cx
+	ret
+
+
+;--------------------------------------------------------------------
+; We must divide the duration by 4 since the timing loop loads
+; whole cache line (4 times the bus width) instead of single BYTE.
+;
+; GetBusCycleTimeToAXfromRegAndMemMovDurationDifferenceInAX
+;	Parameters:
+;		AX:		Difference in register and memory access durations
+;				(Precise Event Timer Ticks)	
+;	Returns:
+;		AX:		Duration for single BYTE in nanosecs
+;	Corrupts registers:
+;		CX, DX
+;--------------------------------------------------------------------
+GetBusCycleTimeToAXfromRegAndMemMovDurationDifferenceInAX:
+	mov		dx, TIMER_CYCLE_TIME
+	mul		dx			; DX:AX = Duration in nanosecs
+	mov		cx, (65536 / OFFSET_TO_NEXT_WORD) * 4
+	div		cx			; AX = Duration for single BYTE in nanosecs
+	ret
+
+
+;--------------------------------------------------------------------
+; GetBusClockRateFromCycleTimeInAX
+;	Parameters:
+;		AX:		Bus Cycle Time in nanosecs
+;	Returns:
+;		CX:		Bus Cycle Time in nanosecs
+;		DX:		Bus Clock Rate (MHz)
+;		AX:		Clock Rate tenths
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+GetBusClockRateFromCycleTimeInAX:
+	xchg	cx, ax
+	xor		dx, dx
+	mov		ax, 1000
+	div		cl			; AL = MHz, AH = Remainder
+	xchg	al, dl		; DX = Bus Clock Rate, AL = 0
+	aad					; AX = 10 * AH (+AL)
+	div		cl
+	xor		ah, ah		; AX = Tenths
+	ret
+
+
+;--------------------------------------------------------------------
+; AssumeVlbCycleTimeToAXfromBusCycleTimeInCX
+;	Parameters:
+;		CX:		Bus Cycle Time in nanosecs
+;	Returns:
+;		AX:		Assumed VLB Cycle Time in nanosecs
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+AssumeVlbCycleTimeToAXfromBusCycleTimeInCX:
+	mov		ax, cx
+	cmp		al, 24		; 25 = 40 MHz
+	jb		SHORT .AssumePentiumSoDivideBy2
+	ret
+.AssumePentiumSoDivideBy2:
+	shr		ax, 1
+	ret
+
+
+;--------------------------------------------------------------------
+; PrintBusMeasurements
+;	Parameters:
+;		CX:		Bus Cycle Time in nanosecs
+;		DX:		Bus Clock Rate (MHz)
+;		AX:		Clock Rate tenths
+;		SI:		Offset to string to format
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, DX, BP
+;--------------------------------------------------------------------
+PrintBusMeasurements:
+	mov		bp, sp
+	push	cx
+	push	dx
+	push	ax
+	CALL_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
+	ret
+
+
+
+; Section containing initialized data
+SECTION .data
+
+OFFSET_TO_NEXT_WORD		EQU	32	; Must be at least 32 (Pentium Cache Line size)
+
+g_szBusMeasurements:
+	db	"Detected bus cycle time of %u ns (%u.%u MHz) ",LF,CR,NULL
+g_szVlbAssumption:
+	db	"Assuming VLB (if exists) cycle time of %u ns (%u.%u MHz) ",LF,CR,NULL
+g_szDashForZero:		db		"- ",NULL
+
+
+
+; Section containing uninitialized data
+SECTION .bss
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Bit.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Bit.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Bit.asm	(revision 348)
@@ -0,0 +1,100 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for bit handling.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Bit_GetSetCountToCXfromDXAX
+;	Parameters
+;		DX:AX:		Source DWORD
+;	Returns:
+;		CX:		Number of bits set in DX:AX
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Bit_GetSetCountToCXfromDXAX:
+	push	bx
+
+	call	Bit_GetSetCountToCXfromAX
+	mov		bx, cx
+	xchg	ax, dx
+	call	Bit_GetSetCountToCXfromAX
+	xchg	ax, dx
+	add		cx, bx
+
+	pop		bx
+	ret
+
+
+;--------------------------------------------------------------------
+; Bit_GetSetCountToCXfromAX
+;	Parameters
+;		AX:		Source WORD
+;	Returns:
+;		CX:		Number of bits set in AX
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Bit_GetSetCountToCXfromAX:
+	push	ax
+
+	xor		cx, cx
+ALIGN JUMP_ALIGN
+.BitScanLoop:
+	shr		ax, 1
+	jz		SHORT .LastBitInCF
+	adc		cl, ch
+	jmp		SHORT .BitScanLoop
+ALIGN JUMP_ALIGN
+.LastBitInCF:
+	adc		cl, ch
+
+	pop		ax
+	ret
+
+
+;--------------------------------------------------------------------
+; Bit_SetToDXAXfromIndexInCL
+;	Parameters:
+;		CL:		Index of bit to set (0...31)
+;		DX:AX:	Destination DWORD with flag to be set
+;	Returns:
+;		DX:AX:	DWORD with wanted bit set
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Bit_SetToDXAXfromIndexInCL:
+	cmp		cl, 16
+	jb		SHORT Bit_SetToAXfromIndexInCL
+
+	sub		cl, 16
+	xchg	ax, dx
+	call	Bit_SetToAXfromIndexInCL
+	xchg	dx, ax
+	add		cl, 16
+	ret
+
+;--------------------------------------------------------------------
+; Bit_SetToAXfromIndexInCL
+;	Parameters:
+;		CL:		Index of bit to set (0...15)
+;		AX:		Destination WORD with flag to be set
+;	Returns:
+;		AX:		WORD with wanted bit set
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Bit_SetToAXfromIndexInCL:
+	push	dx
+
+	mov		dx, 1
+	shl		dx, cl
+	or		ax, dx
+
+	pop		dx
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Math.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Math.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Math.asm	(revision 348)
@@ -0,0 +1,64 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for register operations.
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Math_DivQWatSSBPbyCX
+;	Parameters:
+;		[SS:BP]:	64-bit unsigned divident
+;		CX:			16-bit unsigned divisor
+;	Returns:
+;		[SS:BP]:	64-bit unsigned quotient
+;		DX:			16-bit unsigned remainder
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDECFG	; Not used in XTIDECFG
+ALIGN JUMP_ALIGN
+Math_DivQWatSSBPbyCX:
+	xor		dx, dx
+	mov		ax, [bp+6]		; Load highest divident WORD to DX:AX
+	div		cx
+	mov		[bp+6], ax		; Store quotient
+
+	mov		ax, [bp+4]
+	div		cx
+	mov		[bp+4], ax
+
+	mov		ax, [bp+2]
+	div		cx
+	mov		[bp+2], ax
+
+	mov		ax, [bp]
+	div		cx
+	mov		[bp], ax
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Math_DivDXAXbyCX
+;	Parameters:
+;		DX:AX:	32-bit unsigned divident
+;		CX:		16-bit unsigned divisor
+;	Returns:
+;		DX:AX:	32-bit unsigned quotient
+;		BX:		16-bit unsigned remainder
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS OR EXCLUDE_FROM_XTIDECFG
+ALIGN JUMP_ALIGN
+Math_DivDXAXbyCX:	; This is currently unused (dead code)
+	xor		bx, bx
+	xchg	bx, ax
+	xchg	dx, ax
+	div		cx
+	xchg	ax, bx
+	div		cx
+	xchg	dx, bx
+	ret
+%endif
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Memory.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Memory.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Memory.asm	(revision 348)
@@ -0,0 +1,127 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for memory access.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; OPTIMIZE_STRING_OPERATION
+;	Parameters
+;		%1:		Repeat instruction
+;		%2:		String instruction without size (for example MOVS and not MOVSB or MOVSW)
+;		CX:		Number of BYTEs to operate
+;		DS:SI:	Ptr to source data
+;		ES:DI:	Ptr to destination
+;	Returns:
+;		SI, DI:	Updated by number of bytes operated
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%macro OPTIMIZE_STRING_OPERATION 2
+	push	cx
+
+	shr		cx, 1			; Operate with WORDs for performance
+	jz	%%HandleRemainingByte
+	%1		%2w
+%%HandleRemainingByte:
+	jnc		SHORT %%OperationCompleted
+	%2b
+
+ALIGN JUMP_ALIGN
+%%OperationCompleted:
+	pop		cx
+%endmacro
+
+
+;--------------------------------------------------------------------
+; Memory_CopyCXbytesFromDSSItoESDI
+;	Parameters
+;		CX:		Number of bytes to copy
+;		DS:SI:	Ptr to source data
+;		ES:DI:	Ptr to destination buffer
+;	Returns:
+;		SI, DI:	Updated by number of bytes copied
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Memory_CopyCXbytesFromDSSItoESDI:
+	OPTIMIZE_STRING_OPERATION rep, movs
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Memory_ZeroSSBPwithSizeInCX
+;	Parameters
+;		CX:		Number of bytes to zero
+;		SS:BP:	Ptr to buffer to zero
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Memory_ZeroSSBPwithSizeInCX:
+	push	es
+	push	di
+	push	ax
+	call	Registers_CopySSBPtoESDI
+	call	Memory_ZeroESDIwithSizeInCX
+	pop		ax
+	pop		di
+	pop		es
+	ret
+
+;--------------------------------------------------------------------
+; Memory_ZeroESDIwithSizeInCX
+;	Parameters
+;		CX:		Number of bytes to zero
+;		ES:DI:	Ptr to destination buffer
+;	Returns:
+;		DI:		Updated by number of BYTEs stored
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Memory_ZeroESDIwithSizeInCX:
+	xor		ax, ax
+	; Fall to Memory_StoreCXbytesFromAccumToESDI
+
+;--------------------------------------------------------------------
+; Memory_StoreCXbytesFromAccumToESDI
+;	Parameters
+;		AX:		Word to use to fill buffer
+;		CX:		Number of BYTEs to store
+;		ES:DI:	Ptr to destination buffer
+;	Returns:
+;		DI:		Updated by number of BYTEs stored
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Memory_StoreCXbytesFromAccumToESDI:
+	OPTIMIZE_STRING_OPERATION rep, stos
+	ret
+
+
+;--------------------------------------------------------------------
+; Memory_ReserveCXbytesFromStackToDSSI
+;	Parameters
+;		CX:		Number of bytes to reserve
+;	Returns:
+;		DS:SI:	Ptr to reserved buffer
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Memory_ReserveCXbytesFromStackToDSSI:
+	pop		ax
+	push	ss
+	pop		ds
+	sub		sp, cx
+	mov		si, sp
+	jmp		ax
+%endif
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Reboot.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Reboot.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Reboot.asm	(revision 348)
@@ -0,0 +1,57 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for rebooting computer.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Reboot_ComputerWithBootFlagInAX
+;	Parameters:
+; 		AX:		Boot Flag
+;	Returns:
+;		Nothing, function never returns
+;--------------------------------------------------------------------
+Reboot_ComputerWithBootFlagInAX:
+	LOAD_BDA_SEGMENT_TO	ds, bx
+	mov		[BDA.wBoot], ax			; Store boot flag
+	; Fall to Reboot_AT
+
+
+;--------------------------------------------------------------------
+; Reboot_AT
+;	Parameters:
+; 		Nothing
+;	Returns:
+;		Nothing, function never returns
+;--------------------------------------------------------------------
+Reboot_AT:
+	mov		al, 0FEh				; System reset (AT+ keyboard controller)
+	out		64h, al					; Reset computer (AT+)
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+	%ifdef INCLUDE_TIME_LIBRARY
+		mov		ax, 10
+		call	Delay_MicrosecondsFromAX
+	%else
+		JMP_DELAY
+	%endif
+%else
+	JMP_DELAY
+%endif
+	; Fall to Reboot_XT
+
+
+;--------------------------------------------------------------------
+; Reboot_XT
+;	Parameters:
+; 		Nothing
+;	Returns:
+;		Nothing, function never returns
+;--------------------------------------------------------------------
+Reboot_XT:
+	xor		ax, ax
+	push	ax
+	popf							; Clear FLAGS (disables interrupt)
+	mov		ds, ax
+	mov		es, ax
+	mov		ss, ax
+	jmp		0FFFFh:0				; XT reset
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Registers.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Registers.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Registers.asm	(revision 348)
@@ -0,0 +1,114 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for register operations.
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Registers_ExchangeDSSIwithESDI
+;	Parameters
+;		Nothing
+;	Returns:
+;		DS:SI and ES:DI are exchanged.
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Registers_ExchangeDSSIwithESDI:
+	push	ds
+	push	es
+	pop		ds
+	pop		es
+	xchg	si, di
+	ret
+
+
+;--------------------------------------------------------------------
+; Registers_CopySSBPtoESDI
+; Registers_CopySSBPtoDSSI
+; Registers_CopyDSSItoESDI
+; Registers_CopyESDItoDSSI
+;	Parameters
+;		Nothing
+;	Returns:
+;		Copies farm pointer to different segment/pointer register pair
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Registers_CopySSBPtoESDI:
+	COPY_SSBP_TO_ESDI
+	ret
+
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Registers_CopySSBPtoDSSI:
+	COPY_SSBP_TO_DSSI
+	ret
+
+ALIGN JUMP_ALIGN
+Registers_CopyDSSItoESDI:
+	COPY_DSSI_TO_ESDI
+	ret
+
+ALIGN JUMP_ALIGN
+Registers_CopyESDItoDSSI:
+	COPY_ESDI_to_DSSI
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Registers_NormalizeESSI
+; Registers_NormalizeESDI
+;	Parameters
+;		DS:SI or ES:DI:	Ptr to normalize
+;	Returns:
+;		DS:SI or ES:DI:	Normalized pointer
+;	Corrupts registers:
+;		AX, CX
+; 
+; Inline of NORMALIZE_FAR_POINTER so that we can share the last 2/3 of the 
+; routine with Registers_NormalizeFinish.
+; 
+;--------------------------------------------------------------------
+%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
+ALIGN JUMP_ALIGN
+Registers_NormalizeESSI:
+	mov			cx, si
+	and			si, byte 0fh
+	jmp			Registers_NormalizeFinish
+
+ALIGN JUMP_ALIGN
+Registers_NormalizeESDI:
+	mov			cx, di
+	and			di, byte 0fh
+;;; fall-through
+
+ALIGN JUMP_ALIGN		
+Registers_NormalizeFinish:		
+	eSHR_IM		cx, 4
+	mov			ax, es
+	add			ax, cx
+	mov			es, ax
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; Registers_SetZFifNullPointerInDSSI (commented to save bytes)
+;	Parameters
+;		DS:SI:	Far pointer
+;	Returns:
+;		ZF:		Set if NULL pointer in DS:SI
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+;ALIGN JUMP_ALIGN
+;Registers_SetZFifNullPointerInDSSI:
+;	push	ax
+;	mov		ax, ds
+;	or		ax, si
+;	pop		ax
+;	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Size.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Size.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Size.asm	(revision 348)
@@ -0,0 +1,115 @@
+; Project name	:	Assembly Library
+; Description	:	Functions for size calculations.
+
+struc BYTE_MULTIPLES
+	.B			resb	1
+	.kiB		resb	1
+	.MiB		resb	1
+	.GiB		resb	1
+	.TiB		resb	1
+endstruc
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Size_GetSizeToAXAndCharToDLfromBXDXAXwithMagnitudeInCX
+;	Parameters:
+;		BX:DX:AX:	Size in magnitude
+;		CX:			Magnitude in BYTE_MULTIPLES
+;	Returns:
+;		AX:			Size in magnitude
+;		CX:			Tenths
+;		DL:			Magnitude character:
+;						'k' = *1024   B = kiB
+;						'M' = *1024 kiB = MiB
+;						'G' = *1024 MiB = GiB
+;						'T' = *1024 GiB = TiB
+;						'P' = *1024 TiB = PiB
+;	Corrupts registers:
+;		BX, DH
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Size_GetSizeToAXAndCharToDLfromBXDXAXwithMagnitudeInCX:
+%ifndef USE_186		; If 8086/8088
+	push	di
+%endif
+	push	si
+
+ALIGN JUMP_ALIGN
+.MagnitudeConversionLoop:
+	ePUSH_T	di, .MagnitudeConversionLoop; DI corrupted only on 8086/8088 build
+	test	bx, bx						; Bits 32...47 in use?
+	jnz		SHORT Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
+	test	dx, dx						; Bits 16...31 in use?
+	jnz		SHORT Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
+	cmp		ax, 10000					; 5 digits needed?
+	jae		SHORT Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
+	add		sp, BYTE 2					; Clean return address from stack
+	xchg	si, cx						; CX = Remainder (0...1023), SI = Magnitude
+
+	; Convert remainder to tenths
+	xchg	bx, ax						; Store AX
+	mov		ax, 10
+	mul		cx							; DX:AX = remainder * 10
+	eSHR_IM	ax, 10						; Divide AX by 1024
+	xchg	cx, ax						; CX = tenths
+	xchg	ax, bx
+
+	; Convert magnitude to character
+	mov		dl, [cs:si+.rgbMagnitudeToChar]
+
+	pop		si
+%ifndef USE_186
+	pop		di
+%endif
+	ret
+.rgbMagnitudeToChar:	db	" kMGTP"
+
+
+;--------------------------------------------------------------------
+; Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
+;	Parameters:
+;		BX:DX:AX:	Size
+;		CX:			Magnitude in BYTE_MULTIPLES
+;	Returns:
+;		BX:DX:AX:	Size in magnitude
+;		SI:			Remainder (0...1023)
+;		CX:			Magnitude in BYTE_MULTIPLES
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX:
+	push	cx
+	xor		si, si					; Zero remainder
+	mov		cl, 10					; Divide by 1024
+ALIGN JUMP_ALIGN
+.ShiftLoop:
+	call	Size_DivideBXDXAXbyTwo
+	rcr		si, 1					; Update remainder
+	loop	.ShiftLoop
+	eSHR_IM	si, 6					; Remainder to SI beginning
+	pop		cx
+	inc		cx						; Increment magnitude
+	ret
+
+
+;--------------------------------------------------------------------
+; Size_ConvertSectorCountInBXDXAXtoKiB
+; Size_DivideBXDXAXbyTwo
+;	Parameters:
+;		BX:DX:AX:	Total sector count
+;	Returns:
+;		BX:DX:AX:	Total size in kiB
+;		CF:			Remainder from division
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Size_ConvertSectorCountInBXDXAXtoKiB:
+Size_DivideBXDXAXbyTwo:
+	shr		bx, 1					; Divide sector count by 2...
+	rcr		dx, 1					; ...to get disk size in...
+	rcr		ax, 1					; ...kiB
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Sort.asm
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Sort.asm	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/Src/Util/Sort.asm	(revision 348)
@@ -0,0 +1,311 @@
+; File name		:	Sort.asm
+; Project name	:	Assembly Library
+; Created date	:	28.9.2010
+; Last update	:	24.10.2010
+; Author		:	Tomi Tilli
+; Description	:	Sorting algorithms
+
+; Algorith is from http://www.algolist.net/Algorithms/Sorting/Quicksort
+
+struc QSORT_PARAMS
+	.lpItems			resb	4
+	.tempAndPivotItems:
+endstruc
+
+;--------------------------------------------------------------------
+; Prototype for comparator callback function
+;	Parameters:
+;		CX:		Item size in bytes
+;		DS:SI:	Ptr to first item to compare
+;		ES:DI:	Ptr to second item to compare
+;	Returns:
+;		FLAGS:	Signed comparition between first and second item
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Sort_ItemsFromDSSIwithCountInDXsizeInCXandComparatorInBX
+;	Parameters:
+;		CX:		Item size in bytes
+;		DX:		Number of items to sort (signed)
+;		CS:BX:	Comparator function
+;		DS:SI:	Ptr to array of items to sort
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Sort_ItemsFromDSSIwithCountInDXsizeInCXandComparatorInBX:
+	push	es
+	push	di
+	mov		di, cx
+	shl		cx, 1						; Reserve temp and pivot items
+	add		cx, BYTE QSORT_PARAMS_size
+	eENTER_STRUCT cx
+	push	cx
+
+	cld
+	mov		cx, di						; Restore item size to CX
+	xor		ax, ax						; Zero starting index
+	dec		dx							; Count to index of last item
+	mov		[bp+QSORT_PARAMS.lpItems], si
+	mov		[bp+QSORT_PARAMS.lpItems+2], ds
+	call	QuicksortItemsInRangeFromAXtoDXwithQsortParamsInSSBP
+
+	lds		si, [bp+QSORT_PARAMS.lpItems]
+	pop		ax
+	eLEAVE_STRUCT ax
+	pop		di
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; QuicksortItemsInRangeFromAXtoDXwithQsortParamsInSSBP
+;	Parameters:
+;		AX:		Index of first item in range
+;		BX:		Comparator function
+;		CX:		Size of struct in bytes
+;		DX:		Index of last (included) item in range
+;		SS:BP:	Ptr to QSORT_PARAMS
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		DS, ES
+;		AX, DX (not for recursion)
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+QuicksortItemsInRangeFromAXtoDXwithQsortParamsInSSBP:
+	push	di
+	push	si
+
+	mov		si, ax			; First index to SI
+	mov		di, dx			; Last index to DI
+	call	ArrangeItemsInRangeAXtoDXusingMiddleItemAsPivot
+
+	; Does left partition need more sorting
+	cmp		si, dx			; if (first index < Index of rightmost unsorted item)
+	jge		SHORT .CheckIfRightPartitionNeedsMoreSorting
+	xchg	ax, si			; AX = first index, SI = Index of leftmost unsorted item
+	call	QuicksortItemsInRangeFromAXtoDXwithQsortParamsInSSBP
+	xchg	ax, si			; AX = Index of leftmost unsorted item
+
+.CheckIfRightPartitionNeedsMoreSorting:
+	cmp		ax, di			; if (Index of leftmost unsorted item < last index)
+	jge		SHORT .SortCompleted
+	mov		dx, di			; DI = Index of leftmost unsorted item
+	call	QuicksortItemsInRangeFromAXtoDXwithQsortParamsInSSBP
+
+ALIGN JUMP_ALIGN
+.SortCompleted:
+	pop		si
+	pop		di
+	ret
+
+
+;--------------------------------------------------------------------
+; ArrangeItemsInRangeAXtoDXusingMiddleItemAsPivot
+;	Parameters:
+;		AX:		Index of first item in range
+;		BX:		Comparator function
+;		CX:		Size of struct in bytes
+;		DX:		Index of last (included) item in range
+;		SS:BP:	Ptr to QSORT_PARAMS
+;	Returns:
+;		AX:		Index of first unsorted item
+;		DX:		Index of last unsorted item
+;	Corrupts registers:
+;		DS, ES
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ArrangeItemsInRangeAXtoDXusingMiddleItemAsPivot:
+	push	di
+	push	si
+
+	call	.GetPivotPointerToESDI
+	call	ArrangeItemsInRangeAXtoDXtoBothSidesOfPivotInESDI
+
+	pop		si
+	pop		di
+	ret
+
+ALIGN JUMP_ALIGN
+.GetPivotPointerToESDI:
+	push	ax
+
+	add		ax, dx
+	shr		ax, 1			; AX = Middle index in partition
+	call	GetItemPointerToDSSIfromIndexInAX
+	call	GetPointerToTemporaryItemToESDI
+	add		di, cx			; Pivot is after temporary item
+	call	CopyItemFromDSSItoESDI
+	sub		di, cx			; Restore DI
+
+	pop		ax
+	ret
+
+
+;--------------------------------------------------------------------
+; ArrangeItemsInRangeAXtoDXtoBothSidesOfPivotInESDI
+;	Parameters:
+;		AX:		Index of first item in range
+;		BX:		Comparator function
+;		CX:		Size of struct in bytes
+;		DX:		Index of last (included) item in range
+;		ES:DI:	Ptr to Pivot item
+;		SS:BP:	Ptr to QSORT_PARAMS
+;	Returns:
+;		AX:		Index of first unsorted item
+;		DX:		Index of last unsorted item
+;	Corrupts registers:
+;		SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ArrangeItemsInRangeAXtoDXtoBothSidesOfPivotInESDI:
+	cmp		ax, dx	; while (left <= right)
+	jg		SHORT .BreakLoopSinceAllItemsExamined
+
+	call	GetItemPointerToDSSIfromIndexInAX
+	call	.GetIndexOfLeftmostItemToAXforItemThatIsGreaterThanEqualToPivotInESDI
+
+	call	GetItemPointerToDSSIfromIndexInDX
+	call	.GetIndexOfRightmostItemToDXforItemThatIsGreaterThanPivotInESDI
+
+	cmp		ax, dx	; If (left <= right)
+	jg		SHORT ArrangeItemsInRangeAXtoDXtoBothSidesOfPivotInESDI
+	call	SwapItemsFromIndexesAXandDX
+	inc		ax
+	dec		dx
+	jmp		SHORT ArrangeItemsInRangeAXtoDXtoBothSidesOfPivotInESDI
+
+ALIGN JUMP_ALIGN
+.GetIndexOfLeftmostItemToAXforItemThatIsGreaterThanEqualToPivotInESDI:
+	call	bx
+	jge		SHORT .NoNeedToIncrementOrDecrementAnyMore
+	inc		ax				; Increment item index
+	add		si, cx			; Point to next struct
+	jmp		SHORT .GetIndexOfLeftmostItemToAXforItemThatIsGreaterThanEqualToPivotInESDI
+
+ALIGN JUMP_ALIGN
+.GetIndexOfRightmostItemToDXforItemThatIsGreaterThanPivotInESDI:
+	call	bx
+	jle		SHORT .NoNeedToIncrementOrDecrementAnyMore
+	dec		dx
+	sub		si, cx
+	jmp		SHORT .GetIndexOfRightmostItemToDXforItemThatIsGreaterThanPivotInESDI
+
+ALIGN JUMP_ALIGN
+.NoNeedToIncrementOrDecrementAnyMore:
+.BreakLoopSinceAllItemsExamined:
+	ret
+
+
+;--------------------------------------------------------------------
+; SwapItemsFromIndexesAXandDX
+;	Parameters:
+;		AX:		Index of item 1
+;		CX:		Size of struct in bytes
+;		DX:		Index of item 2
+;		SS:BP:	Ptr to QSORT_PARAMS
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		SI, DS
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+SwapItemsFromIndexesAXandDX:
+	push	es
+	push	di
+
+	; Item AX to stack
+	call	GetPointerToTemporaryItemToESDI
+	call	GetItemPointerToDSSIfromIndexInAX
+	call	CopyItemFromDSSItoESDI
+
+	; Item DX to Item AX
+	call	Registers_ExchangeDSSIwithESDI
+	call	GetItemPointerToDSSIfromIndexInDX
+	call	CopyItemFromDSSItoESDI
+
+	; Stack to Item DX
+	call	GetPointerToTemporaryItemToESDI
+	call	Registers_ExchangeDSSIwithESDI
+	call	CopyItemFromDSSItoESDI
+
+	pop		di
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; GetPointerToTemporaryItemToESDI
+;	Parameters:
+;		SS:BP:	Ptr to QSORT_PARAMS
+;	Returns:
+;		ES:DI:	Ptr to temporary item
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetPointerToTemporaryItemToESDI:
+	lea		di, [bp+QSORT_PARAMS.tempAndPivotItems]
+	push	ss
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; GetItemPointerToDSSIfromIndexInDX
+; GetItemPointerToDSSIfromIndexInAX
+;	Parameters:
+;		AX or DX:	Item index
+;		CX:			Size of struct in bytes
+;		SS:BP:		Ptr to QSORT_PARAMS
+;	Returns:
+;		DS:SI:		Ptr to item
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetItemPointerToDSSIfromIndexInDX:
+	xchg	ax, dx
+	call	GetItemPointerToDSSIfromIndexInAX
+	xchg	dx, ax
+	ret
+
+ALIGN JUMP_ALIGN
+GetItemPointerToDSSIfromIndexInAX:
+	push	dx
+	push	ax
+
+	mul		cx		; DX:AX = index (AX) * size of struct (CX)
+	lds		si, [bp+QSORT_PARAMS.lpItems]
+	add		si, ax
+
+	pop		ax
+	pop		dx
+	ret
+
+
+;--------------------------------------------------------------------
+; CopyItemFromDSSItoESDI
+;	Parameters:
+;		CX:		Item size in bytes
+;		DS:SI:	Ptr to source item
+;		ES:DI:	Ptr to destination buffer
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CopyItemFromDSSItoESDI:
+	call	Memory_CopyCXbytesFromDSSItoESDI
+	sub		si, cx			; Restore SI
+	ret
Index: /tags/Assembly_Library_for_v2.0.0beta1/gpl-2.0.txt
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/gpl-2.0.txt	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/gpl-2.0.txt	(revision 348)
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: /tags/Assembly_Library_for_v2.0.0beta1/makefile
===================================================================
--- /tags/Assembly_Library_for_v2.0.0beta1/makefile	(revision 348)
+++ /tags/Assembly_Library_for_v2.0.0beta1/makefile	(revision 348)
@@ -0,0 +1,126 @@
+###############################################################################
+# Generic makefile for building BIOS binary file.                             #
+# v. 1.0.0 (28.7.2007 ... 27.6.2010)                                          #
+# (C) Tomi Tilli                                                              #
+# aitotat@gmail.com                                                           #
+#                                                                             #
+# Valid makefile targets are:                                                 #
+# all		Removes existing files and builds binary file in \Build           #
+# build		Builds binary file in \Build                                      #
+# clean		Removes all files from \Build                                     #
+#                                                                             #
+# Build directory must be created manually if it does not exist.              #
+#                                                                             #
+###############################################################################
+
+###########################################
+# Source files and destination executable #
+###########################################
+
+# Assembly source code file (*.asm):
+#SRC_ASM = Src/LibraryTests.asm
+SRC_ASM = Src/TimerTest.asm
+#SRC_ASM = Src/LibSizeCheck.asm
+
+# Program executable file name without extension:
+PROG = test
+EXTENSION = com
+
+
+#######################################
+# Destination and include directories #
+#######################################
+
+# Directory where binary file will be compiled to
+BUILD_DIR = Build
+
+# Subdirectories where included files are:
+HEADERS = Inc/
+HEADERS += Src/
+HEADERS += Src/Display/
+HEADERS += Src/File/
+HEADERS += Src/Keyboard/
+HEADERS += Src/Menu/
+HEADERS += Src/Menu/Dialog/
+HEADERS += Src/String/
+HEADERS += Src/Time/
+HEADERS += Src/Util/
+
+
+#################################################################
+# Assembler preprocessor defines.                               #
+#################################################################
+DEFINES =
+DEFINES_XT = ELIMINATE_CGA_SNOW
+DEFINES_XTPLUS = USE_186 ELIMINATE_CGA_SNOW
+DEFINES_AT = USE_186 USE_286 USE_AT
+
+
+###################
+# Other variables #
+###################
+
+# Add -D in front of every preprocessor define declaration
+DEFS = $(DEFINES:%=-D%)
+DEFS_XT = $(DEFINES_XT:%=-D%)
+DEFS_XTPLUS = $(DEFINES_XTPLUS:%=-D%)
+DEFS_AT = $(DEFINES_AT:%=-D%)
+
+# Add -I in front of all header directories
+IHEADERS = $(HEADERS:%=-I%)
+
+# Path + target file to be built
+TARGET = $(BUILD_DIR)/$(PROG)
+
+
+#########################
+# Compilers and linkers #
+#########################
+
+# Make
+MAKE = mingw32-make.exe
+
+# Assembler
+AS = nasm.exe
+
+# use this command to erase files.
+RM = -del /Q
+
+
+#############################
+# Compiler and linker flags #
+#############################
+
+# Assembly compiler flags
+ASFLAGS = -f bin				# Produce binary object files
+ASFLAGS += $(DEFS)				# Preprocessor defines
+ASFLAGS += $(IHEADERS)			# Set header file directory paths
+ASFLAGS += -Worphan-labels		# Warn about labels without colon
+ASFLAGS += -O9					# Optimize operands to their shortest forms
+
+
+############################################
+# Build process. Actual work is done here. #
+############################################
+
+.PHONY: all at xtplus xt clean
+
+# Make clean debug and release versions
+all: clean at xtplus xt
+	@echo All done!
+
+at:
+	@$(AS) "$(SRC_ASM)" $(ASFLAGS) $(DEFS_AT) -l"$(TARGET)_at.lst" -o"$(TARGET)_at.$(EXTENSION)"
+	@echo AT version "$(TARGET)_at.$(EXTENSION)" built.
+
+xtplus:
+	@$(AS) "$(SRC_ASM)" $(ASFLAGS) $(DEFS_XTPLUS) -l"$(TARGET)_xtp.lst" -o"$(TARGET)_xtp.$(EXTENSION)"
+	@echo XT plus version "$(TARGET)_xtp.$(EXTENSION)" built.
+
+xt:
+	@$(AS) "$(SRC_ASM)" $(ASFLAGS) $(DEFS_XT) -l"$(TARGET)_xt.lst" -o"$(TARGET)_xt.$(EXTENSION)"
+	@echo XT version "$(TARGET)_xt.$(EXTENSION)" built.
+
+clean:
+	@$(RM) $(BUILD_DIR)\*.*
+	@echo Deleted "(*.*)" from "$(BUILD_DIR)/"
