Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!seismo!mimsy!chris From: chris@mimsy.UUCP Newsgroups: comp.unix.questions Subject: Re: Let the Sun-3 beep! How??? Message-ID: <6503@mimsy.UUCP> Date: Thu, 30-Apr-87 00:49:05 EDT Article-I.D.: mimsy.6503 Posted: Thu Apr 30 00:49:05 1987 Date-Received: Fri, 1-May-87 02:46:12 EDT References: <1415@ames.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 254 In article <1415@ames.UUCP> watson@ames.UUCP (John S. Watson) writes: >Here is a morse code program for Sun workstations. John's program works, but, being a fan of data structures, I had to rewrite it. Also, his tends to use inordinate amounts of CPU time, to run at different speeds on different kinds of Suns, and to sound somewhat lopsided if you had something in the background. Moreover, if you interrupted it, it might leave the bell on, which is decidedly annoying. This version's output is essentially identical. The single optional argument specifies the number of milliseconds for the basic time unit (default 30). The Sun timer resolution is somewhat low, and values between 21 and 30 all act the same, and 20 runs 50% faster than these; this is an annoyance, but it does keep the CPU time down. /* * Morse Code Program for Suns * * Inspired by version by: * John S. Watson 4/29/87 * NASA Ames Research Center * ARPA: watson@ames.arpa * UUCP: ...!ames!watson * * This version by: * Chris Torek 4/29/87 * University of Maryland * Department of Computer Science * (chris@mimsy.umd.edu) */ #include #include #include #include #include #include #include #include /* * Morsetab[] contains the `visual form' rendition of each known * character. All other characters act as word separators, hence * there is no need for an entry for space. * * The encode() function puts a pointer to the valid codes in the * table codetab[]; the invalid ones remain NULL. The code translation * table is 256 entries, and the initialisation of the array is * portable to EBCDIC (among others). * * N.B.: all of the code values in morsetab[] must be valid input * character codes. */ struct morse { int m_code; /* the input character (lowercase) */ char *m_rend; /* and its rendition */ } morsetab[] = { 'a', ".-", 'b', "-..", 'c', "-.-.", 'd', "-..", 'e', ".", 'f', "..-.", 'g', "--.", 'h', "....", 'i', "..", 'j', ".---", 'k', "-.-", 'l', ".-..", 'm', "--", 'n', "-.", 'o', "---", 'p', ".--.", 'q', "--.-", 'r', ".-.", 's', "...", 't', "-", 'u', "..-", 'v', "...-", 'w', ".--", 'x', "-..-", 'y', "-.--", 'z', "--..", '0', "-----", '1', ".----", '2', "..---", '3', "...--", '4', "....-", '5', ".....", '6', "-....", '7', "--...", '8', "---..", '9', "----.", ',', "--..--", '.', ".-.-.-", -1, NULL /* end marker */ }; char *codetab[256]; /* convert X to milliseconds (in scale factors) */ #define MS(x) ((x) * 1000) char *progname; long scale = MS(30); int keyboard; int bell_on = KBD_CMD_BELL; int bell_off = KBD_CMD_NOBELL; #define FEEP() (void) ioctl(keyboard, KIOCCMD, (char *) &bell_on) #define UNFEEP() (void) ioctl(keyboard, KIOCCMD, (char *) &bell_off) /* * Pause for number counts. Number must not be `large'. */ unit_pause(number) int number; { struct timeval tv; #define USEC 1000000 /* microseconds per second */ /* this value may be >= 1e6 */ tv.tv_usec = number * scale; tv.tv_sec = tv.tv_usec / USEC; tv.tv_usec -= tv.tv_sec * USEC; (void) select(0, (int *)0, (int *)0, (int *)0, &tv); } /* * Do a dit (if it) or dah (if not). */ d(it) int it; { FEEP(); unit_pause(it ? 1 : 3); UNFEEP(); unit_pause(1); } /* * Build the input character translation table. */ encode() { register struct morse *p; register int i; for (p = morsetab; p->m_rend != NULL; p++) { i = p->m_code; if (codetab[i] != NULL) goto bug; codetab[i] = p->m_rend; if (islower(i)) { i = toupper(i); if (codetab[i] != NULL) { bug: (void) fprintf(stderr, "%s: panic: codetab[%d] != NULL\n", progname, i); exit(1); } codetab[i] = p->m_rend; } } } init_keyboard() { keyboard = open("/dev/kbd", O_RDWR, 0666); if (keyboard < 0) { (void) fprintf(stderr, "%s: cannot open ", progname); perror("/dev/kbd"); exit(1); } } /* * `Print' the contents of file f in morse code. */ morse(f) register FILE *f; { register int c; register char *mp; int inword = 0; while ((c = getc(f)) != EOF) { if ((mp = codetab[c]) == NULL) { if (inword) { unit_pause(5); inword = 0; } continue; } inword = 1; while ((c = *mp++) != 0) d(c == '.'); unit_pause(2); } } catch() { UNFEEP(); exit(1); } set(sig, disp) int sig, (*disp)(); { #if defined(sun) && defined(lint) /* Sun 3.0 lint library is wrong */ if (signal(sig, (void (*)()) SIG_IGN) != SIG_IGN) (void) signal(sig, (void (*)()) disp); #else if (signal(sig, SIG_IGN) != SIG_IGN) (void) signal(sig, disp); #endif } main(argc, argv) int argc; char **argv; { progname = argv[0]; set(SIGHUP, catch); set(SIGQUIT, catch); set(SIGINT, catch); set(SIGTERM, catch); if (argc >= 2) { scale = MS(atoi(argv[1])); if (scale < MS(1)) { (void) fprintf(stderr, "%s: can't go that fast\n", progname); exit(1); } } init_keyboard(); encode(); morse(stdin); exit(0); } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris