ford@kenobi.UUCP (Mike "Ford" Ditto) (05/26/88)
Since everyone's talking about direct video access these days, I put together a device driver just for that purpose. "/dev/vidram" is a character device that lets you use seek/read/write to access the **RAW** video memory. I think this is a much lower level access than anyone will want; for example, if the screen-blanker is active (blanking the screen) you will just read zeroes from this device. But I'll send it out so all you people can see if you have some use for it. "vidram.shar" is after my signature. -=] Ford [=- "Once there were parking lots, (In Real Life: Mike Ditto) now it's a peaceful oasis. ford%kenobi@crash.CTS.COM This was a Pizza Hut, ...!sdcsvax!crash!kenobi!ford now it's all covered with daisies." -- Talking Heads #! /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 # Size # Install # Name # Remove # Files # INSTALL # This archive created: Tue May 24 23:44:09 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@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 "'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 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 # End of shell archive exit 0
ford@crash.cts.com (Michael Ditto) (05/27/88)
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@crash.CTS.COM Bonita, CA 92002 ford@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@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@crash.CTS.COM Bonita, CA 92002 ford@crash.CTS.COM