/* setkey -- set Kaypro function keys from keyboard */ /* copyright 1984 Michael M Rubenstein */ /* syntax: */ /* setkey */ /* If no file type is given, .KEY is assumed */ /* the file contains lines of the following form */ /* */ /* where is "0" - "9", ".", ",", "-", "e" (enter), "u" (up), */ /* "d" (down), "l" (left), or "r" (right) */ /* and is any combination of quoted strings, circumflex */ /* character (e.g. ^m for carriage return) or hexadecimal values */ /* examples: */ /* 1 "tst"^m (tst ) */ /* u "t" ^m ^j (t ) */ /* u "t" 0d 0a (same as previous) */ #include #include #define NKEYS 18 struct jump { char j_jp; char *j_addr; }; struct bios { struct jump b_jump[16]; char b_ioconfig; char b_wrtsafe; char b_vtab[NKEYS]; char b_mbaud, pbaud; char b_sndoff; }; struct sndtab { char s_entry[4]; }; static unsigned lineno = 1; extern struct jump boot_; extern FCB dfcb_; extern char dbuff_[]; extern char *cindex(); main() { struct FILE infile; static int keyind; static int quote; static int c, d; static char *p; static char work[4]; static int i; static char *v_vtab; static struct sndtab *v_sndtab; char w_vtab[NKEYS]; struct sndtab w_sndtab[NKEYS]; static char keynames[] = "udlr0123456789-,e.", keyvalues[] = "\013\012\008\0140123456789-,\015."; if (dfcb_.name1.fname[0] == ' ' || dfcb_.name1.fname[0] == '/') help(); /* set up file name */ if (dfcb_.name1.ftype[0] == ' ') strncpy(dfcb_.name1.ftype, "KEY", 3); strncpy(&infile, &dfcb_, sizeof(FCB)); if (open(&infile) == 0xff) error("setkey: Cannot open input file"); /* set up for getc */ infile.f_buff = dbuff_; infile.f_bufl = infile.f_bufc = 128; /* copy current key settings to work area */ v_vtab = boot_.j_addr->b_vtab; v_sndtab = (struct sndtab *) (v_vtab + (boot_.j_addr->b_sndoff & 0xff)); strncpy(w_vtab, v_vtab, NKEYS); strncpy(w_sndtab, v_sndtab, NKEYS * sizeof(struct sndtab)); do { while (isspace(c = getc(&infile))) if (c == '\n') ++lineno; if (c == EOF || c == CPMEOF) break; if ((p = cindex(keynames, tolower(c))) == NULL) { ps("setkey: Invalid key name on line "); pn(lineno); ps("\r\n"); exit(1); } keyind = p - keynames; /* get the key values from file */ i = 0; quote = FALSE; c = getc(&infile); while (c != '\r' && c != '\n' && c != EOF && c != CPMEOF) { if (quote) { if (c == '"' && (c = getc(&infile)) != '"') { quote = FALSE; continue; } } else switch (c) { case '"': quote = TRUE; c = getc(&infile); continue; case '^': if ((c = getc(&infile)) == EOF || c == CPMEOF || isspace(c)) { ps("setkey: Invalid use of ^ in line "); pn(lineno); ps("\r\n"); exit(1); } c &= 0x1f; break; case ' ': case '\t': c = getc(&infile); continue; default: c = 16 * hexdig(c) + hexdig(getc(&infile)); } if (i >= 4) { ps("setkey: Value too long in line "); pn(lineno); ps("\r\n"); exit(1); } work[i++] = c; c = getc(&infile); } if (i == 0) w_vtab[keyind] = keyvalues[keyind]; /* default */ else if (i == 1) w_vtab[keyind] = work[0]; /* one character value */ else { w_vtab[keyind] = '\0'; /* multiple character value */ while (i < 3) work[i++] = '\0'; strncpy(&w_sndtab[keyind], work, 4); } if (c == '\n') ++lineno; } while (c != EOF && c != CPMEOF); close(&infile); /* move the new key values into BIOS */ strncpy(v_vtab, w_vtab, NKEYS); strncpy(v_sndtab, w_sndtab, NKEYS * sizeof(struct sndtab)); } /* convert ascii char to hex */ hexdig(c) int c; { static char *p; static char hexd[] = "0123456789abcdef"; if ((p = cindex(hexd, c)) == NULL) { ps("setkey: Invalid hex digit in line "); pn(lineno); ps("\r\n"); exit(1); } return p - hexd; } /* print a number on console */ pn(u) unsigned u; { if (u > 10) pn(u / 10); conout(u % 10 + '0'); } /* show how to use */ help() { static char *msg[] = { "syntax: setkey \r\n\r\n", "If no file type is given, .KEY is assumed.\r\n\r\n", "The file contains lines of the form\r\n\r\n", " \r\n\r\n", "where is \"0\" - \"9\", \".\", \",\", \"-\", \"e\" (enter),\r\n", "\"u\" (up), \"d\" (down), \"l\" (left), or \"r\" (right)\r\n", "and is any combination of quoted strings, circumflex\r\n", "character (e.g. ^m for carriage return) or hexadecimal values.\r\n\r\n", "Examples:\r\n\r\n", "1 \"tst\"^m (tst )\r\n", "u \"t\" ^m ^j (t )\r\n", "u \"t\" 0d 0a (same as previous)\r\n\r\n", "Maximum 4 characters per key.\r\n", NULL }; static char **p; for (p = msg; *p != NULL; ++p) ps(*p); exit(0); }