From: john@sg25.aud.temple.edu (John W. Schwegler)
Newsgroups: comp.sys.sgi.misc
Subject: Re: From where do I get a SYNC signal?
Date: 7 Jan 93 21:27:02 GMT


Try the following code, which synchronizes a RESET signal on the parallel
port out line with the swapping of screens (on our Indigo, it does so,
anyway :)

This program generates a visual stimulus. Two types are available:
checkerboard/gray scale, or checkerboard/inverse checkerboard. The parallel
port signal comes out well synchronized with the screen refresh (use an
oscilloscope to compare retrace/RESET signal for exact timing in your case).
Just rip out the current drawing code and use the parallel port stuff.

By the way, the parallel port reset signal comes out on pin 16 of the
DB-25 connector, according to the October comp.sys.sgi archives,
courtesy of Dave Olson.

Compile and link the two source files below with -lgl_s -lc_s:
______________________________________________________________________________
testmon.c: 
______________________________________________________________________________
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl.h>
#include <getopt.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/schedctl.h>
#include <sys/lock.h>



extern char *optarg;
extern int optind;
int xm,ym;
void make_gray(float gray);
void make_pat(int firston,int h,int v);

main(int argc,char **argv)
{
int which_screen,count;
pid_t sync_pid;
int frame1=0,frame2=0;
int nx=15,ny=12;
int xset=0,yset=0;
int use_gray=0;
int nswap = 30;
float gray_lev = 0.00;
signed char c;

if (schedctl(NDPRI,0,NDPHIMIN-2) < 0) {
        fprintf(stderr,"*******************************************\n");
        fprintf(stderr,"WARNING: not running in high-priority mode!\n");
        fprintf(stderr,"*******************************************\n");
        sleep(3);
        }
if (plock(PROCLOCK) < 0) {
        fprintf(stderr,"******************************\n");
        fprintf(stderr,"WARNING: not locked in memory!\n");
        fprintf(stderr,"******************************\n");
        sleep(3);
        }
foreground();
xm = getgdesc(GD_XPMAX);
ym = getgdesc(GD_YPMAX);
while ((c = getopt(argc,argv,"x:y:g:s:f:rh")) != -1) {
        switch (c) {
                case 'x':
                  nx = atoi(optarg);
                  if (!yset) ny = (ym*nx)/xm;
                  xset = 1;
                  break;
                case 'y':
                  ny = atoi(optarg);
                  if (!xset) nx = (xm*ny)/ym;
                  yset = 1;
                  break;
                case 's':
                  nswap = atoi(optarg);
                  if (frame1 == 0) { 
                        frame1 = nswap;
                        frame2 = nswap;
                        }
                  break;
                case 'f':
                  frame1 = atoi(optarg);
                  frame2 = nswap;
                  break;
                case 'g':
                  use_gray = 1;
                  gray_lev = atof(optarg);
                  printf("Gray is %g.\n",gray_lev);
                  break;
                case 'r':
                  use_gray = 0;
                  break;
                case 'h':
                case '?':
                default:
                  fprintf(stderr,"usage: %s [-x nxpat] [-y nypat] [-g
graylev] [-s swapint] [rh?]\n",
                        argv[0]);
                  exit(2);
                }
        }
noborder();
init_plp();
prefposition(0,xm-1,0,ym-1);
winopen("test");
doublebuffer();
gconfig();
make_pat(1,nx,ny);
swapbuffers();
if (use_gray) {
        make_gray(gray_lev);
        }
else {
        make_pat(0,nx,ny);
        }
which_screen = 1;
while (1) {
        if (which_screen == 1)
                swapinterval(frame1);
        else
                swapinterval(frame2);
        swapbuffers();
        if (which_screen == 1)
                plp_trig();
        which_screen = 3 - which_screen;
        }
}

void 
make_pat(int firston,int h,int v)
{
float x,y;
int j,k;
int hcol,vcol;

x = ((float) xm)/h;
y = ((float) ym)/v;
vcol = firston;
for (j=0; j < v; j++) {
        hcol = vcol;
        for (k=0; k < h; k++) {
                if (hcol) color(WHITE);
                else color(BLACK);
                rectf(x*k,y*j,(k+1)*x,(j+1)*y);
                hcol = 1-hcol;
                }
        vcol = 1-vcol;
        
        }
}

void 
make_gray(float ngray)
{
float x,y;
x = ((float) xm)-1;
y = ((float) ym)-1;
mapcolor(512,(short) (ngray*255.),(short) (255.*ngray),(short) (255.*ngray));
gflush();
qtest();
color(512);
rectf(0.,0.,x,y);
}
______________________________________________________________________________
plp.c:
______________________________________________________________________________
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/plp.h>

#define NPTS 2
static int fd;

init_plp()
{
if ((fd = open("/dev/plp",O_RDWR)) < 0) {
        fprintf(stderr,"Couldn't open plp port!\n");
        exit(1);
        }
if (ioctl(fd,PLPIOCIGNACK,1) < 0) {
        fprintf(stderr,"Wouldn't take IGNACK\n");
        exit(1);
        }
if (ioctl(fd,PLPIOCSTROBE,PLP_STROBE(126,63,63))) {
        fprintf(stderr,"Wouldn't take PLP STROBE\n");
        exit(1);
        }
}


plp_trig()
{
ioctl(fd,PLPIOCRESET);
}
______________________________________________________________________________
"Genius may have its limitations,       | John Schwegler
   but stupidity is not thus            | Temple U. Auditory Research Dept.
   handicapped."                        | john@sg25.aud.temple.edu
         - Elbert Hubbard               | (215) 221-3687 FAX 221-7523