Writing directly to screen memory o

Neil Erskine erskine at force10.UUCP
Fri May 13 22:08:51 AEST 1988


In article <47900007 at uxe.cso.uiuc.edu> mcdonald at uxe.cso.uiuc.edu writes:
>>Has anyone ever written directly to the screen memory with UNIX or
>>XENIX on a PC?  I know that I probably open /dev/mem and start 
>>writing at the ega address space (after probably massaging the
>>video controller or whatever).  The UNIX that I am running is
>
>I am also interested in this. It appears that the cheapest way to
>get access to a 386 operating system and good C compiler is some flavor
>of Unix. I need, however, to be able to write direct to the screen
>and use the IO ports on the graphics board to do animation graphics.
>There should be some way to get a segment selector to point to the
>graphics memory, but one would also need to get IO access to the IO
>ports on the graphics card to be able to do anything useful. I looked
>in a book about the 386, and it is clear that it can be done, but,
>the question is how. Does any flavor of Unix for the 386 allow
>graphics access?
>Doug McDonald  (mcdonald at uxe.cso.uiuc.edu)

	SCO Xenix Release 2.2 supports this through ioctl calls. The
documentation is included in the manual entry SCREEN(HW), which is
normally in the 'RUN TIME ENVIRONMENT manual. Here is a stupid program which
writes directly to screen memory. Compile with the -Me option. It works
on Xenix-286 and Xenix-386.

	BE WARNED! Don't expect multi-screens to work properly when running
programs that use this facility.  Although the screen flip works, the
program doing direct update is still mapped to do this. Xenix doesn't do
anything clever about remapping the segment descriptor to an alternate site
when you flip to an alternate screen, so you get two programs writing to
the screen at the same time. I have stopped using this facility,
finding that watching my buffering of output data gives me reasonable
performance. However, MicroGnuEmacs really smoked with it!

						Neil
-------------------------- Cut here ----------------------------------------
#include <stdio.h>
#include <fcntl.h>
#include <sys/machdep.h>
#include <sys/sysmacros.h>

main (argc, argv)
int argc;
char *argv[];
{
    int adaptor;
    char *adaptor_dev;
    char attr;
    int cmode;
    int dmode;
    extern int errno;
    int fd;
    int selector;
    char far *scr;
    char far *cf;
    char *c;
    char ch;
    int i;

    initsfu ();
    sc_move_disp(5,5);
    sc_refresh_disp();
    adaptor = ioctl (1, CONS_CURRENT, 0);
    switch (adaptor) {
	case MONO:
	    adaptor_dev = "/dev/mono";
	    dmode = M_MCA_MODE;
	    break;
	case CGA:
	    adaptor_dev = "/dev/color";
	    dmode = M_C80x25;
	    break;
	case EGA:
	    adaptor_dev = "/dev/ega";
	    dmode = M_ENH_C80x25;
	    /* break;	/* I don't know anything about this guy */
	default:
	    printf ("Unsupported adaptor %d\n\r", adaptor);
	    stopsfu ();
	    exit(0);
	    break;
    }
    printf ("Using adaptor %s\n\r", adaptor_dev);
    fd = open (adaptor_dev, O_WRONLY);
    if (fd < 0) {
	fprintf (stderr, "Could not access %s, errno = %d\n\r",
		 adaptor_dev, errno);
	stopsfu ();
	exit (-1);
    }
    cmode = ioctl (fd, CONS_GET, 0);
    printf ("Current display mode is %d\n\r", cmode);
    getchar ();

    selector = ioctl (fd, MAPCONS, 0);
    scr = sotofar (selector, 0);
    (void) ioctl (fd, MODESWITCH | dmode, 0);

    ch = 'A';
    attr = 0x0f;
    while (getchar() != 'F') {
	for (cf=scr,i=0; i < 80*25; i++) {
	    *cf++ = ch;
	    *cf++ = attr ^= 0x7f;
	}
	ch++;
    }

    (void) ioctl (fd, MODESWITCH | cmode, 0);

    stopsfu ();
    exit (0);
}
-- 
Neil S. Erskine		MT&T - (902) 453-4915 x340
AP Computers 		USENET { garfield, watmath, ihnp4!utzoo!utai,
3845 Dutch Village Rd.		 uunet } !dalcs!force10!erskine
Halifax, N.S. B3L-4H9



More information about the Comp.unix.xenix mailing list