In article <1...@ames.UUCP> wat...@ames.UUCP (John S. Watson) writes:
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: wat...@ames.arpa
* UUCP: ...!ames!watson
*
* This version by:
* Chris Torek 4/29/87
* University of Maryland
* Department of Computer Science
* (ch...@mimsy.umd.edu)
*/
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sundev/kbd.h>
#include <sundev/kbio.h>
/*
* 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 */
'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 */
/* 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;
}
}
{
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);
}
{
UNFEEP();
exit(1);
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
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: ch...@mimsy.umd.edu Path: seismo!mimsy!chris