/* IOBoard.c * inBoard() and outBoard(); new versions for the combined I/O board. * Root privileges are needed. * Revised: 2005 May 18, JAB */ #include "Parse5A.h" #include /* For mmap() */ #define MEM "/dev/mem" /* System memory */ #define OFFS 0xfe102000 /* Offset to Region 2 of PCI board */ #define OFFP 0xec00 /* Offset to Region 1 in PCI board 00:06.0 */ /* (These two defaults will (probably) be incorrect * if the I/O board changes slots) */ #define NUMB 128 /* Number of bytes to process (128 bytes = 64 shorts) */ #define DEVICES "/proc/bus/pci/devices" /* For info about I/O board */ #define TAG 0x10b53001 /* PLX + Dan's 3001 for Mark-5A IO board */ #define TAGB 0x10b59030 /* PLX + 0x9030 assigned to Mark 5B */ /* Following three defines are from "ICS307 frequency calculator" * for 33.0 MHz output from an assumed input of 16.66666666667 MHz */ #define VDW 91 #define RDW 8 #define OD 10 static int first = TRUE; /* First time called? */ // static int found = 0; /* 0 = not found, 1 = Mark-5A board, 2 = Mark-5B */ /* ?? Change to global when ready ?? */ static char * cmd[] = { "", "", "SET", "GET" }; static int memp; /* From open() on MEM */ static volatile unsigned short * buf1; /* Memory Region 2 as shorts (input section) */ static volatile unsigned short * buf2; /* Memory Region 2 offset as shorts (output section) */ volatile unsigned short * idr; /* Input design revision */ volatile unsigned short * odr; /* Output design revision */ static int Initize() { /* Initialize first time */ static unsigned short zero = 0; FILE * devi; /* From fopen() on DEVICES */ char line[512]; unsigned long fill = FILL_PATTERN; /* For buf2[6] and buf2[7] */ unsigned long tag; /* Check: TAG or TAGB */ unsigned long t1, t3, t4, t5, t10, t11, t12; unsigned int t0, t2, t6, t7, t8, t9; unsigned long off0; /* Offset to Region 0 of PCI board */ unsigned long off1; /* Offset to Region 1 of PCI board */ unsigned long off2; /* Offset to Region 2 of PCI board */ unsigned long siz0; /* Size of region 0, longs */ unsigned long siz1; /* Size of region 1, longs */ unsigned long siz2; /* Size of region 2, longs */ unsigned long offp = OFFP; /* Offset to Region 1 of PCI board */ unsigned long offs = OFFS; /* Offset to Region 2 of PCI board */ /* (These are defaults to be changed below) */ /* ** Open file DEVICES (to get offs and offp) ** */ if ((devi = fopen(DEVICES, "r")) == NULL) { /* OK? */ (void) fprintf(stderr, /* Nope */ "%s Initize() ERROR: \007 Can't fopen() file ", me); perror(DEVICES); /* Assume no I/O board */ idr = &zero; /* So input design revision is zero */ odr = &zero; /* Output design revision is zero */ found = 0; /* (Should already be 0) */ return(-1); /* Error */ } /* ** Find board TAG (Mark5A IO board) or ** * ** TAGB (Mark5B board) in token 2 ** */ while (found == 0) { /* Loop until found > 0 (or end of file) */ if (fgets(line, sizeof(line), devi) == NULL || strlen(line) < 80) { /* Read a line, OK? */ (void) fprintf(stderr, /* Nope */ "%s Initize() WARNING: fgets() end of file ", me); perror(DEVICES); break; /* Not found, out of while loop until found */ } /* Decode the needed parts of the line */ (void) sscanf(line, "%x %lx %x %lx %lx %lx %x %x %x %x %lx %lx %lx", &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9, &t10, &t11, &t12); tag = t1; if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s Initize() DEBUG: tag %#lx \n", me, tag); if (tag == TAG) /* This one? */ found = 1; /* Yes, Mark-5A IO board */ else if (tag == TAGB) { /* This one? */ found = 2; /* Yes, Mark-5B board */ off0 = t3; off1 = t4; off1--; /* Why?! */ off2 = t5; siz0 = t10; siz1 = t11; siz2 = t12; } /* End of if Mark-5B board */ else /* Not yet found */ continue; /* To next while */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s Initize() DEBUG: %#x %#lx %#x %#lx %#lx " "%#lx %#x %#x %#x %#x %#lx %#lx %#lx \n", me, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); /* Here we've found either TAG or TAGB */ offp = t4; offp--; /* Why?! */ offs = t5; } /* End of while loop until found */ (void) fclose(devi); /* We're done with it */ if (found == 0) { /* Did we find either Mark-5A or Mark5B board? */ if (msglev < 1) /* Nope, debuggery? */ (void) fprintf(stderr, /* Yes */ "%s Initize() WARNING: Mark-5 board not found \n", me); idr = &zero; /* Input design revision is zero */ odr = &zero; /* Output design revision is zero */ return(-2); /* No I/O board */ } /* * Here (found > 0), we've found Mark-5A IO board or Mark-5B board * */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s Initize() DEBUG: offs %#lx, offp %#lx, found %d \n", me, offs, offp, found); /* * Open file MEM, system memory * */ if ((memp = open(MEM, O_RDWR)) < 0) { /* OK? */ (void) fprintf(stderr, "%s Initize() ERROR: \007 Can't open() file ", me); /* Nope */ perror(MEM); return(-3); /* Error */ } /* * Map board Region 2 to memory * */ if ((buf1 = (unsigned short *) mmap(0, NUMB, PROT_READ | PROT_WRITE, MAP_SHARED, memp, offs)) == MAP_FAILED) { /* OK? */ (void) fprintf(stderr, /* Nope */ "%s Initize() ERROR: \007 Can't mmap() offset %#lx, file ", me, offs); perror(MEM); (void) close(memp); return(-4); /* Error, mmap() failed */ } /* Else OK * * * Did we find Mark-5B board? * */ if (found == 2) { /* Mark-5B? */ if (msglev < 1) /* Yes, debuggery? */ (void) fprintf(stderr, /* Yes */ "%s Initize() DEBUG: Found Mark-5B board \n", me); /* Input design revision and output design revision are both zero */ odr = idr = &zero; /* * Set the SS clock to 33 MHz for Mark-5B * * * Set SS clock on */ if (XLRSetFPDPMode(dev, SS_FPDP_XMITMASTER, 0) != XLR_SUCCESS) { /* OK? */ /* SS_FPDP_XMIT = transmit (does not drive clock), * SS_FPDP_XMITMASTER = normal transmit (with clock) */ (void) fprintf(stderr, /* Nope */ "%s Initize() ERROR: \007 XLRSetFPDPMode() returned error \n", me); (void) errors(); return(-5); /* Error */ } (void) errors(); /* * Set SS "port base clock" to 33-MHz parameters defined above * */ if (XLRSetPortBaseClock(dev, RDW, VDW, OD) != XLR_SUCCESS) { /* OK? */ (void) fprintf(stderr, /* Nope */ "%s Initize() ERROR: \007 XLRSetPortBaseClock() returned error \n", me); (void) errors(); return(-6); /* XLR error */ } (void) errors(); /* Else Mark-5B clock set OK */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s Initize() DEBUG: SS port base clock set to 33 MHz \n", me); buf2 = buf1 + 0x7e00 / 2; /* Offset to DIM (Will's) */ /* Are we in DIM (Will's) or DOM (Brian's) mode? */ /* ?? Lots more Mark-5B stuff goes here ?? */ return(0); /* Normal end for case Mark-5B board */ } /* End of if Mark-5B board */ /* Else Mark5A. Now buf1[] is Dan's, and ... */ buf2 = buf1 + 32; /* Offset to Will's buf2[] */ /* Design revisions (global) for DTS_id */ idr = buf1 + 5; /* Input design revision */ odr = buf2 + 5; /* Output design revision */ /* * Reset * */ buf1[0] = 0; buf1[0] = 0x0200; /* Pulse R */ buf1[0] = 0; /* * Set fill-detection pattern * */ buf2[1] = 0x8000; /* Set F */ buf2[6] = fill >> 16; /* MSBs */ buf2[7] = fill & 0xffff; /* LSBs */ return(0); /* Normal end, Mark5A */ } /* End of Initize() */ static int Debug() { /* More debuggery if requested */ if (msglev < 0) { /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s IOB DEBUG: buf1[0] 0x%4.4x, buf1[1] 0x%4.4x, buf1[2] 0x%4.4x \n", me, buf1[0], buf1[1], buf1[2]); (void) fprintf(stderr, "%s IOB DEBUG: buf1[3] 0x%4.4x, buf1[4] 0x%4.4x, buf1[5] 0x%4.4x \n", me, buf1[3], buf1[4], buf1[5]); (void) fprintf(stderr, "%s IOB DEBUG: buf2[0] 0x%4.4x, buf2[1] 0x%4.4x, buf2[2] 0x%4.4x \n", me, buf2[0], buf2[1], buf2[2]); (void) fprintf(stderr, "%s IOB DEBUG: buf2[3] 0x%4.4x, buf2[4] 0x%4.4x, buf2[5] 0x%4.4x \n", me, buf2[3], buf2[4], buf2[5]); (void) fprintf(stderr, "%s IOB DEBUG: buf2[6] 0x%4.4x, buf2[7] 0x%4.4x, buf2[8] 0x%4.4x \n", me, buf2[6], buf2[7], buf2[8]); } /* End of if debuggery */ return(0); } /* End of Debug() */ int outBoard (int SoG) { /* Talk with the Mark 5A output board. Reference memo: "Mark 5A * Input/Output Board Control/Status," by ARW, 4 October 2001. * SoG is SET to command the output board from parameters in * outb, or SoG is GET to retrieve the parameters from the output * board and put them into outb. */ static char outbmode[8] = ""; /* Previous version */ static double outbfreq = -1.0; static int outbtrka = -1; static int outbtrkb = -1; static int outbtmode = 0; static char outbformt[8] = ""; int j, k, code, trka, trkb; double freq; /* Local diddled frequency, MHz */ unsigned long dphase; /* Delta phase, cf. AD9850 writeup, p. 8 */ unsigned char * dp = (unsigned char *) &dphase; /* ** Initialize? ** */ if (first) { /* First time called? */ k = Initize(); /* Yes, initialize */ first = FALSE; /* Never again (even if error) */ if (k == 0 && found > 0) /* OK? */ ldir.iob = TRUE; /* Yes, we have an I/O board */ else if (k < 0) { /* Found I/O board? */ ldir.iob = FALSE; /* No I/O board in this machine */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s outBoard() WARNING: I/O board not found \n", me); } else { /* Some other error */ if (msglev < 2) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s outBoard() ERROR: Initize() returned error %d \n", me, k); ldir.iob = FALSE; /* Error, assume no I/O board */ } } /* End of if first */ /* ** Check: Do we have an I/O board? ** */ if (found == 0) { /* OK? */ /* No I/O board. Following is a dummy version that does almost nothing */ outb.active = FALSE; /* No I/O board so can't be active */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, "%s outBoard() DEBUG: " /* Yes */ " %s, %s, mode %s, \n freq %.3f, %s, trka %d, trkb %d \n", me, cmd[SoG], outb.active ? "ACTIVE" : "NOT ACTIVE", outb.mode, outb.freq, outb.synced ? "SYNCED" : "NOT SYNCED", outb.trka, outb.trkb); return(0); /* Normal for case no I/O board */ } /* Here we have an I/O board, but which one? */ if (found == 2) { /* Mark5B? */ /* Yes, but this version does almost nothing */ outb.active = FALSE; if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s outBoard() WARNING: Mark5B under construction \n", me); return(0); /* Normal end */ } /* End of if Mark5B */ /* Else Mark5A with I/O board */ /* ** Check: SET? ** */ if (SoG == SET) { /* Set info from struct outb to I/O Board? */ /* * Yes. Clock frequency * */ if (outb.freq != outbfreq || strncasecmp(outb.mode, outbmode, 8) != 0 || outb.tmode != outbtmode || strncasecmp(outb.formt, outbformt, 8) != 0) { /* Changed? */ /* Yes. Check: freq = 0 selects external clock */ if (outb.freq == 0.0) /* External clock? */ buf2[1] &= 0xefff; /* Yes, clear I, preserve F, V, and CODE */ else { /* * Set clock frequency from outb.freq in MHz * */ /* Note that this clock is logically in the output board * but accessed through buf1[]. We multiply by 9/8 to * account for parity, and, for VLBA, we multiply by 126/125 * to account for non-data-replacement tape-frame headers. * And, with 64 tracks, the clock rate needs to double. */ freq = outb.freq; /* Initialize, MHz */ if (strcasecmp(outb.formt, "vlba") == 0 || /* VLBA format? */ strcasecmp(outb.formt, "mark4") == 0) /* Or Mark-4 format? */ freq *= 1.125; /* Yes, account for parity */ if (strcasecmp(outb.formt, "vlba") == 0) /* VLBA format? */ freq *= 1.008; /* Yes, account for non-data-replacement */ if (outb.tmode == 64) /* 64-tracks? */ freq *= 2.0; /* Yes, double clock rate */ dphase = (unsigned long) (freq*42949672.96+0.5); /* 2^32/100 = 42949672.96, cf., AD9850 writeup, p. 8 */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s outBoard() DEBUG: DPhase %#lx %ld \n", me, dphase, dphase); for (j = 0; j < 5; j++) { /* Each Wj */ if (j == 0) /* W0? */ buf1[0] = 0; /* Yes, W0 = phase, cf., AD9850 writeup, p. 10 */ else /* Other j */ buf1[0] = dp[4-j]; /* Wj */ buf1[2] = 1; /* Pulse W = W_CLK */ buf1[2] = 0; } buf1[0] = 0x100; /* Pulse U = FQ_UD */ buf1[0] = 0; /* Reset for next time */ /* * Set to use internal clock * */ buf2[1] |= 0x1000; /* Set I */ } /* End of else set clock frequency */ // /* * Clear counter and acquire sync * */ // buf2[2] = 2; /* Pulse C (off Q) */ // buf2[2] = 0; // buf2[2] = 1; /* And set Q */ outbfreq = outb.freq; /* Save new value for next time */ /* (outb.tmode and outb.formt are used below) */ } /* End of if clock frequency (etc.) changed */ /* * Mode and Tmode? * */ if (strncasecmp(outb.mode, outbmode, 8) != 0 || outb.tmode != outbtmode || strncasecmp(outb.formt, outbformt, 8) != 0) { /* Changed? */ if (strcasecmp(outb.mode, "st") == 0) { /* Yes. ST mode? */ buf2[1] &= 0xfff0; /* Yes, CODE = 4, preserve F, I, and V */ buf2[1] |= 4; /* Set CODE */ } else if (strcasecmp(outb.mode, "tvr") == 0) { /* TVR? */ buf2[1] &= 0xfff0; /* Yes, CODE = 8, preserve F, I, and V */ buf2[1] |= 8; /* Set CODE */ } else if (strcasecmp(outb.mode, "vlbi") == 0) { /* VLBI? */ buf2[1] &= 0xfff0; /* Yes, preserve F, I, and V */ if (outb.tmode == 32) /* 32-track? */ buf2[1] |= 0; /* Yes */ else if (outb.tmode == 64) /* 64-track? */ buf2[1] |= 1; /* Yes */ else if (outb.tmode == 16) /* 16-track? */ buf2[1] |= 2; /* Yes */ else if (outb.tmode == 8) /* 8-track? */ buf2[1] |= 3; /* Yes */ else /* Zero or unknown, default to ST */ buf2[1] |= 4; } /* End of else if VLBI */ else { /* "?" or unknown */ buf2[1] &= 0xfff0; /* Preserve F, I, and V */ buf2[1] |= 4; /* Default to ST */ } /* * Formt? * */ if (strcasecmp(outb.formt, "vlba") == 0) { /* VLBA? */ buf2[1] &= 0xf0ff; /* Reset V, preserve F, I, and CODE */ buf2[1] |= 0x0100; /* Set V (no check) */ } else /* Mark 4 or unknown */ buf2[1] &= 0xf0ff; /* Reset V, preserve F, I, and CODE */ // /* * Clear counter and acquire sync * */ // buf2[2] = 2; /* Pulse C (off Q) */ // buf2[2] = 0; // buf2[2] = 1; /* And set Q */ (void) strncpy(outbmode, outb.mode, 8); /* For next time */ outbtmode = outb.tmode; (void) strncpy(outbformt, outb.formt, 8); } /* End of if mode or tmode changed */ /* * Tracks A and B * */ /* (Some terminological confusion between tracks and channels; * we're actually calculating bit numbers) */ if (outb.trka != outbtrka) { /* Changed? */ trka = outb.trka - (outb.trka > 100 ? 70 : 2); /* Yes */ /* (-100 + 32 - 2 = -70) */ buf2[0] &= 0xff00; /* Preserve CHB */ buf2[0] |= trka; /* Set CHA */ outbtrka = outb.trka; /* For next time */ } if (outb.trkb != outbtrkb) { /* Changed? */ trkb = outb.trkb - (outb.trkb > 100 ? 70 : 2); /* Yes */ buf2[0] &= 0x00ff; /* Preserve CHA */ buf2[0] |= trkb << 8; /* Set CHB */ outbtrkb = outb.trkb; /* For next time */ } /* We now do the CQ trick on SET even if nothing has changed */ buf2[2] = 2; /* Pulse C (off Q) */ buf2[2] = 0; buf2[2] = 1; /* And set Q */ } /* End of if SET */ /* ** Check: GET? ** */ else if (SoG == GET) { /* Get info from I/O board to struct outb? */ /* * Yes, zctive and synced? * */ outb.active = buf2[2] & 0x0001; /* Q, TRUE or FALSE */ outb.synced = buf2[3] & 0x0001; /* S, TRUE or FALSE */ outb.numrs = buf2[4]; /* Number of re-syncs */ /* outb.mode is vlbi or st, outb.tmode is 8, 16, 32, 64, * or 0 if unknown, outb.formt is mark4, vlba, or null if * unknown, all as read from the output board */ code = buf2[1] & 0x000f; /* Output board CODE */ /* * Find outb.mode * */ if (code < 4) /* VLBI? */ (void) strcpy(outb.mode, "vlbi"); /* Yes */ else if (code == 4) /* Straight through? */ (void) strcpy(outb.mode, "st"); /* Yes */ else if (code > 7) /* TVR? */ (void) strcpy(outb.mode, "tvr"); /* Yes */ else /* Unknown */ (void) strcpy(outb.mode, "?"); /* * Find formt * */ if (code > 7) /* TVR? */ (void) strcpy(outb.formt, "tvr"); /* Yes */ else if (buf2[1] & 0x100) /* VLBA? */ (void) strcpy(outb.formt, "vlba"); /* Yes */ else if (code < 4) /* Mark 4? */ (void) strcpy(outb.formt, "mark4"); /* Yes */ /* Else unknown, leave outb.formt unchanged */ /* * Find tmode * */ if (code == 0 || code == 4) /* 32 tracks or ST? */ outb.tmode = 32; /* Yes */ else if (code == 1) /* 64 tracks? */ outb.tmode = 64; /* Yes */ else if (code == 2) /* 16 tracks? */ outb.tmode = 16; else if (code == 3) /* 8 tracks? */ outb.tmode = 8; /* Yes */ else /* Unknown (probably TVR) */ outb.tmode = 0; /* * Throttled bit * */ outb.throt = buf2[1] & 0x80; /* SF = suspend flag */ buf2[1] = buf2[1] & 0xff7f; /* Clear it for next time */ /* * Tracks A and B * */ /* (Some terminological confusion between tracks and channels; * we start with bit numbers) */ trka = buf2[0] & 0xff; /* Channel A */ trkb = buf2[0] >> 8; /* Channel B */ outb.trka = trka + (trka > 31 ? 70 : 2); /* (100 - 32 + 2 = 70) */ outb.trkb = trkb + (trkb > 31 ? 70 : 2); /* (We can't read back the clock frequency) */ } /* End of else if GET */ else /* * Neither SET nor GET is an error * */ return(-2); /* Error */ (void) Debug(); return(0); /* Normal for case have I/O board */ } /* End of outBoard() */ int inBoard (int SoG) { /* Talk with the Mark 5A input board. Reference memo: "Mark 5A * Input/Output Board Control/Status," by ARW, 4 October 2001. * SoG is SET to command the input board from parameters in * inb, or SoG is GET to retrieve the parameters from the input * board and put them into inb. */ static char inbmode[8] = ""; /* Previous version */ static int inbntracks = -1; int k, mode; /* ** Initialize? ** */ if (first) { /* First time called? */ k = Initize(); /* Yes, initialize */ first = FALSE; /* Never again (even if error) */ if (k == 0) /* OK? */ ldir.iob = TRUE; /* Yes, we have an I/O board */ else if (k == -2) { /* Found I/O board? */ ldir.iob = FALSE; /* No I/O board in this machine */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s inBoard() WARNING: I/O board not found \n", me); } else { /* Some other error */ if (msglev < 2) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s inBoard() ERROR: Initize() returned error %d \n", me, k); ldir.iob = FALSE; /* Error, assume no I/O board */ } } /* End of if first */ /* ** Check: Do we have an I/O board? ** */ if (! ldir.iob) { /* OK? */ /* No I/O board. Following is a dummy version that does almost nothing */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s inBoard() DEBUG: %s, mode %s \n", me, cmd[SoG], inb.mode); return(0); /* Normal for case no I/O board */ } /* Here we have an I/O board */ /* ** Check: SET? ** */ if (SoG == SET) { /* Set info from struct inb to I/O Board? */ /* * Yes, set MODE from inb.mode and inb.ntracks * */ if (strncasecmp(inb.mode, inbmode, 8) != 0 || inb.ntracks != inbntracks) { /* Changed? */ if (strcasecmp(inb.mode, "st") == 0) { /* ST mode? */ buf1[1] &= 0x0f00; /* Yes, MODE = 4, preserve V */ buf1[1] |= 4; /* Set MODE */ } else if (strcasecmp(inb.mode, "test") == 0 || strcasecmp(inb.mode, "tvg") == 0) { /* TVG? */ buf1[1] &= 0x0f00; /* Yes, MODE = 8, preserve V */ buf1[1] |= 8; /* Set MODE */ } else if (strcasecmp(inb.mode, "vlbi") == 0 || strcasecmp(inb.mode, "vlba") == 0 || strcasecmp(inb.mode, "mark4") == 0) { /* VLBI? */ if (strcasecmp(inb.mode, "vlba") == 0) /* Yes, VLBA? */ buf1[1] = 0x0100; /* Yes, set V */ else /* Not VLBA */ buf1[1] = 0; /* Clear V */ if (inb.ntracks == 32) /* 32 tracks? */ buf1[1] |= 0; /* Yes */ else if (inb.ntracks == 64) /* 64 tracks? */ buf1[1] |= 1; /* Yes */ else if (inb.ntracks == 16) /* 16 tracks? */ buf1[1] |= 2; /* Yes */ else if (inb.ntracks == 8) /* 8 tracks? */ buf1[1] |= 3; /* Yes */ else /* Zero or unknown, default to ST */ buf1[1] |= 4; } /* End of else if VLBI or VLBA */ else { /* "?" or unknown */ buf1[1] &= 0x0f00; /* Preserve V */ buf1[1] |= 4; /* Default to ST */ } (void) strncpy(inbmode, inb.mode, 8); /* For next time */ inbntracks = inb.ntracks; } /* End of if changed */ /* Set noclock bit */ if (inb.notclock) /* Clock off? */ buf1[4] = 1; /* Yes */ else /* Normal, clock on */ buf1[4] = 0; } /* End of if SET */ /* ** Check: GET? ** */ else if (SoG == GET) { /* Get info from I/O board to struct inb? */ mode = buf1[1] & 0x00ff; /* Yes, get MODE */ if (mode > 7) /* TVG? */ (void) strcpy(inb.mode, "tvg"); /* Yes */ else if (mode == 4) /* ST? */ (void) strcpy(inb.mode, "st"); /* Yes */ else if (mode < 4 && buf1[1] & 0x0f00) /* VLBA? */ (void) strcpy(inb.mode, "vlba"); /* Yes */ else if (mode < 4) /* Other VLBI = mark4? */ (void) strcpy(inb.mode, "mark4"); /* Yes */ else /* Unknown */ (void) strcpy(inb.mode, "?"); /* * Find ntracks * */ if (mode == 0 || mode == 4) /* 32 tracks or ST? */ inb.ntracks = 32; /* Yes */ else if (mode == 1) /* 64 tracks? */ inb.ntracks = 64; /* Yes */ else if (mode == 2) /* 16 tracks? */ inb.ntracks = 16; else if (mode == 3) /* 8 tracks? */ inb.ntracks = 8; /* Yes */ else /* Unknown (probably TVG) */ inb.ntracks = 0; inb.errb = buf1[3]; /* Error bit(s) */ } /* End of else if GET */ else /* * Neither SET nor GET is an error * */ return(-2); /* Error */ (void) Debug(); return(0); /* Normal for case have I/O board */ } /* End of inBoard() */