Graphic characters in Norton Utilities SYS-V

Rick Richardson rick at pcrat.uucp
Fri Aug 3 10:23:17 AEST 1990


In article <8Y-48O9 at xds13.ferranti.com> peter at ficc.ferranti.com (Peter da Silva) writes:
>In article <1990Jul31.101937.9157 at pcrat.uucp> rick at pcrat.UUCP (Rick Richardson) writes:

>> Remember that a pre-condition was that ETI was fully supported, and
>> John said it was.  So, there is no chance this application will break.

>But it already broke! This whole discussion started because someone's
>system was set up slightly differently (in this case an alternate character
>set) and it went ahead anyway with the (now) non-working direct screen
>writer. Can you guarantee that nobody's extended VGA, or IBM's new XGA
>cards, or whatever won't fool it into thinking that it can do direct
>screen I/O and have it do something worse than print gibberish?

I agree that if the user can't control what mode the software operates
in, then the software is at fault, and should be fixed.  I don't
think that condemns the whole idea of providing direct screen write
as an option.

In some cases, it simply must be done.  Anything that wants to do
graphics is going to have to go directly to the screen.  (Lets
leave X windows, another user mode application, out of this for
now; many don't need or want it at this point).

In other cases, direct screen writes are of tremendous value.
People find it convenient to lean on the arrow keys to move
around, and expect to stop on a dime when they see where they
want to be.  For many screen layouts, this requires the use
of scrolling regions to do it in an eye pleasing manner.

Perhaps we can agree that the console driver should have
scrolling regions, and return to the favorite activity of
this group -- UNIX vendor bashing.

Anyway, I enclose for the curious, a benchmark that shows the
difference in speed for the ANSI console driver vs. direct
screen writes.  For those that don't care to run it, I
got a maximum of 12 scrolls per second using ANSI, and 140
scrolls per second using direct screen writes.  The test
simulates an application where only a portion of the
screen (horizontally and vertically) is expected to scroll.

-Rick

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  sw.c
# Wrapped by rick at pcroe on Thu Aug  2 19:54:26 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sw.c'\"
else
echo shar: Extracting \"'sw.c'\" \(5463 characters\)
sed "s/^X//" >'sw.c' <<'END_OF_FILE'
X
X/*
X *	Test program to demonstrate scrolling speed
X *
X *	cc sw.c -o sw
X */
X#include <stdio.h>
X
X#include <sys/types.h>
X#include <sys/times.h>
X#include <termio.h>
X#include <limits.h>		/* for CLK_TCK (100) */
X
X#include <sys/at_ansi.h>
X#include <sys/kd.h>
X
Xlong	times();
X
Xchar			*taddr;
Xchar			*paddr;
Xint			start;
X
X#define	TESTSECS	10	/* seconds */
X
X#define	LINES	25
X#define	COLS	80
X#define	XOFF	8
X#define	YOFF	4
X#define	SLINES	(LINES-YOFF)
X#define	SCOLS	(COLS-XOFF)
X
Xchar *strings[SLINES] =
X{
X"Line 01 Line 01 Line 01 Line 01 Line 01 Line 01 Line 01 Line 01 Line 01",
X"Line 02 Line 02 Line 02 Line 02 Line 02 Line 02 Line 02 Line 02 Line 02",
X"Line 03 Line 03 Line 03 Line 03 Line 03 Line 03 Line 03 Line 03 Line 03",
X"Line 04 Line 04 Line 04 Line 04 Line 04 Line 04 Line 04 Line 04 Line 04",
X"Line 05 Line 05 Line 05 Line 05 Line 05 Line 05 Line 05 Line 05 Line 05",
X"Line 06 Line 06 Line 06 Line 06 Line 06 Line 06 Line 06 Line 06 Line 06",
X"Line 07 Line 07 Line 07 Line 07 Line 07 Line 07 Line 07 Line 07 Line 07",
X"Line 08 Line 08 Line 08 Line 08 Line 08 Line 08 Line 08 Line 08 Line 08",
X"Line 09 Line 09 Line 09 Line 09 Line 09 Line 09 Line 09 Line 09 Line 09",
X"Line 10 Line 10 Line 10 Line 10 Line 10 Line 10 Line 10 Line 10 Line 10",
X"Line 11 Line 11 Line 11 Line 11 Line 11 Line 11 Line 11 Line 11 Line 11",
X"Line 12 Line 12 Line 12 Line 12 Line 12 Line 12 Line 12 Line 12 Line 12",
X"Line 13 Line 13 Line 13 Line 13 Line 13 Line 13 Line 13 Line 13 Line 13",
X"Line 14 Line 14 Line 14 Line 14 Line 14 Line 14 Line 14 Line 14 Line 14",
X"Line 15 Line 15 Line 15 Line 15 Line 15 Line 15 Line 15 Line 15 Line 15",
X"Line 16 Line 16 Line 16 Line 16 Line 16 Line 16 Line 16 Line 16 Line 16",
X"Line 17 Line 17 Line 17 Line 17 Line 17 Line 17 Line 17 Line 17 Line 17",
X"Line 18 Line 18 Line 18 Line 18 Line 18 Line 18 Line 18 Line 18 Line 18",
X"Line 19 Line 19 Line 19 Line 19 Line 19 Line 19 Line 19 Line 19 Line 19",
X"Line 20 Line 20 Line 20 Line 20 Line 20 Line 20 Line 20 Line 20 Line 20",
X"Line 21 Line 21 Line 21 Line 21 Line 21 Line 21 Line 21 Line 21 Line 21",
X};
X
Xmain()
X{
X	double	do_mapping();
X	double	do_ansi();
X	double	a, m;
X
X	init_mapping();
X
X	raw();
X	(void) do_ansi(1);
X	(void) do_mapping(1);
X	noraw();
X
X	a = do_ansi(0);
X	m = do_mapping(0);
X
X	printf("\n");
X	printf("Ansi:	%f scrolls/second\n", a);
X	printf("Mapped:	%f scrolls/second\n", m);
X}
X
Xdouble
Xdo_mapping(man)
X{
X	int	r;
X	long	start, end;
X	struct tms tms;
X	int	n;
X	char	buf[256];
X
X	/* Put up 'static' area */
X	if (man)
X		write_screen(1, 1, 0x70,
X		" Mapped: Manual test - hold <cr> down, 'q' to exit");
X	else
X		write_screen(1, 1, 0x70,
X		" Mapped: Automatic test                           ");
X	for (r = 0; r < SLINES; ++r)
X	{
X		write_screen(YOFF+r, XOFF, 0x07, strings[ (r+n) % SLINES ] );
X		sprintf(buf, "%*s ", XOFF-3, (r&1) ? "Stuff" : "Fixed");
X		write_screen(YOFF+r, 1, 0x70, buf);
X		write_screen(YOFF+r, XOFF-1, 0x07, " ");
X	}
X
X	/* Start scrolling the data region */
X	if (!man) start = times(&tms);
X	n = 0;
X	for (;;)
X	{
X		if (man)
X		{
X			buf[0] = 0;
X			read(0, buf, 1);
X			if (buf[0] == 'q')
X				break;
X		}
X		++n;
X		/* Just rewrite the entire scrolling region */
X		for (r = 0; r < SLINES; ++r)
X		{
X			write_screen(YOFF+r, XOFF, 0x07,
X				strings[ (r+n) % SLINES ] );
X		}
X		if (!man)
X		{
X			end = times(&tms);
X			if ( end >= (start + CLK_TCK*TESTSECS) )
X				break;
X		}
X	}
X	if (man)
X		return 0;
X	else
X		return	(double) n / ( ((double)(end-start)) / CLK_TCK);
X}
X
Xdouble do_ansi(man)
X{
X	int	r;
X	long	start, end;
X	struct tms tms;
X	int	n;
X	char	buf[256];
X
X	/* Put up 'static' area */
X	printf("\033[2J\033[H\033[7m");
X	if (man)
X		printf(
X		" Ansi: Manual test - hold <cr> down, 'q' to exit");
X	else
X		printf(
X		" Ansi: Automatic speed test                     ");
X	printf("\033[m");
X	for (r = 0; r < SLINES; ++r)
X	{
X		printf("\033[%d;%dH%s",
X			YOFF+r, XOFF, strings[ (r+n) % SLINES ] );
X		printf("\033[%d;1H\033[7m%*s \033[m ", YOFF+r, XOFF-3,
X			(r&1) ? "Stuff" : "Fixed");
X	}
X
X	/* Start scrolling the data region */
X	if (!man) start = times(&tms);
X	n = 0;
X	for (;;)
X	{
X		if (man)
X		{
X			buf[0] = 0;
X			fflush(stdout);
X			read(0, buf, 1);
X			if (buf[0] == 'q')
X				break;
X		}
X		++n;
X		/* Delete top line, rewrite fixed stuff */
X		printf("\033[%d;1H\033[1M", YOFF);
X		for (r = 0; r < SLINES; ++r)
X			printf("\033[%d;1H\033[7m%*s \033[m ",
X				YOFF+r, XOFF-3, (r&1) ? "Stuff" : "Fixed");
X		/* Add new line to bottom, completing region scroll */
X		printf("\033[%d;%dH%s", YOFF+SLINES-1, XOFF,
X			strings[n%SLINES]);
X		if (!man)
X		{
X			end = times(&tms);
X			if ( end >= (start + CLK_TCK*TESTSECS) )
X				break;
X		}
X	}
X	if (man)
X		return 0;
X	else
X		return	(double) n / ( ((double)(end-start)) / CLK_TCK);
X}
X
Xinit_mapping()
X{
X	paddr = (char *) ioctl(0, MAPCONS, 0);
X	start = (get_crtc(0x0c)<<8) | get_crtc(0x0d);
X	taddr = paddr + start*2;
X}
X
Xwrite_screen(y, x, a, s)
Xchar	*s;
X{
X	register char	*p = taddr + (y-1)*160 + ((x-1)<<1);
X	while (*s)
X	{
X		*p++= *s++;
X		*p++ = a;
X	}
X}
X
Xget_crtc(n)
X{
X	struct port_io_arg	io;
X	register int		rc;
X
X	io.args[0].dir = OUT_ON_PORT;
X	io.args[0].port = 0x3d4;
X	io.args[0].data = n;
X	io.args[1].dir = IN_ON_PORT;
X	io.args[1].port = 0x3d5;
X	io.args[2].port = 0;
X	io.args[3].port = 0;
X	rc = ioctl(0, EGAIO, &io);
X	return (io.args[1].data & 0xff);
X}
X
Xstruct termio old;
Xraw()
X{
X	struct termio new;
X	ioctl(0, TCGETA, &old);
X	new = old;
X	new.c_lflag &= ~(ECHO|ICANON);
X	new.c_cc[VMIN] = 1;
X	new.c_cc[VTIME] = 0;
X	ioctl(0, TCSETA, &new);
X}
Xnoraw()
X{
X	ioctl(0, TCSETA, &old);
X}
END_OF_FILE
if test 5463 -ne `wc -c <'sw.c'`; then
    echo shar: \"'sw.c'\" unpacked with wrong size!
fi
# end of 'sw.c'
fi
echo shar: End of shell archive.
exit 0
-- 
Rick Richardson - PC Research, Inc., uunet!pcrat!rick, (201) 389-8963



More information about the Comp.unix.i386 mailing list