AT&T V/386 Console Graphics Prog Example
Rick Calder
rhc at nsscb.UUCP
Mon Nov 20 04:09:11 AEST 1989
/*
This is an example of how to program graphics on a console
virtual terminal screen. It is written for an AT&T VDC600 VGA card,
at 800x600, but can easily be modified for others supported by the
compiler. See '/usr/include/sys/kd.h'.
It will first open an available virtual terminal, set the
graphic mode, and then display the graphic area ( 25 ints x 600 lines).
Program the appropriate bytes of the graphic area to correspond to
the screen pixels, one bit per pixel.
You may put this program in the background to free up the
console, and then use the <ALT-SysReq><Fx> to bounce back and forth.
Use the <DEL> to close the graphic. After a bounce out and back, no
input will be read until the <BEEP>. Why ? Let me know if you
figure it out ! Really, I've no idea.
See the manpage, display(7)
Warnings:
Although it is possible to write character sequences which
set arbitrary bits on the screen in any of the three graphic modes,
this mode of operation is not currently supported.
Rick Calder, AT&T National Systems Support Center
[att!]rick!rick rick at rick.att.com
attmail!rcalder
-------------------------------- cut here ------------------------------------
*/
/* #disclaimer: per the manpage, display(7), this code is not supported by
AT&T. Use at your own risk, distribute freely, please leave in my
authorship info.
Rick Calder [att!]rick!rick rick at rick.att.com attmail!rcalder
programming help : research!debra research!shadow!dhn
change the following for other video modes:
VGASCREEN_SIZE (800 * 600) total pixels
SCREEN ((800/8) * 600) bytes per line
LINES 600
COLS ((800 / 8) / 4) ints per line
in acquiredisplay():
ioctl(0, SW_VDC800x600E, 0); AT&T VDC600 video card
in releasedisplay():
ioctl(0, SW_VGAC80x25, 0); any VGA card, text mode
*/
#include <fcntl.h>
#include <memory.h>
#include <stdio.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/at_ansi.h>
#include <sys/kd.h>
#include <sys/vt.h>
#define ALIGN_TO_4K(size) (((size) + 4095) & ~4095)
#define VGAWINDOW_SIZE 0x10000 /* 65536, 64K */
#define VGASCREEN_ADDR 0xA0000 /* others at 0xB0000 */
#define VGASCREEN_SIZE (800 * 600)
#define SCREEN ((800/8) * 600) /* bytes per line */
#define LINES 600
#define COLS ((800 / 8) / 4) /* ints per line */
struct kd_memloc memloc;
char *dp;
int *pad[LINES][COLS];
void scribble(), initmem(),
acquiredisplay(), releasedisplay();
main(argc,argv)
int argc;
char **argv;
{
int a;
long vt;
char devname[15];
struct vt_mode vtmode;
/* VT_OPENQRY on stderr allows prog to be put in background */
if ( ioctl(2,VT_OPENQRY,&vt) == -1 ) {
perror("VT_OPENQRY failed");
exit(-1);
}
close(0); close(1); close(2);
setpgrp();
sprintf(devname,"/dev/vt0%ld", vt);
a = open(devname,O_RDWR,NULL);
if ( a == -1 ) {
perror("vtopen failed");
exit(-1);
}
dup(a); dup(a);
if ( ioctl(0,VT_ACTIVATE,vt) == -1 ) {
perror("VT_ACTIVATE failed");
exit(-1);
}
sigset(SIGINT,exit);
vtmode.mode = VT_PROCESS; /* process controls console switching */
vtmode.waitv = 1; /* no writes on inactive consoles */
vtmode.relsig = SIGUSR1; /* received on hot-key for other console */
vtmode.acqsig = SIGUSR1; /* received on hot-key to this console */
vtmode.frsig = SIGUSR2; /* not used, for forced release of display */
sigset(SIGUSR2,SIG_IGN); /* prevents 'User signal 2' message */
ioctl(0,VT_SETMODE, &vtmode);
**pad = (int *) malloc(SCREEN);
memset(pad,'\0',SCREEN);
initmem();
scribble();
acquiredisplay(); /* initial set up */
while ( 1 );
}
void
scribble()
{
int x, y;
for ( y = 0; y < LINES; y++ )
for ( x = 0; x < COLS; x++ ) {
pad[y][x] = (int *) 0xFF00FF00;
x += 2;
}
}
void
acquiredisplay()
{
ioctl(0, SW_VDC800x600E, 0); /* AT&T VDC600 video card */
sleep(1); /* settling time */
ioctl(0, KDMAPDISP, &memloc);
memcpy(dp, pad, SCREEN); /* need to refresh screen */
sigset(SIGUSR1, releasedisplay); /* set for next signal */
}
void
releasedisplay()
{
ioctl(0, KDUNMAPDISP, 0); /* unmap from user memory */
sleep(1); /* settling time */
ioctl(0, SW_VGAC80x25, 0); /* any VGA card, text mode */
ioctl(0, VT_RELDISP, 1); /* results in console switch */
sigset(SIGUSR1, acquiredisplay); /* set for next signal */
}
void
initmem()
{
/* get a virtual address that is page aligned */
dp = (char *) malloc(ALIGN_TO_4K(VGAWINDOW_SIZE + 4096));
dp = (char *) ALIGN_TO_4K ((unsigned long) dp);
memloc.physaddr = (caddr_t) VGASCREEN_ADDR;
memloc.vaddr = dp;
memloc.length = ALIGN_TO_4K (VGAWINDOW_SIZE);
memloc.ioflg = 1;
}
--
Rick Calder, AT&T National Systems Support Center
[att!]rick!rick rick at rick.att.com
attmail!rcalder
More information about the Comp.unix.i386
mailing list