home *** CD-ROM | disk | FTP | other *** search
- /*
- * Keyboard buffer stuffer
- *
- * This program copies characters from the command line into the PC
- * keyboard buffer, adding correct "scan code" extensions as it does so.
- * Numerous "escape sequences" are recognized to provide for stuffing
- * non-ASCII characters produced by the various non-alphanumeric keys on
- * the PC keyboard.
- *
- * The default BIOS keyboard buffer holds only 15 entries, however this
- * program uses the START/END pointers from BIOS, so it should work
- * correctly with the various utilities that enlarge the buffer.
- *
- * Copyright 1994 Dave Dunfield
- * All rights reserved.
- *
- * Permission granted for personal (non-commerical) use only.
- *
- * Compile command: CC stuff -fop
- */
- #include <stdio.h>
-
- #define BIOS_SEG 0x40 /* BIOS data segment */
- #define BUFFER_START 0x80 /* Pointer to start of keyboard buffer */
- #define BUFFER_END 0x82 /* Pointer to end of keyboard buffer */
- #define BUFFER_TAIL 0x1A /* Pointer to next character to receive */
- #define BUFFER_HEAD 0x1C /* Pointer to first available spot */
-
- /* Prefix codes for "ALPHA" keys */
- char alpha_prefix[] = {
- 0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24,
- 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1F, 0x14,
- 0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C };
-
- /* Codes for misc. ASCII keys */
- unsigned ascii_prefix[] = {
- 0x3920, 0x0231, 0x0332, 0x0433, 0x0534, 0x0635, 0x0736, 0x0837,
- 0x0938, 0x0A39, 0x0B30, 0x0C2D, 0x0D3D, 0x2B5C, 0x297E, 0x0221,
- 0x0340, 0x0423, 0x0524, 0x0625, 0x0826, 0x092A, 0x0A28, 0x0B29,
- 0x0C5F, 0x0D2B, 0x2B7C, 0x1A5B, 0x1B5D, 0x273B, 0x2827, 0x332C,
- 0x342E, 0x352F, 0x1A7B, 0x1B7D, 0x273A, 0x2822, 0x333C, 0x343E,
- 0x353F, 0x2960, 0 };
-
- /* Table of special keys & codes */
- char misc_key[] = {
- '=', '!', '/', '\\', /* Enter, Backspace, Tab, Backtab */
- '@','#','$', '+', '-', /* Escape, Ins, Del, keypad+, keypad- */
- '<', '>', '{', '}', /* Right, Left, Up, Down */
- '(', ')', '[', ']', /* Home, End, PgUp, PgDn */
- '^' }; /* Single '^' */
- unsigned misc_code[] = {
- 0x1C0D, 0x0E08, 0x0F09, 0x0F00,
- 0x011B, 0x5200, 0x5300, 0x4E2b, 0x4A2D,
- 0x4B00, 0x4D00, 0x4800, 0x5000,
- 0x4700, 0x4F00, 0x4900, 0x5100,
- 0x075E };
-
- /* Help text */
- char *help[] = {
- "\nKeyboard buffer stuffer - by Dave Dunfield\n",
- "\nUse: stuff <characters>\n\n",
- "^ indicates special characters:\n\n",
- " ^A-Z Ctrl ^*A-Z Alt ^.0-9 Fn ^,0-9 SFn ^:0-9 CFn ^;0-9 AFn\n\n",
- " ^^ (^) ^= Enter ^@ Esc ^! Backsp ^/ Tab ^\\ Backtab\n",
- " ^< Right ^> Left ^{ Up ^} Down ^[ PgUp ^] PgDn\n",
- " ^( Home ^) End ^+ Kpad+ ^- Kpad- ^# Ins ^$ Del\n",
- " ^? Clear keyboard buffer\n",
- 0 };
-
- /*
- * Main program - Stuff arguments into the keyboard buffer
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i;
-
- if(argc < 2) { /* No data to stuff, display help */
- for(i=0; help[i]; ++i)
- fputs(help[i], stdout);
- return; }
-
- i = 1;
- while(i < argc) { /* Stuff all arguments */
- stuff_string(argv[i]);
- if(++i < argc)
- stuff_string(" "); }
- }
-
- /*
- * Stuff a string into the keyboard buffer
- */
- stuff_string(ptr)
- char *ptr;
- {
- int i, j;
- char c, prefix;
-
- while(c = *ptr++) {
- if(isalpha(c)) /* Normal "ALPHA" character */
- prefix = alpha_prefix[(c & 0x1F) - 1];
- else if(c == '^') {
- if(isalpha(c = *ptr++)) /* ALPHA control code */
- prefix = alpha_prefix[(c &= 0x1F) - 1];
- else switch(c) {
- default:
- for(i=0; i < sizeof(misc_key); ++i)
- if(c == misc_key[i]) {
- stuff_key(misc_code[i]);
- goto done; }
- clear_buffer();
- abort("Unknown ^!\n");
- case '.' : /* Normal function key */
- prefix = 0x3B;
- goto dofunc;
- case ',' : /* Shift function key */
- prefix = 0x54;
- goto dofunc;
- case ':' : /* CTRL function key */
- prefix = 0x5E;
- goto dofunc;
- case ';' : /* ALT function key */
- prefix = 0x68;
- dofunc:
- if(isdigit(c = *ptr++)) {
- prefix += (c == '0') ? 9 : (c - '1');
- c = 0;
- break; }
- clear_buffer();
- abort("Fkey must be 0-9\n");
- case '?' : /* Clear buffer */
- clear_buffer();
- continue;
- case '*' : /* ALT-ALPHA character */
- prefix = alpha_prefix[(*ptr++ & 0x1F) - 1];
- c = 0; } }
- else {
- for(i=0; j = ascii_prefix[i]; ++i)
- if((j & 255) == c) {
- stuff_key(j);
- goto done; }
- clear_buffer();
- abort("Unknown character\n"); }
- stuff_key((prefix << 8) | c);
- done: }
- }
-
- /*
- * Stuff a single keystroke into the keyboard buffer
- */
- stuff_key(key)
- unsigned key;
- {
- unsigned head;
-
- disable();
- pokew(BIOS_SEG, head = peekw(BIOS_SEG, BUFFER_HEAD), key);
-
- if((head += 2) >= peekw(BIOS_SEG, BUFFER_END))
- head = peekw(BIOS_SEG, BUFFER_START);
-
- if(head == peekw(BIOS_SEG, BUFFER_TAIL)) {
- clear_buffer();
- abort("Key buffer FULL!\n"); }
-
- if(head != peekw(BIOS_SEG, BUFFER_TAIL))
- pokew(BIOS_SEG, BUFFER_HEAD, head);
- enable();
- }
-
- /*
- * Clear the keyboard buffer
- */
- clear_buffer()
- {
- disable();
- pokew(BIOS_SEG, BUFFER_HEAD, peekw(BIOS_SEG, BUFFER_TAIL));
- enable();
- }
-