home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!husc6!necntc!ncoast!allbery
- From: lee@srs.UUCP (Lee Hasiuk)
- Newsgroups: comp.sources.misc
- Subject: Sun Multibus to VME Adapter Switch Setting Program
- Message-ID: <4845@ncoast.UUCP>
- Date: 13 Oct 87 02:42:08 GMT
- Sender: allbery@ncoast.UUCP
- Lines: 768
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8710/6
-
- I have written a program (enclosed) which will hopefully make it much
- easier for those of you faced with having to set up Sun VME to Multibus
- adapters. The program is called vme2mb and takes as arguments a
- description of your device and outputs a complete list of switch
- settings.
-
- Enjoy!
-
- Lee Hasiuk
- Speech Recognition Systems
- Rochester, NY
- {rutgers, ames, allegra}!rochester!srs!lee
-
- #!/bin/sh
- #
- # shar archiver, delete everything above the #!/bin/sh line
- # and run through sh (not csh)
- #
- echo 'shar: extracting "vme2mb.doc" (4755 characters)'
- # 'vme2mb.doc' has a checksum of 54470 on BSD and 51163 on System V.
- sed 's/^X//' > vme2mb.doc << 'XXX_EOF_XXX'
- Xvme2mb- Determine switch settings for a Sun VME to Multibus adapter
- X
- XSYNOPSIS
- X
- Xvme2mb {-m addr,size} {-i addr,size} {-v vec} {-d 20/24} {-o offset}
- X
- XDESCRIPTION
- X
- XGiven a description of a device in Multibus address space, produce switch
- Xsettings for a Sun Microsystems VME to Multibus Adapter part # 501-1054.
- XThe settings are output in an order which is helpful when setting up the
- Xboard. If the board is oriented as follows (looking at the component side):
- X
- X (TOP)
- X--------------- ------------------ ----------------
- X| VMEbus P1 | | VMEbus P2 | | VMEbus P3 |
- X------------------------------------------------------------
- X| DIP2 DIP10 |
- X| DIP8 DIP6 |
- X| DIP1 DIP9 |
- X| DIP7 DIP5 |
- X| |
- X| DIP3 |
- X| DIP12 DIP11 DIP4 |
- X------------------------------------------------------------
- X| Mutilbus P2 | | Multibus P1 |
- X----------------------- ----------------------------------
- X (BOTTOM)
- X
- Xthe switch settings are output starting from the left, going
- Xdown each column from top to bottom until the bottom of the right hand
- Xcolumn is reached.
- X
- XOPTIONS
- X
- XAll numbers supplied to the program may be in decimal or hexadecimal notation.
- XHexadecimal numbers must be preceeded by 0x or 0X.
- X
- X-m addr,size
- XDefault: no memory address response
- X
- XSets the memory address space response of the board. 'addr' is the base
- Xaddress, and 'size' is the number of bytes which your device uses, starting
- Xat the given address. 'size' will be rounded up to 256 or the closest power
- Xof two, whichever is greater, due to the implementation of the adapter board.
- XMay be used with -i option below for boards with both memory and I/O response.
- X
- X-i addr,size
- XDefault: no I/O address response
- X
- XSets the I/O address space response of the board. 'addr' is the base
- Xaddress, and 'size' is the number of bytes which your device uses, starting
- Xat the given address. 'size' will be rounded up to the closest non-zero
- Xpower of two, due to the implementation of the adapter board.
- XMay be used with -m option above for boards with both memory and I/O response.
- X
- X-v vec
- XDefault: interrupt vector assumed to be in PROM
- X
- XSets the interrupt vector which is generated when the Multibus board requests
- Xan interrupt at any level. If the vector is not specified, the board is
- Xsetup so that none of the vector switches are set. This is the proper setting
- Xwhen interrupt vectors are stored in a PROM supplied by the user.
- X
- X-d 20/24
- XDefault: -d 20
- X
- XSets the number of bits that your Multibus board supplies when doing DMA
- Xtransfers to the VMEbus. The only legal values for this parameter are 20
- Xor 24 (or 0x14/0x18). BEWARE: Some Sun boards that would appear to be
- X24 bit DMA devices will not work when they pass all 24 bits. The
- XXylogics 472 tape controller (xtc0) comes to mind as having this problem.
- X24 bit DMA isn't necessary unless you expect your board to transfer data
- Xdirectly to another VMEbus device.
- X
- X-o off
- XDefault: -o 0x000000
- X
- XSets the DMA offset when setting up a 20 bit (-d 20) DMA device to do
- XDMA to other than the Sun DVMA space. Only the top 4 bits of the supplied
- X24 bit value are used, the other bits must be zero. It is extremely rare
- Xfor a device to require the use of this parameter.
- X
- XOUTPUT
- X
- XThe output is a list of all the dip switches on the board, with the settings
- Xfor each section of each switch. Each switch has 8 sections which can either
- Xbe ON (switch up if board held in above orientation), OFF (switch down),
- Xor X. X means that it doesn't matter which way the switch is set.
- X
- XEXAMPLES
- X
- XHere are a few vme2mb command lines for various well-known Sun devices:
- X
- X1) Xylogics 450 disk controller
- X Address space: Multibus I/O
- X Base address: 0xee40
- X Size: 6 bytes (rounded to 8)
- X Vector: 0x48
- X DMA address provided: 24 bits
- X
- X vme2mb -i 0xee40,8 -v 0x48 -d 24
- X
- X2) Tapemaster 1/2 inch tape controller
- X Address space: Multibus I/O
- X Base address: 0x60
- X Size: 2 bytes
- X Vector: 0x60
- X DMA address provided: 20 bits
- X
- X vme2mb -i 0x60,2 -v 0x60
- X
- XSEE ALSO
- X
- XSun VME-Multibus Adapter Board User's Manual
- XPart Number 800-1193-05
- XRevision: A of 25 September 1986
- X
- XBEWARE of earlier revisions (also labelled A, but with earlier dates),
- Xthey contain incorrect information about setting up the DMA dip switch!
- X
- XTRADEMARKS
- X
- XMultibus is a trademark of Intel Corporation
- X
- XSun, Sun Microsystems, Sun Workstation, and DVMA are registered trademarks
- Xof Sun Microsystems, Incorporated.
- XXX_EOF_XXX
- if test 4755 -ne "`wc -c < vme2mb.doc`"
- then
- echo 'shar: transmission error on "vme2mb.doc"'
- fi
- chk=`sum vme2mb.doc | awk '{print $1}'`
- if test 54470 -ne $chk -a 51163 -ne $chk
- then
- echo 'shar: checksum error on "vme2mb.doc"'
- fi
- echo 'shar: extracting "Makefile" (40 characters)'
- # 'Makefile' has a checksum of 46411 on BSD and 3199 on System V.
- sed 's/^X//' > Makefile << 'XXX_EOF_XXX'
- Xvme2mb: vme2mb.c
- X cc -o vme2mb vme2mb.c
- XXX_EOF_XXX
- if test 40 -ne "`wc -c < Makefile`"
- then
- echo 'shar: transmission error on "Makefile"'
- fi
- chk=`sum Makefile | awk '{print $1}'`
- if test 46411 -ne $chk -a 3199 -ne $chk
- then
- echo 'shar: checksum error on "Makefile"'
- fi
- echo 'shar: extracting "vme2mb.c" (16196 characters)'
- # 'vme2mb.c' has a checksum of 51222 on BSD and 40552 on System V.
- sed 's/^X//' > vme2mb.c << 'XXX_EOF_XXX'
- X#ifndef lint
- Xstatic char sccsId[] = "@(#)vme2mb.c 1.1 9/30/87 SRS";
- X#endif
- X
- X/*
- X * Produce switch settings for a Sun VME to Multibus adapter.
- X *
- X * Lee Hasiuk
- X * Speech Recognition Systems
- X * 1895 Mt. Hope Ave.
- X * Rochester, NY 14620
- X * (716) 271-0600
- X *
- X */
- X
- X#include <stdio.h>
- X#include <strings.h>
- X#include <ctype.h>
- X
- Xtypedef short boolean;
- X
- X#define FALSE 0
- X#define TRUE 1
- X#define DONTCARE -1
- X
- X#define NSW 8 /* # of switches in a dip switch */
- X#define NDIP (12 + 1) /* # of dip switches on board, 0 not used */
- X
- X/*
- X * Structure defining a dip switch; sense is TRUE if a switch is ON for a 1
- X * or FALSE is switch is ON for a 0. Bits is an array with one element for
- X * each section of a dip switch. The value stored in element i of bits is
- X * the bit number (0 = LSB, 31 = MSB) which the i+1th section of the dip
- X * switch is set for. For example, if sense was FALSE and bits[0]
- X * was 23, section 1 of the dip switch would be ON if bit 23 of the number
- X * being used to set it was 0. The meaning of the number being used to set
- X * the dip switch varies with the dip switch. If bits[n] is -1, the
- X * n+1th section of the dip switch is not bit specific, and may be
- X * either a don't care or be used in some other way.
- X */
- Xtypedef struct {
- X boolean sense;
- X short bits[NSW];
- X} dipSw;
- X
- X/* The board's switches and their meanings */
- X#define X DONTCARE
- Xstatic dipSw dips[] = {
- X /* 1 2 3 4 5 6 7 8 - section number of switch */
- X { FALSE, X, X, X, X, X, X, X, X }, /* DIP0 - not real */
- X { FALSE, X, 7, 6, 5, 4, 3, 2, 1 }, /* DIP1 */
- X { FALSE, X, 7, 6, 5, 4, 3, 2, 1 }, /* DIP2 */
- X { FALSE, 15, 14, 13, 12, 11, 10, 9, 8 }, /* DIP3 */
- X { FALSE, 15, 14, 13, 12, 11, 10, 9, 8 }, /* DIP4 */
- X { FALSE, 15, 14, 13, 12, 11, 10, 9, 8 }, /* DIP5 */
- X { FALSE, 15, 14, 13, 12, 11, 10, 9, 8 }, /* DIP6 */
- X { FALSE, 23, 22, 21, 20, 19, 18, 17, 16 }, /* DIP7 */
- X { FALSE, 23, 22, 21, 20, 19, 18, 17, 16 }, /* DIP8 */
- X { TRUE, 0, 0, 0, 0, 0, 0, 0, 0 }, /* DIP9 */
- X { TRUE, 0, 0, 0, 0, 0, 0, 0, 0 }, /* DIP10 */
- X { TRUE, 23, 22, 21, 20, X, X, X, X }, /* DIP11 */
- X { FALSE, 0, 1, 2, 3, 4, 5, 6, 7 }, /* DIP12 */
- X};
- X#undef X
- X
- X/*
- X * Order that switch settings will be listed. Looking at component side
- X * of board, with VME connectors farthest from you, we go top to bottom,
- X * and left to right.
- X * (TOP)
- X * --------------- ------------------ ----------------
- X * | VMEbus P1 | | VMEbus P2 | | VMEbus P3 |
- X * ------------------------------------------------------------
- X * | DIP2 DIP10 |
- X * | DIP8 DIP6 |
- X * | DIP1 DIP9 |
- X * | DIP7 DIP5 |
- X * | |
- X * | DIP3 |
- X * | DIP12 DIP11 DIP4 |
- X * ------------------------------------------------------------
- X * | Mutilbus P2 | | Multibus P1 |
- X * ----------------------- ----------------------------------
- X * (BOTTOM)
- X */
- Xstatic int dumpOrder[] = { 12, 8, 7, 11, 6, 5, 4, 2, 1, 3, 10, 9 };
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X static long memDescr[2] = {0, 0};
- X static long ioDescr[2] = {0, 0};
- X long intVec = -1; /* If no vector supplied, may be PROMed, switches off */
- X long dmaSize = 20; /* Default to 20 bit addressing; a must for xt0 */
- X long dmaOff = 0; /* DMA offset is usually 0 - DVMA space */
- X boolean set[NDIP][NSW]; /* Settings go here */
- X char opt;
- X extern char *optarg;
- X extern int opterr;
- X
- X /* Though we could run with no args, they probably want a usage message */
- X if (argc < 2)
- X usage();
- X
- X opterr = 0;
- X while ((opt = getopt(argc, argv, "m:i:v:d:o:")) != EOF) {
- X switch (opt) {
- X case 'm':
- X
- X /* Multibus memory space specified, 2 numbers to parse */
- X getVals(optarg, memDescr, 2);
- X break;
- X case 'i':
- X
- X /* Multibus i/o space specified, 2 numbers to parse */
- X getVals(optarg, ioDescr, 2);
- X break;
- X case 'v':
- X
- X /* Interrupt vector supplied, 1 number to parse */
- X getVals(optarg, &intVec, 1);
- X break;
- X case 'd':
- X
- X /* DMA type specified, 1 number to parse */
- X getVals(optarg, &dmaSize, 1);
- X break;
- X case 'o':
- X
- X /* DMA offset specified, 1 number to parse */
- X getVals(optarg, &dmaOff, 1);
- X break;
- X default:
- X
- X /* Huh ? */
- X usage();
- X }
- X }
- X
- X /* Given their parameters, set up the switches */
- X vme2mb(dips, set, memDescr, ioDescr, intVec, dmaSize, dmaOff);
- X
- X /* Now print out the mess - somebody want to add graphics? */
- X showSettings(set, NDIP - 1, dumpOrder);
- X
- X exit(0);
- X}
- X
- X/*
- X * Give a usage message and leave.
- X */
- Xstatic
- Xusage()
- X{
- X (void)fprintf(stderr, "\
- XUsage: vme2mb {-m addr,size} {-i addr,size} {-v vec} {-d 20/24} {-o offset}\n");
- X exit(1);
- X}
- X
- X/*
- X * Given a set of switches, and the board's parameters, set up switches
- X * as specified by the parameters. Output goes into an array which
- X * is index by [switch #][section # - 1] and a FALSE indicates an off,
- X * TRUE an ON, and DONTCARE can be either.
- X */
- Xstatic
- Xvme2mb(dips, set, mem, io, vec, dsiz, doff)
- XdipSw dips[];
- Xboolean set[][NSW];
- Xlong mem[], io[], vec, dsiz, doff;
- X{
- X
- X /* Set up mem space switches; dip 8 & 6 are blksize (min 256), 7 & 5 base */
- X doAddrSpace(mem, (long) 256, dips, set, 8, 6, 7, 5);
- X
- X /* Set up io space; dip 4 & 2 are blocksize (min 2), 3 & 1 base */
- X doAddrSpace(io, (long) 2, dips, set, 4, 2, 3, 1);
- X
- X /* Set up interrupt vector in dip 12 */
- X doIntVec(vec, dips, set, 12);
- X
- X /* Set up dma in dip 11 */
- X doDma(dsiz, doff, dips, set, 11);
- X
- X /* Dip 9 and 10 are unused, usually set to all off */
- X setSw((long) 0, &dips[9], set[9]);
- X setSw((long) 0, &dips[10], set[10]);
- X}
- X
- X/*
- X * Given 20 or 24 bit DMA size and possibly a 24 bit offset, set up
- X * the DMA dip switch.
- X */
- Xstatic
- XdoDma(dsiz, doff, dip, set, sw)
- Xlong dsiz, doff; /* DMA size (20 or 24) and offset */
- XdipSw dip[]; /* DIP switch descriptions */
- Xshort set[][NSW]; /* Where the settings go */
- Xint sw; /* Switch to set */
- X{
- X
- X /* 20 bit DMA ? */
- X if (dsiz == 20) {
- X
- X /* Offset can only have bits set in MSN of 24 bit address */
- X if ((doff & 0x0fffff) != 0)
- X err("Only bits 23-20 of DMA offset may be used", (char *) 0);
- X
- X /* Set offset switches */
- X setSw(doff, &dip[sw], set[sw]);
- X
- X /* Force sections 5-8 off; no 24 bit address supplied by Multibus bd */
- X forceSw(set[sw], 5, FALSE);
- X forceSw(set[sw], 6, FALSE);
- X forceSw(set[sw], 7, FALSE);
- X forceSw(set[sw], 8, FALSE);
- X }
- X
- X /* 24 bit DMA ? */
- X else if (dsiz == 24) {
- X
- X /* No offset allowed */
- X if (doff != 0)
- X err("Can't use DMA offset with 24 bit DMA", (char *) 0);
- X
- X /* Switches are 1-4 off, 5-8 on to pass high bits unaltered */
- X forceSw(set[sw], 1, FALSE);
- X forceSw(set[sw], 2, FALSE);
- X forceSw(set[sw], 3, FALSE);
- X forceSw(set[sw], 4, FALSE);
- X forceSw(set[sw], 5, TRUE);
- X forceSw(set[sw], 6, TRUE);
- X forceSw(set[sw], 7, TRUE);
- X forceSw(set[sw], 8, TRUE);
- X }
- X else
- X
- X /* Unknown DMA request */
- X err("DMA size must be either 20 or 24", (char *) 0);
- X}
- X
- X/*
- X * Set up the dip switch used for interrupt vector generation. Should be
- X * passed a -1 for vec if no vector is supplied by user; this forces all
- X * switch sections off, we is the way we would be if user provided a PROM
- X * for interrupt vector generation.
- X */
- Xstatic
- XdoIntVec(vec, dip, set, sw)
- Xlong vec; /* Interrupt vector */
- XdipSw dip[]; /* DIP switch descriptions */
- Xshort set[][NSW]; /* Where the settings go */
- Xint sw; /* Switch # to set */
- X{
- X
- X /* Classic switch; just set it and return */
- X setSw(vec, &dip[sw], set[sw]);
- X}
- X
- X/*
- X * Set up switches for an address space; address spaces are specified by
- X * a two element array, the 0th element being the base address, and the
- X * next element the size. Four switches are provided for setting; two
- X * for the block size (order unimportant) and two for the base address
- X * (order also unimportant). If the block size is 0, the switch is set
- X * for no response in that address space. If block size is less than
- X * minimum, it is set to minimum. If it isn't a power of two, it is
- X * rounded to the next highest power of two.
- X */
- Xstatic
- XdoAddrSpace(space, minblk, dip, set, block1, block2, addr1, addr2)
- Xlong space[]; /* Adress space description */
- Xlong minblk; /* Minimum blocksize allowed */
- XdipSw dip[]; /* DIP switch descriptions */
- Xshort set[][NSW]; /* Where the settings go */
- Xint block1, block2; /* Switches for block size */
- Xint addr1, addr2; /* Switches for base address */
- X{
- X
- X /* Does board use this space ? */
- X if (space[1] != 0) {
- X
- X /* Yes, make the block size a power of two, at least minblk */
- X makeValidBlockSize(&space[1], minblk);
- X
- X /* Set the block size switches */
- X doBlockSize(space[1], &dip[block1], set[block1]);
- X doBlockSize(space[1], &dip[block2], set[block2]);
- X
- X /* Set the base address switches */
- X doBaseAddr(space[0], space[1], &dip[addr1], set[addr1]);
- X doBaseAddr(space[0], space[1], &dip[addr2], set[addr2]);
- X }
- X else {
- X
- X /* Address space not used, set switches for no response */
- X setSw((long) -1, &dip[block1], set[block1]);
- X setSw((long) -1, &dip[block2], set[block2]);
- X setSw((long) 0, &dip[addr1], set[addr1]);
- X setSw((long) 0, &dip[addr2], set[addr2]);
- X }
- X}
- X
- X/*
- X * Apply the algorithm for converting a block size to a number that the
- X * switch setter can use. The goal is to covert a number with a single
- X * bit set (a legal block size) to a number with all of the bits that
- X * are less than that bit set, and the original bit not set. Sounds
- X * like subtracting 1, doesn't it?
- X */
- Xstatic
- XdoBlockSize(size, dipswp, settings)
- Xlong size;
- XdipSw *dipswp;
- Xboolean settings[];
- X{
- X
- X /* Apply the 'algorithm' */
- X size -= 1;
- X
- X /* Set the switches */
- X setSw(size, dipswp, settings);
- X}
- X
- X/*
- X * Apply the algorithm for converting a block size and a base address
- X * to a number that the switch setter can use. The goal is to take the
- X * blocksize (with one bit set), subtract one from it (thus setting
- X * bits lower than the one set), then or'ing this number with the
- X * base address.
- X */
- Xstatic
- XdoBaseAddr(base, size, dipswp, settings)
- Xlong base, size;
- XdipSw *dipswp;
- Xboolean settings[];
- X{
- X /* Apply the 'algorithm' */
- X base |= size - 1;
- X
- X /* Set the switches */
- X setSw(base, dipswp, settings);
- X}
- X
- X/*
- X * Print out the dip switch settings in the order specified by an array of
- X * ints indexing into the setting array.
- X */
- XshowSettings(set, nset, order)
- Xboolean set[][NSW];
- Xint nset;
- Xint order[];
- X{
- X int i;
- X
- X for (i = 0; i < nset; i++)
- X dumpSw(set, order[i]);
- X}
- X
- X/*
- X * Given a switch number and the settings; print out the settings for
- X * that switch.
- X */
- Xstatic
- XdumpSw(set, sw)
- Xboolean set[][NSW]; /* The array of switch settings */
- Xint sw; /* Switch # to be displayed */
- X{
- X int i;
- X
- X (void)printf("DIP%-2d: ", sw);
- X for (i = 0; i < NSW; i++) {
- X if (set[sw][i] == TRUE)
- X (void)printf("%d ON ", i + 1);
- X else if (set[sw][i] == FALSE)
- X (void)printf("%d OFF ", i + 1);
- X else
- X (void)printf("%d X ", i + 1);
- X }
- X (void)printf("\n");
- X}
- X
- X/*
- X * Force a section of an already chosen DIP switch to a particular
- X * (ON, OFF, DONTCARE) value. The section number is 1 through 8,
- X * but the setting array is indexed 0 through 7.
- X */
- Xstatic
- XforceSw(settings, sw, how)
- Xboolean settings[];
- Xint sw;
- Xboolean how;
- X{
- X
- X /* Force the setting */
- X settings[sw - 1] = how;
- X}
- X
- X/*
- X * Given a number and a description of how a dip switch is set (based on
- X * which sections are affected by which bits of the number), set the dip
- X * switch by putting the states of the switches in an array.
- X */
- Xstatic
- XsetSw(val, dipswp, settings)
- Xlong val; /* Value to set in the switches */
- XdipSw *dipswp; /* Description of this switch */
- Xboolean settings[]; /* Where the settings go */
- X{
- X int i;
- X short bit;
- X
- X /* Go through each section of the switch */
- X for (i = 0; i < NSW; i++) {
- X
- X /* Is this position used (!= DONTCARE) ? */
- X if ((bit = dipswp->bits[i]) != DONTCARE) {
- X
- X /* Position used, is corresponding bit set in the input value? */
- X if (val & (1 << bit))
- X
- X /* Bit set, set the switch according to its sense */
- X settings[i] = dipswp->sense;
- X else
- X
- X /* Bit not set, set the switch opposite to its sense */
- X settings[i] = !dipswp->sense;
- X }
- X else
- X
- X /* Position not used, switch is a don't care, for now */
- X settings[i] = DONTCARE;
- X }
- X}
- X
- X/*
- X * Convert a potential block size for a device into a valid one. This
- X * involves making sure that it is at least a minimum value (smallest that
- X * can be set with the switches) and a power of 2. If either does not hold,
- X * the block size is rounded up and a warning sent to stderr.
- X */
- Xstatic
- XmakeValidBlockSize(valp, minval)
- Xlong *valp; /* Pointer to number to be made valid */
- Xlong minval; /* Minimum block size allowable */
- X{
- X long val = *valp;
- X int highest, lowest, i;
- X
- X /* Block size must be at least minval */
- X if (val < minval) {
- X
- X /* It wasn't; print a warning, set it to minimum and return */
- X (void)fprintf(stderr,
- X "Set blocksize of %ld to minimum allowable of %ld\n",
- X val, minval);
- X *valp = minval;
- X return;
- X }
- X
- X /* Find the highest bit set; and ensure that it's also the lowest */
- X highest = lowest = 0;
- X
- X /* Cycle through the bits */
- X for (i = 1; i <= 32; i++) {
- X
- X /* Bit set ? */
- X if (val & 1) {
- X
- X /* Bit is set, has lowest been detected ? */
- X if (lowest == 0)
- X
- X /* No, this is the lowest bit */
- X lowest = i;
- X
- X /* Bit is set, may be highest bit */
- X highest = i;
- X }
- X
- X /* Get to next bit */
- X val >>= 1;
- X }
- X
- X /* Are highest and lowest the same bit ? */
- X if (highest != lowest) {
- X
- X /* No, round up, print warning and return */
- X val = 1 << highest;
- X (void)fprintf(stderr, "Blocksize of %ld rounded up to %ld\n",
- X *valp, val);
- X *valp = val;
- X }
- X}
- X
- X/*
- X * Print an error message with possibly one string argument. Exit with
- X * non-zero status.
- X */
- Xstatic
- Xerr(fmt, param)
- Xchar *fmt, *param;
- X{
- X (void)fprintf(stderr, fmt, param);
- X (void)fprintf(stderr, "\n");
- X exit(1);
- X}
- X
- X/*
- X * Given a string containing numbers in hex or decimal format, an array
- X * to place their binary values in and a count, parse the string. The
- X * numbers are separated by commas.
- X */
- Xstatic
- XgetVals(str, vals, count)
- Xchar *str; /* String containing the numbers */
- Xlong *vals; /* Array to place the values in */
- Xint count; /* Number of values to be parsed */
- X{
- X long numParse();
- X char *p, *strtok();
- X char buf[255];
- X
- X /* Make a copy of the string, since strtok() will trash it */
- X (void)strcpy(buf, str);
- X
- X /* Parse it based on commas as separators */
- X p = strtok(buf, ",");
- X
- X /* Cycle until end of string or we get all that we want */
- X while (p && count--) {
- X
- X /* Extract the value, place it in the array */
- X *vals++ = numParse(p);
- X
- X /* Advance to next possible number */
- X p = strtok((char *) 0, ",");
- X }
- X
- X /* If we didn't parse the whole string, or didn't get all the values we
- X need, perhaps the user doesn't understand how we work */
- X if (p || count)
- X usage();
- X}
- X
- X/*
- X * Take a string, and extract either a hexadecimal or decimal number from it.
- X * It is a fatal error if we can't get either.
- X * Returns the value.
- X */
- Xstatic long
- XnumParse(str)
- Xchar *str;
- X{
- X long scanval;
- X char foo[255];
- X
- X /* Convert upper case to lower case (to parse 0x) */
- X lcase(str);
- X
- X /* Scanf parsing; number may be hex, with no garbage afterward */
- X if (sscanf(str, "0x%lx%[^\1-\127]", &scanval, foo) == 1 ||
- X
- X /* Or decimal, again with no garbage */
- X sscanf(str, "%ld%[^\1-\127]", &scanval, foo) == 1)
- X return(scanval);
- X
- X /* Didn't grok it */
- X err("Cannot parse number: %s", str);
- X /*NOTREACHED*/
- X}
- X
- X/*
- X * Convert upper case characters in a string to lower case.
- X */
- Xlcase(p)
- Xchar *p;
- X{
- X for (; *p != '\0'; p++)
- X if (isupper(*p))
- X *p = tolower(*p);
- X}
- XXX_EOF_XXX
- if test 16196 -ne "`wc -c < vme2mb.c`"
- then
- echo 'shar: transmission error on "vme2mb.c"'
- fi
- chk=`sum vme2mb.c | awk '{print $1}'`
- if test 51222 -ne $chk -a 40552 -ne $chk
- then
- echo 'shar: checksum error on "vme2mb.c"'
- fi
-