Index: /trunk/Assembly_Library/Src/Display/DisplayCharOut.asm
===================================================================
--- /trunk/Assembly_Library/Src/Display/DisplayCharOut.asm	(revision 41)
+++ /trunk/Assembly_Library/Src/Display/DisplayCharOut.asm	(revision 42)
@@ -2,5 +2,5 @@
 ; Project name	:	Assembly Library
 ; Created date	:	26.6.2010
-; Last update	:	13.8.2010
+; Last update	:	18.9.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Functions for outputting characters to video memory.
@@ -13,4 +13,29 @@
 
 ;--------------------------------------------------------------------
+; WAIT_RETRACE_IF_NECESSARY_THEN
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output (stosw only)
+;		DS:		BDA segment (zero)
+;		ES:DI:	Ptr to video memory where to output
+;	Returns:
+;		DI:		Incremented for next character
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+%macro WAIT_RETRACE_IF_NECESSARY_THEN 1
+%ifdef ELIMINATE_CGA_SNOW
+	%ifidn %1, stosb
+		call	StosbWithoutCgaSnow
+	%else
+		call	StoswWithoutCgaSnow
+	%endif
+%else
+	%1			; STOSB or STOSW
+%endif
+%endmacro
+
+
+;--------------------------------------------------------------------
 ; DisplayCharOut_TeletypeOutputWithAttribute
 ; DisplayCharOut_TeletypeOutput
@@ -29,5 +54,5 @@
 	cmp		al, ' '							; Printable character?
 	jb		SHORT DisplayCharOut_BiosTeletypeOutput
-	stosw
+	WAIT_RETRACE_IF_NECESSARY_THEN stosw
 	ret
 
@@ -85,9 +110,10 @@
 ;		AL:		Character to output
 ;		AH:		Attribute to output
-;		ES:DI:	Ptr to video memory where to output
-;	Returns:
-;		DI:		Incremented for next character
-;	Corrupts registers:
-;		AX
+;		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
@@ -95,10 +121,10 @@
 	xchg	al, ah				; Swap character and attribute
 	inc		di					; Skip character
-	stosb
+	WAIT_RETRACE_IF_NECESSARY_THEN stosb
 	ret
 
 ALIGN JUMP_ALIGN
 DisplayCharOut_Character:
-	stosb
+	WAIT_RETRACE_IF_NECESSARY_THEN stosb
 	inc		di					; Skip attribute
 	ret
@@ -106,5 +132,5 @@
 ALIGN JUMP_ALIGN
 DisplayCharOut_CharacterWithAttribute:
-	stosw
+	WAIT_RETRACE_IF_NECESSARY_THEN stosw
 	ret
 
@@ -129,2 +155,101 @@
 .BufferFull:
 	ret
+
+
+; STOSB and STOSW replacement functions to prevent CGA snow. These will slow
+; drawing a lot so use them only if it is necessary to eliminate CGA snow.
+%ifdef ELIMINATE_CGA_SNOW
+
+OFFSET_TO_CGA_STATUS_REGISTER	EQU		6		; Base port 3D4h + 6 = 3DAh
+CGA_STATUS_REGISTER				EQU		3DAh
+
+;--------------------------------------------------------------------
+; WAIT_UNTIL_SAFE_CGA_WRITE
+;	Parameters:
+;		DX:		CGA Status Register Address (3DAh)
+;	Returns:
+;		Interrupts disabled
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+%macro WAIT_UNTIL_SAFE_CGA_WRITE 0
+	cli				; Interrupt request would mess up timing
+%%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
+	sti
+	nop				; Should have time to serve IRQ here
+	cli
+%%WaitUntilNextRetraceStarts:
+	in		al, dx
+	shr		al, 1
+	jnc		SHORT %%WaitUntilNextRetraceStarts
+%endmacro
+
+;--------------------------------------------------------------------
+; StosbWithoutCgaSnow
+; StoswWithoutCgaSnow
+;	Parameters:
+;		AL:		Character to output
+;		AH:		Attribute to output (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
+StosbWithoutCgaSnow:
+	call	LoadAndVerifyStatusRegisterFromBDA
+	jne		SHORT .StosbWithoutWaitSinceUnknownPort
+
+	mov		ah, al
+	WAIT_UNTIL_SAFE_CGA_WRITE
+	mov		al, ah
+	stosb
+	sti
+	ret
+ALIGN JUMP_ALIGN
+.StosbWithoutWaitSinceUnknownPort:
+	stosb
+	ret
+
+ALIGN JUMP_ALIGN
+StoswWithoutCgaSnow:
+	call	LoadAndVerifyStatusRegisterFromBDA
+	jne		SHORT .StoswWithoutWaitSinceUnknownPort
+
+	push	bx
+	xchg	bx, ax
+	WAIT_UNTIL_SAFE_CGA_WRITE
+	xchg	ax, bx
+	stosw
+	pop		bx
+	sti
+	ret
+ALIGN JUMP_ALIGN
+.StoswWithoutWaitSinceUnknownPort:
+	stosw
+	ret
+
+;--------------------------------------------------------------------
+; LoadAndVerifyStatusRegisterFromBDA
+;	Parameters:
+;		DS:		BDA segment (zero)
+;	Returns:
+;		DX:		CGA Status Register Address
+;		ZF:		Set if CGA Base Port found in BDA
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+LoadAndVerifyStatusRegisterFromBDA:
+	mov		dx, [BDA.wVidPort]
+	add		dl, OFFSET_TO_CGA_STATUS_REGISTER
+	cmp		dx, CGA_STATUS_REGISTER
+	ret
+
+%endif ; ELIMINATE_CGA_SNOW
Index: /trunk/Assembly_Library/Src/Display/DisplayPrint.asm
===================================================================
--- /trunk/Assembly_Library/Src/Display/DisplayPrint.asm	(revision 41)
+++ /trunk/Assembly_Library/Src/Display/DisplayPrint.asm	(revision 42)
@@ -2,5 +2,5 @@
 ; Project name	:	Assembly Library
 ; Created date	:	26.6.2010
-; Last update	:	10.8.2010
+; Last update	:	18.9.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Functions for display output.
@@ -250,42 +250,4 @@
 
 ;--------------------------------------------------------------------
-; 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:
-;		AX, DX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-DisplayPrint_RepeatCharacterFromALwithCountInCX:
-	push	ax
-	call	DisplayPrint_CharacterFromAL
-	pop		ax
-	loop	DisplayPrint_RepeatCharacterFromALwithCountInCX
-	ret
-
-
-;--------------------------------------------------------------------
-; DisplayPrint_CharacterFromAL
-;	Parameters:
-;		AL:		Character to display
-;		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:
-	mov		ah, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
-	jmp		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fnCharOut]
-
-
-;--------------------------------------------------------------------
 ; DisplayPrint_ClearScreen
 ;	Parameters:
@@ -317,5 +279,5 @@
 ;		ES:DI:	Ptr to cursor location in video RAM
 ;	Returns:
-;		Nothing
+;		DI:		Updated offset to video RAM
 ;	Corrupts registers:
 ;		AX, DX
@@ -323,34 +285,66 @@
 ALIGN JUMP_ALIGN
 DisplayPrint_ClearAreaWithHeightInAHandWidthInAL:
+	push	si
 	push	cx
 	push	bx
-	push	di
-
-	xchg	bx, ax							; Move parameters to BX
+
+	xchg	bx, ax							; Area size to BX
 	call	DisplayCursor_GetSoftwareCoordinatesToAX
-	xchg	dx, ax							; Coordinates now in DX
-	xor		cx, cx							; Zero CX
-
-ALIGN JUMP_ALIGN
-.ClearRowFromArea:
+	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, ' '							; Clear with space
-	mov		ah, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
-	mov		cl, bl							; Area width = WORDs to clear
-	rep stosw
-	dec		bh
-	jz		SHORT .AreaCleared
-
-	inc		dh								; Increment row
-	push	dx
-	xchg	ax, dx
+	call	DisplayPrint_RepeatCharacterFromALwithCountInCX
+
+	xchg	ax, si							; Coordinates to AX
+	inc		ah								; Increment row
+	mov		si, ax
 	call	DisplayCursor_SetCoordinatesFromAX
-	pop		dx
-	jmp		SHORT .ClearRowFromArea
-
-ALIGN JUMP_ALIGN
-.AreaCleared:
-	pop		di
-	mov		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
+	dec		bh								; Decrement rows left
+	jnz		SHORT .ClearRowLoop
+
 	pop		bx
 	pop		cx
-	ret
+	pop		si
+	ret
+
+
+;--------------------------------------------------------------------
+; 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:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DisplayPrint_RepeatCharacterFromALwithCountInCX:
+	push	ax
+	call	DisplayPrint_CharacterFromAL
+	pop		ax
+	loop	DisplayPrint_RepeatCharacterFromALwithCountInCX
+	ret
+
+
+;--------------------------------------------------------------------
+; DisplayPrint_CharacterFromAL
+;	Parameters:
+;		AL:		Character to display
+;		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:
+	mov		ah, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
+	jmp		[VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fnCharOut]
Index: /trunk/Assembly_Library/Src/Time/Delay.asm
===================================================================
--- /trunk/Assembly_Library/Src/Time/Delay.asm	(revision 41)
+++ /trunk/Assembly_Library/Src/Time/Delay.asm	(revision 42)
@@ -76,8 +76,8 @@
 	push	dx
 
+	sti							; Make sure that interrupts are enabled
 	xchg	dx, ax
 	call	TimerTicks_ReadFromBdaToAX
 	add		dx, ax				; DX = end time
-	sti							; Make sure that interrupts are enabled
 .WaitLoop:
 	call	TimerTicks_ReadFromBdaToAX
Index: /trunk/Assembly_Library/makefile
===================================================================
--- /trunk/Assembly_Library/makefile	(revision 41)
+++ /trunk/Assembly_Library/makefile	(revision 42)
@@ -50,5 +50,5 @@
 # Assembler preprocessor defines.                               #
 #################################################################
-DEFINES =
+DEFINES = ELIMINATE_CGA_SNOW
 DEFINES_XT = 
 DEFINES_XTPLUS = USE_186
