/* * keybrd.ti: * functions, maps and interrupt handlers for TI Pro keyboards * * Copyright (c) 1989 University of Toronto. All rights reserved. * Anyone may use or copy this software, except that it may not be * sold for profit, that this copyright notice remain intact, and that * credit is given where it is due. The University of Toronto and the * author make no warranty and accept no liability for this software. */ static char rcsid[] = "$Header: keybrd.ti,v 1.6 89/02/23 20:39:31 pkern Exp $"; #include #include "cterm.h" #include "ti.h" #define word unsigned int uchar kqueued=0, keyboom=0; static union REGS r; static uchar f_map=0, f_vec=0, kb_mode=0; extern int (*xmit)(); extern uchar flowctl, local, xoff; /* check for queued keys */ kbdhit() { #ifdef KBDQUE return (kqueued); #else r.h.ah = 1; int86(KBD_INT, &r, &r); return (!(r.x.flags & Zflag)); /* ie. ! Z-flag */ #endif } /* flush keyboard type-ahead queue */ kbflush() { r.h.ah = 3; int86(KBD_INT, &r, &r); kqueued = 0; } /* toggle keyboard autorepeat */ kbautorep(sw) int sw; /* switch : 1 = on, 0 = off */ { r.h.ah = 4; r.h.al = (sw) ? 1 : 2; int86(KBD_INT, &r, &r); } /* get keyboard word */ word kbdget() { r.h.ah = 2; int86(KBD_INT, &r, &r); kb_mode = r.h.al; r.h.ah = 0; int86(KBD_INT, &r, &r); kqueued--; return((word) r.x.ax); } /* return a keypadv[] offset | 8-bit alternative */ kbdfn(kn) word kn; { word fn; extern word keymap[], alt8[]; kn = kn >> 8; fn = alt8[kn] & 0x7f; if (fn) { if (kb_mode & 0x01) /* CTRL key */ fn = (alt8[kn] >> 8) & 0x3f; else if (kb_mode & 0x04) /* SHIFT key */ fn = alt8[kn] >> 8; kb_mode = 0; fn |= 0x80; } return((fn << 8) | keymap[kn]); } /* * keypad map (aN = alt N, cN = ctrl N, sN = shift N) * +-----+-----+-----+-----+ * | PF1 | PF2 | PF3 | PF4 | cursor code offsets: * | aF1 | aF2 | aF3 | aF4 | UP - 0 * +-----+-----+-----+-----+ DOWN - 1 * | 7 | 8 | 9 | - | RIGHT - 2 * | a1 | a2 | a3 | a4 | LEFT - 3 * | F5 | F6 | F7 | F8 | * +-----+-----+-----+-----+ * | 4 | 5 | 6 | , | keypad code string offsets: * | aQ | aW | aE | aR | 8 - "0" 10 - "8" 18 - "F3" * | cF5 | cF6 | cF7 | cF8 | 9 - "1" 11 - "9" 19 - "F4" * +-----+-----+-----+-----+ A - "2" 12 - "-" 1A - "\200" * | 1 | 2 | 3 | aF | B - "3" 13 - "," 1B - "\b" * | aA | aS | aD | aF8 | C - "4" 14 - "." 1C - "\003" * | aF5 | aF6 | aF7 | | D - "5" 15 - "ENTER" 1D - "\r\n" * +-----+-----+-----+Enter| E - "6" 16 - "F1" 1E *-> ansback * | 0 | . | | F - "7" 17 - "F2" 1F - "" (empty) * | aZ aX | aC | aV | * | sF5 sF6 | sF7 | sF8 | * +-----------+-----+-----+ */ /* * keymap: * keypadv[] offsets for all (ie. 90H) extended function codes */ static word keymap[0x90] = { /* 0x0_ */ 0x1f, 0x1f, 0x1f, 0x1a, 0x1f, 0x1f, 0x1f, 0x1f, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x1f, 0x1f, /* 0x1_ */ 0x0c, 0x0d, 0x0e, 0x13, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x09, 0x0a, /* 0x2_ */ 0x0b, 0x15, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x08, 0x08, 0x14, 0x15, /* 0x3_ */ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1b, 0x0f, /* 0x4_ */ 0x10, 0x11, 0x12, 0x00, 0x01, 0x03, 0x02, 0x1f, 0x00, 0x00, 0x1f, 0x03, 0x03, 0x02, 0x02, 0x1f, /* 0x5_ */ 0x01, 0x01, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x08, 0x08, 0x14, 0x15, 0x00, 0x01, 0x1f, 0x1f, /* 0x6_ */ 0x1f, 0x1f, 0x0c, 0x0d, 0x0e, 0x13, 0x00, 0x01, 0x16, 0x17, 0x18, 0x19, 0x09, 0x0a, 0x0b, 0x15, /* 0x7_ */ 0x00, 0x01, 0x1f, 0x03, 0x02, 0x1f, 0x01, 0x1f, 0x0f, 0x10, 0x11, 0x12, 0x1f, 0x1f, 0x1f, 0x1f, /* 0x8_ */ 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x1f, 0x1f, 0x1f, 0x00, 0x01, 0x02, 0x03, 0x16, 0x17, 0x18, 0x19 }; /* * alt8: * keymap[] ALTernatives with 8th bit set. * (Turbo C direct storage: 'lsb msb') */ static word alt8[0x90] = { /* 0x0_ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1_ */ 'qQ', 'wW', 'eE', 'rR', 'tT', 'yY', 'uU', 'iI', 'oO', 'pP', 0, 0, 0, 0, 'aA', 'sS', /* 0x2_ */ 'dD', 'fF', 'gG', 'hH', 'jJ', 'kK', 'lL', 0, 0, 0, 0, 0, 'zZ', 'xX', 'cC', 'vV', /* 0x3_ */ 'bB', 'nN', 'mM', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4_ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5_ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6_ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7_ */ 0, 0, 0, 0, 0, 0, 0, 0, '1!', '2@', '3#', '4$', '5%', '6^', '7&', '8*', /* 0x8_ */ '9(', '0)', '-_', '=+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* k_brk -- intercept SHIFT BRK/PAUS interrupt */ void interrupt k_brk(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags) word bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags; { flags |= Cflag; /* ie. don't queue it */ keyboom++; } /* k_paus -- intercept PAUS key interrupt */ void interrupt k_paus(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags) word bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags; { if (flowctl && !local) if (xoff) { xmit(XON); xoff = 0; } else { xmit(XOFF); xoff++; } flags |= Cflag; /* don't queue it */ } /* k_que -- take note of new keystroke in buffer */ void interrupt k_que() { kqueued++; /* outport(0,7); /* simple but pathetic-sounding keyclick */ } /* * remap: table of scan codes for remapping TI Pro keypad * - new scan values for scan codes 27 -> 44 * (first 4 bits = ctrl/alt/shift bit choice * last 8 bits = the new scan code) * 0 = scan code unused (ie. it should never occur) */ static unsigned int remap[22] = { 0x217, 0x218, 0x219, 0x21a, 0x201, 0, 0x401, 0x204, 0x101, 0x102, 0x003, 0x004, 0x202, 0, 0, 0, 0x001, 0x002, 0x103, 0x104, 0x203, 0x403 }; /* k_map -- remap keypad scan codes */ void interrupt k_map(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags) word bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags; { uchar al, ah; al = ax & 0xff; ah = (ax >> 11); if (al < 45 && al > 22) ax = (ah << 11) + remap[al-23]; else if ((ax & 0x300) && al == 81) /* CTRL/ALT-SPACE */ ax = (ax & 0xff00) | 10; /* CTRL/ALT-2@ */ } /* * o_brk, o_paus, o_que, o_map: * temp storage for old interrupt vectors */ void interrupt (*o_brk)(); void interrupt (*o_paus)(); void interrupt (*o_que)(); void interrupt (*o_map)(); init_kbd() { if (f_vec) return(0); kbflush(); /* remember old intr vector(s) */ o_brk = getvect(KEYBRK); o_paus = getvect(KEYPAUS); o_que = getvect(KBDQUE); o_map = getvect(KBDMAP); /* install new one(s) */ disable(); setvect(KEYBRK, k_brk); setvect(KEYPAUS, k_paus); setvect(KBDQUE, k_que); setvect(KBDMAP, k_map); enable(); f_vec = 1; /* vector(s) installed */ /* some important key mappings */ keymap[K_SETUP >> 8] = 0x80; /* flag the SETUP key */ keymap[(K_SETUP >> 8)+1] = 0x80; /* ditto on F2 */ keymap[K_shBRK >> 8] = 0x40; /* shiftBrk - hang up */ keymap[K_NUL >> 8] = 0x41; /* ctrl-2@ - send NUL */ keymap[K_BREAK >> 8] = 0x42; /* BREAK - send BREAK */ keymap[K_BKSP >> 8] = 0x1b; /* backsp keypadv[] position */ keymap[K_cBRK >> 8] = 0x1e; /* ctrlBrk keypadv[] position */ keyboom = 0; } reset_kbd() { if (!f_vec) return; /* no vectors to reset, yet */ kbflush(); /* restore old intr vector(s) */ disable(); setvect(KEYBRK, o_brk); setvect(KEYPAUS, o_paus); setvect(KBDQUE, o_que); setvect(KBDMAP, o_map); enable(); f_vec = 0; /* vector(s) reset */ } /* switch newline mode */ nlmod(sw) uchar sw; { /* shift ENTER offset, if needed */ keymap[0x21] = keymap[0x2f] = ((sw) ? 0x1d : 0x15); }