Unix PC /dev/vidram device driver (sources)

Michael Ditto ford at crash.cts.com
Fri May 27 15:30:43 AEST 1988


AAARRRGGGHHH!!!   Somehow I posted a shar file which did not include
the most important file, "vid.c".  Here's the corrected file.

I would cancel the original article, but I can't log in to the machine I
posted it from, so it's up to you to ignore the first one and use this
one.  Sorry about the wasted net-traffic, everyone.

Did you ever have one of those days?


Mike Ditto					-=] Ford [=-
P.O. Box 1721					ford%kenobi at crash.CTS.COM
Bonita, CA 92002				ford at crash.CTS.COM


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	vidram.doc
#	Makefile
#	vid.c		<<<===   Now included!!!!!
#	INSTALL
#	Size
#	Install
#	Name
#	Remove
#	Files
# This archive created: Thu May 26 21:06:24 1988
export PATH; PATH=/bin:$PATH
echo shar: extracting "'vidram.doc'" '(2985 characters)'
if test -f 'vidram.doc'
then
	echo shar: will not over-write existing file "'vidram.doc'"
else
cat << \SHAR_EOF > 'vidram.doc'
Ha!  You expect documentation for a program I wrote in 10 minutes and
give away free?!?!  Well, I guess I can do something...

The "/dev/vidram" driver allows file-like access to the Unix PC video
bitmap memory.  This is a very low-level way to access the display,
and I don't recommend it, but it's an interesting thing to experiment
with.  Use it at your own risk.

To use it, just open(2) "/dev/vidram" and lseek(2) to the position you
want to access.  The video display is arranged in 16-bit words, and
the leftmost 16 pixels on the top line are at lseek offset 0.  The
leftmost pixel is the least significant bit (bit 0) of this word, and
the rightmost pixel of that group of 16 is the most significant bit
(bit 15) of the word.  This can be confusing if you think in Motorola
Byte Order, but that's your problem anyway.  You may read(2) or
write(2) the bytes to/from the display after seeking to the position
you want.

Note that the driver makes things look like just a bunch of bytes; you
only have to think of the 16-bit words if you want to visualize how
all these bits would appear on the screen.  Because Unix works in
bytes, and the screen hardware works in words, the driver is not
incredibly efficient.  But it is somewhat interesting, so I wrote it.

The driver is currently set up so that only super-user can write to
the screen (anyone can read).  It is pretty obvious how to change this
in the source if you want to just use the file permissions to regulate
/dev/vidram access.


To make the driver, just type "make" (as root).  You can also type
"make installable" to create a "vid+IN" that J. Random Luser can
install on his machine, or "make floppy" to make an Installable Floppy
that you can send to J. Random Luser if he doesn't have a uucp
connection.  Note that this doesn't physically create a floppy disk
where there wasn't one, it just writes on a disk that you supply,
despite the misleading command name and my misleading description
above.  The installable packages don't include source; if you want to
give that to someone, just send the shar file you got it in.


In case anyone's interested, here's a breakdown of how long it took me
to write this driver:


	10 minutes  to write the code.  It compiled the first time (weird!).
	10 minutes  to steal the installation package from another driver.
	10 minutes  to test it a bit and discover that the hardware only
		    allows word-wide access, and modify the code to do this.
	10 minutes  for the machine to crash and reboot, since there was a
		    slight bug in that last change.
	10 minutes  to fix the bug, recompile and test a bit more.
	10 minutes  to write this silly file.


Anyway, let me know if you find this program useful, educational, or
broken.

					-=] Ford [=-

"Once there were parking lots,		(In Real Life:  Mike Ditto)
now it's a peaceful oasis.		ford%kenobi at crash.CTS.COM
This was a Pizza Hut,			...!sdcsvax!crash!kenobi!ford
now it's all covered with daisies." -- Talking Heads
SHAR_EOF
if test 2985 -ne "`wc -c < 'vidram.doc'`"
then
	echo shar: error transmitting "'vidram.doc'" '(should have been 2985 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(360 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
D=-O
CFLAGS= $D
DRIVER=vid

install : $(DRIVER).o
	./INSTALL

all : $(DRIVER)+IN

installable : $(DRIVER)+IN

$(DRIVER)+IN : $(DRIVER).o
	cpio -oBc < Files > $(DRIVER)+IN

floppy : $(DRIVER)+IN
	echo "Insert a formatted floppy disk and press return"; read foo
	dd if=$(DRIVER)+IN of=/dev/rfp021 bs=16384

clean: 
	rm $(DRIVER).o $(DRIVER)+IN

clobber : clean

SHAR_EOF
if test 360 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 360 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'vid.c'" '(2627 characters)'
if test -f 'vid.c'
then
	echo shar: will not over-write existing file "'vid.c'"
else
cat << \SHAR_EOF > 'vid.c'
/************************************************************
 *
 * "/dev/vidram", a loadable device driver which allows
 * file-like access to the Unix PC video memory.
 *
 ************************************************************/

/************************************************************
 *
 * This program was written by me, Mike "Ford" Ditto, and
 * I hereby release it into the public domain in the interest
 * of promoting the development of free, quality software
 * for the hackers and users of the world.
 *
 * Feel free to use, copy, modify, improve, and redistribute
 * this program, but keep in mind the spirit of this
 * contribution; always provide source, and always allow
 * free redistribution (shareware is fine with me).  If
 * you use a significant part of this code in a program of
 * yours, I would appreciate being given the appropriate
 * amount of credit.
 *				-=] Ford [=-
 *
 ************************************************************/

#define KERNEL

#include <sys/types.h>
#include <sys/param.h>
#include <sys/inode.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/conf.h>
#include <sys/errno.h>
#include <sys/systm.h>
#include <sys/iohw.h>


#define VIDSIZE 0x8000


int vidstate;
#define VIDOPEN 0x01


vidrelease()
{
    if (vidstate & VIDOPEN)
	u.u_error = EBUSY;
}


vidopen(dev, flag)
dev_t dev;
int flag;
{
#ifndef ANYONE_CAN_WRITE
    if ( (flag&FWRITE) && !suser() )
	return;
#endif
    if (minor(dev))
    {
	u.u_error = ENODEV;
	return;
    }
    vidstate |= VIDOPEN;
}


vidclose(dev, flag)
dev_t dev;
int flag;
{
    vidstate &= ~VIDOPEN;
}


vidread()
{
    register unsigned char ch;

    if (u.u_offset < 0 || u.u_offset >= VIDSIZE)
    {
	u.u_error = ENODEV;
	return;
    }

    if (u.u_offset + u.u_count > VIDSIZE)
	u.u_count = VIDSIZE - u.u_offset;

    while (u.u_count>0)
    {
	register unsigned short *addr =
	    (unsigned short *)((char *)VIDMEM+(u.u_offset&~1));

	if (u.u_offset & 1)
	    ch = *addr & 0xff;
	else
	    ch = *addr >> 8;
	if (subyte(u.u_base, ch))
	    return;

	++u.u_offset;
	++u.u_base;
	--u.u_count;
    }
}


vidwrite()
{
    register int ch;
    register unsigned short *addr;

    if (u.u_offset < 0 || u.u_offset > VIDSIZE)
    {
	u.u_error = ENODEV;
	return;
    }

    if (u.u_offset + u.u_count > VIDSIZE)
	u.u_count = VIDSIZE - u.u_offset;

    while ( (u.u_count>0) && ((ch = fubyte(u.u_base)) != -1) )
    {
	addr = (unsigned short *)((char *)VIDMEM+(u.u_offset&~1));

	if (u.u_offset & 1)
	    *addr = *addr & 0xff00 | ch;
	else
	    *addr = *addr & 0xff | ch<<8;

	++u.u_offset;
	++u.u_base;
	--u.u_count;
    }
}
SHAR_EOF
if test 2627 -ne "`wc -c < 'vid.c'`"
then
	echo shar: error transmitting "'vid.c'" '(should have been 2627 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'INSTALL'" '(918 characters)'
if test -f 'INSTALL'
then
	echo shar: will not over-write existing file "'INSTALL'"
else
cat << \SHAR_EOF > 'INSTALL'
set -e		# exit if there anything goes wrong

DRIVER=vid

if [ ! -f ${DRIVER}.o ]
then
	echo "you must make ${DRIVER}.o before running INSTALL" 1>&2
	exit 1
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}`
	if [ $? -ne 0 ]
	then
		echo "${DRIVER} cannot be added to the /etc/master file" 1>&2
		exit 1
	fi

	rm -f /dev/vidram > /dev/null 2>&1
	/etc/mknod /dev/vidram c $MAJOR 0
fi

cp ${DRIVER}.o /etc/lddrv/

cd /etc/lddrv

# remove the driver if it's already running

./lddrv -q ${DRIVER} && ./lddrv -d ${DRIVER}

# allocate and load the module

if ./lddrv -a ${DRIVER}
then
	echo "Driver ${DRIVER} successfully loaded"
else
	echo "Error: Driver ${DRIVER} failed loading stage" 1>&2
	exit 1
fi

# load the driver at boot time

grep "^${DRIVER}\$" drivers > /dev/null || echo ${DRIVER} >> drivers
SHAR_EOF
if test 918 -ne "`wc -c < 'INSTALL'`"
then
	echo shar: error transmitting "'INSTALL'" '(should have been 918 characters)'
fi
chmod +x 'INSTALL'
fi # end of overwriting check
echo shar: extracting "'Size'" '(3 characters)'
if test -f 'Size'
then
	echo shar: will not over-write existing file "'Size'"
else
cat << \SHAR_EOF > 'Size'
42
SHAR_EOF
if test 3 -ne "`wc -c < 'Size'`"
then
	echo shar: error transmitting "'Size'" '(should have been 3 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Install'" '(250 characters)'
if test -f 'Install'
then
	echo shar: will not over-write existing file "'Install'"
else
cat << \SHAR_EOF > 'Install'
# Install script for /dev/vidram driver

DRIVER=vid

./INSTALL || exit 1

cd /etc/lddrv

# put an entry in InstDrv for ${DRIVER}
cat >> InstDrv << EOF
Name=/dev/vidram driver
File=${DRIVER}
EOF


echo "The /dev/vidram driver is now installed"
exit 0
SHAR_EOF
if test 250 -ne "`wc -c < 'Install'`"
then
	echo shar: error transmitting "'Install'" '(should have been 250 characters)'
fi
chmod +x 'Install'
fi # end of overwriting check
echo shar: extracting "'Name'" '(42 characters)'
if test -f 'Name'
then
	echo shar: will not over-write existing file "'Name'"
else
cat << \SHAR_EOF > 'Name'
/dev/vidram driver by Ford Prefect (M.D.)
SHAR_EOF
if test 42 -ne "`wc -c < 'Name'`"
then
	echo shar: error transmitting "'Name'" '(should have been 42 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Remove'" '(167 characters)'
if test -f 'Remove'
then
	echo shar: will not over-write existing file "'Remove'"
else
cat << \SHAR_EOF > 'Remove'
rm -f /dev/vidram

cd /etc/lddrv
./lddrv -dv vid
echo '/^vid$/d
w' | ed - drivers
rm -f ifile.vid vid vid.o

/etc/masterupd -d vid


echo "/dev/vidram driver REMOVED"
SHAR_EOF
if test 167 -ne "`wc -c < 'Remove'`"
then
	echo shar: error transmitting "'Remove'" '(should have been 167 characters)'
fi
chmod +x 'Remove'
fi # end of overwriting check
echo shar: extracting "'Files'" '(45 characters)'
if test -f 'Files'
then
	echo shar: will not over-write existing file "'Files'"
else
cat << \SHAR_EOF > 'Files'
Size
Install
Name
Remove
Files
INSTALL
vid.o
SHAR_EOF
if test 45 -ne "`wc -c < 'Files'`"
then
	echo shar: error transmitting "'Files'" '(should have been 45 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
-- 

Mike Ditto					-=] Ford [=-
P.O. Box 1721					ford%kenobi at crash.CTS.COM
Bonita, CA 92002				ford at crash.CTS.COM



More information about the Comp.sys.att mailing list