[net.micro.pc] Addition help with Video Retrace Code

bradley@druxq.UUCP (DavidsonBC) (08/06/85)

This is a different way to control the monitor to remove the fuzz or
snow.  The snow is caused by the video chip and the CPU trying to
access the same section of memory at the same time, basically your
trying to write to the video buffer as the video chip is trying to
read memory. The snow usally appears on the color monitor more than
on a monichrome monitor.

Below is the C and assembler code needed to display a screen without snow.

A few notes on the code that follows:  
	The code works for the AT&T 6300, IBM and an other 
	compatible computer.

	The dos has a few storage locations that this code uses; 
		1.) 40:63h is where the video port address is saved, 
			3B4h for mono and 3D4h for color. 
		2.) 40:65h contains the current mode of the video.

	The basic way to avoid the snow is to avoid contension for the
	video buffer, the most reliable way to do this is to disable
	the video while writting to the video buffer.

	While the video is disabled you can only write a maximum of 265
	characters before the user will notice any flicker in the screen
	so the maximum you write should be 240 characters of three lines
	of characters and attributes.

	The way this module works is by having a global pointer indexing
	to the [0][0] position of an internal memory buffer used to
	build the screens.  This means that the program can change the
	current screen without having to re-build screens, just change the
	pointer to another buffer and call the module to display it.

	This technique of disabling the video only needs to be used for
	color since moving 3 lines at a time seems to avoid snow on a
	monochrome monitor.

The DeSmet C module for moving an entire buffer to the screen.

global variables used:

screen_buffer	character pointer to the home corner of the source buffer.
screen_page	integer for which page video page to move the source to.
screen_cols	integer for number of columns in a line.

Other routines:

peek()		passed segment and offset and returns the value stored
		in memory at that location.  Not standard in the DeSmet 
		library, Source not provided.

_showds()	Standard in the DeSmet library. Returns the current
		segment where all the data is stored.

color_off()	Not Standard in the DeSmet library. Disables the color video.
color_on()	Not Standard in the DeSmet library. Enables the color video.

_lmove()	Standard in the DeSmet library. Simply moves the number of
		bytes from the source segment:offset to the destination 
		segment:offset.


to_screen(video_page)
	int	video_page;
{

int	video,video_seg,ds_reg,color,size,loop;
int	*screen_ptr; 			/* a char and attribute pointer. */

color = (peek(0x40,0x63) & 0x40);	/* 0 = mono 1 = color */
size = (3 * screen_cols) << 1;		/* 3 lines of bytes */
video = 25 * screen_cols * page;	/* offset to start of video page. */
video_seg = (color != 0) ? 0xB800 : 0xB000;
ds_reg = _showds();
screen_ptr = screen_buffer;		/* copy pointer so we do not change
					   the global pointer. */
for (loop = 0; loop < 25; loop += 3)
{
	if (color != 0)			/* remove this if snow on mono */
		color_off();
	_lmove(size,screen_ptr,ds_reg,video,video_seg);
	if (color != 0)			/* remove this if snow on mono */
		color_on();

	screen_ptr += size;
	video += size;
}
}					/* end of to_screen() */

The in-line assembler for color_off();

color_off()			/* disables the video signal */
{

#asm				/* assembler to follow */

	push	ES
	mov	ax,40
	mov	ES,ax		; ES points to DOS data seg 
	mov	dx,ES:[63h]	; base register for video chip
	add	dx,6h		; status register

color_off_loop:
	in	al,dx		; read status of retrace.
	test	al,8h
	jz	color_off_loop	; wait for retrace

	mov	al,ES:[65h]	; current mode register for video chip
	and	al,0F7h		; disable video bit
	sub	dx,2		; dx points to mode register now.
	out	dx,al		; video disabled

	pop	ES
#				/* end of in-line assembler */
}

The in-line assembler for color_on();

color_on()		/* enable video */
{

#asm
	push	ES
	mov	ax,40h
	mov	ES,40h		; ES points to DOS data area
	mov	al,ES:[65]	; video mode
	mov	dx,ES:[63]	; base register for video chip
	add	dx,4		; dx points to mode register
	out	dx,al		; video enabled again
	pop	ES
#
}

Sorry that this article was so long but snow free screens on any type
of monitor is not a simple process.  If you need some of the other 
source for functions or have any questions post an article or send me mail 
I will try to find the source in my library or answer any questions about 
the 6300 or compatibles.

Brad Davidson @ A T & T Information Systems Laboratories, Denver
x 1607
druxq!bradley

ludemann@ubc-cs.UUCP (Peter Ludemann) (08/09/85)

In article <1884@druxq.UUCP> bradley@druxq.UUCP (DavidsonBC) writes:
>This is a different way to control the monitor to remove the fuzz or
>snow.  The snow is caused by the video chip and the CPU trying to
>access the same section of memory at the same time ...
>
>	The basic way to avoid the snow is to avoid contension for the
>	video buffer, the most reliable way to do this is to disable
>	the video while writting to the video buffer.

There's a much easier way.  One of the bits in a port for the video
controller tells you whether or not the monitor is doing retrace.
Just loop busily while the bit says retrace isn't happening and
then write your bit of the screen.  I managed to write about
100 characters without any snow but I suspect more are possible.

I don't have the code handy, but if anyone's interested, I'll look
it up and post it.  But if you've got the IBM Tech Reference
handy, it shouldn't be hard to figure out.

One thing: my own IBM-"compatible" doens't have the snow problem
and leaves the port looking as if retrace never happens.
The scren writing program ran at least twice as fast as
on the IBM-PC.  And both were much faster than using BIOS.
     ubc-vision!ubc-cs!ludemann.UUCP