[comp.sys.att] Hardware reverse video for the UNIXpc

jbm@uncle.UUCP (John B. Milton) (09/19/88)

Well, well, well. I was examining the schematics for the UNIXpc and noticed
an interesting thing. At D2 on page 8 of 25, there is an XOR gate that
has video from the sift register on one pin, and a line called ENINVERS* on
the other pin. Hmm, says I, this looks like hardware reverse video. I have
never seen the screen on the UNIXpc in reverse before. I traced the line
back to page 6 and found a bit selectable latch at C2. It is a 74LS259. It
has an ABC selector, an in pin, an enable and 8 outputs. In this case, the
ABC are addresses: 1110 0100 0xxx 0000 0000 0000. The data is bit 15 of
the data written to the address. The effect is that one write changes only
one bit. The memory of the bits is the latch itself. Any driver in the system
can change any bit without having to know what the current state is. Anyway,
the fact that the ENINVERS line is attached to the 8th output IS NOT DOCUMENTED
It may have been an added feature, so it might not be there on old boards.
The file /usr/include/sys/hardware.h describes all the bits EXCEPT the 8th one.

To verify this, I whipped out the handy kernel debugger. This is called db.o,
and is a loadable device driver. It was posted to the net a while back:
 DEVNAME  ID  BLK CHAR  LINE   SIZE    ADDR     FLAGS
      db   6   -1   -1   -1  0xc000  0x369000 ALLOC BOUND 
I issued a "WW e47000<cr>8000<cr>", AND LO!! the screen reversed. I suppose
if it didn't I wouldn't have posted this 'eh?

I thought the best thing to do with this since you can't get at it through
/dev/mem, was to add an ioctl to the vidram driver that Ford posted a while
back. The diffs are below. A few #defines, a few tweeks to the INSTALL, and
addition of the vidioctl() function. I find that I'm not sure if I really like
the screen that way or not. People used to XEROX, Suns, Mac, HP, etc. might
like it this way, some will hate it. Also included below is a little program
"rev" to do the ioctl() interactively for shell scripts and such. I suppose
some EMACS freaks would also like it for "visable bell". It would be nice if
this were implemented in the screen driver as an ANSI escape, oh well.

If you have a main board older than P5, let me know if this works. Diffs and
program below, enjoy.

NEWS FLASH: I'm editing the D. file right now. It seems that when the screen
blanks (to save phosphor burn, right) The screen is ALL WHITE! Hmm, being
way down in the hardware, it makes everything backwards. When you're in
reverse mode you turn down the brightness a lot anyway. Ho hum. I guess there
has to be a down side to everything.

*** old/vid.c	Sun Sep 18 23:36:12 1988
--- vid.c	Mon Sep 19 00:04:28 1988
***************
*** 136,138
  	--u.u_count;
      }
  }

--- 136,157 -----
  	--u.u_count;
      }
  }
+ 
+ /* these three lines seem to be missing from <sys/hardware.h> */
+ #define INV_GCR_ADDR	((unsigned short *)0xE47000)	/* ENINVERS- */
+ #define INV_DISABLE		0x0000	/* ENINVERS  0=normal video */
+ #define INV_ENABLE		0x8000	/* ENINVERS  0=inverse video */
+ 
+ #define VIDINV 0
+ 
+ vidioctl(dev,cmd,arg,mode)
+ dev_t dev;
+ int cmd,arg,mode;
+ {
+ 	switch(cmd) {
+ 		case VIDINV:
+ 			*INV_GCR_ADDR=arg;
+ 			break;
+ 	}
+ 	return(0);
+ }

*** old/INSTALL	Mon Sep 19 00:11:34 1988
--- INSTALL	Mon Sep 19 00:10:50 1988
***************
*** 9,17
  fi
  
  
! if [ ! -c /dev/vidram ]
! then
! 	/etc/masterupd -a char release open close read write ${DRIVER}
  
  	# get the assigned device number
  	MAJOR=`/etc/masterupd -c ${DRIVER}`

--- 9,18 -----
  fi
  
  
! #if [ ! -c /dev/vidram ]
! #then
! 	/etc/masterupd -d ${DRIVER}
! 	/etc/masterupd -a char release open close read write ioctl ${DRIVER}
  
  	# get the assigned device number
  	MAJOR=`/etc/masterupd -c ${DRIVER}`
***************
*** 23,29
  
  	rm -f /dev/vidram > /dev/null 2>&1
  	/etc/mknod /dev/vidram c $MAJOR 0
! fi
  
  cp ${DRIVER}.o /etc/lddrv/
  

--- 24,30 -----
  
  	rm -f /dev/vidram > /dev/null 2>&1
  	/etc/mknod /dev/vidram c $MAJOR 0
! #fi
  
  cp ${DRIVER}.o /etc/lddrv/
---------------------------------------------------  
/* rev.c */
#include <fcntl.h>
#include <stdio.h>

extern int errno;

#define VIDDEV   "/dev/vidram"

static char *me,*usage="Usage: %s [0|1]\n";

void qperrorf(format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
char *format,*a1,*a2,*a3,*a4,*a5,*a6,*a7,*a8,*a9;
{
	char line[200];

	sprintf(line,format,a1,a2,a3,a4,a5,a6,a7,a8,a9);
	perror(line);
	exit(errno);
}

int main(argc,argv)
int argc;
char *argv[];
{
	char c;
	int f,wr;

	me=argv[0];
	if (argc==0)
		fprintf(stderr,usage,me);
	else
		if ((f=open(VIDDEV,O_RDONLY))==-1)
			qperrorf(stderr,"%s: open error on %s",me,VIDDEV);
		else {
			setuid(getuid()); /* all the root we need for now man */
			wr=0;
			switch (argv[1][0]) {
				case '1':
					wr=0x8000;
				case '0':
					if (ioctl(f,0,wr)==-1)
						qperrorf(stderr,"%s: ioctl error on %s",me,VIDDEV);
					break;
				default:
					fprintf(stderr,usage,me);
			}
			close(f);
		}
}
------------------
John
-- 
John Bly Milton IV, jbm@uncle.UUCP, n8emr!uncle!jbm@osu-cis.cis.ohio-state.edu
home: (614) 294-4823, work: (614) 459-7641; CP/M to MP/M, MS-DOS to OS/2