/* * keybrd.pc: * functions, maps and interrupt handlers for IBM PC 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: /homes/ugw/pkern/src/cterm/RCS/keybrd.pc,v 1.6 89/10/04 19:49:57 pkern Exp $"; #include #include "cterm.h" #include "pc.h" #define word unsigned int uchar keyboom=0; static union REGS r; static uchar f_map=0, f_vec=0, kb_mode=0; extern uchar flowctl, local, xoff; #ifdef KB_INT #define INTA00 0x20 #define KB_DATA 0x60 #define KB_CTL 0x61 #define EOI 0x20 static word keybuf[256]; static uchar kbin=0, kbout=0, autorep; void interrupt (*o_int)(); /* #include "kbrd_gen.h" /* */ #include "kbrd_101.h" /* */ /* setup screen function key reminders */ char funky1[] = FUNKY1; char funky2[] = FUNKY2; kbdhit() { return(kbin != kbout); } void kbflush() { kbin = kbout; } void kbautorep(sw) int sw; { autorep = sw; } word kbdget() { if (f_vec) return(keybuf[kbout++]); /* else use regular bios */ r.h.ah = 0; int86(KBD_INT, &r, &r); if (r.x.ax & 0xff) r.x.ax &= 0xff; return((word) r.x.ax); } #else /* KB_INT */ /* check for queued keys */ kbdhit() { r.h.ah = 1; int86(KBD_INT, &r, &r); return (!(r.x.flags & Zflag)); /* ie. ! Z-flag */ } /* flush keyboard type-ahead queue */ void kbflush() { r.h.ah = 3; int86(KBD_INT, &r, &r); } /* toggle keyboard autorepeat */ void 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); if (r.x.ax & 0xff) r.x.ax &= 0xff; return((word) r.x.ax); } #endif /* KB_INT */ /* 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 & 0x04) /* Ctrl key */ fn = (alt8[kn] >> 8) & 0x3f; else if (kb_mode & 0x03) /* Shift keys */ fn = alt8[kn] >> 8; fn |= 0x80; } return((fn << 8) | keymap[kn]); } /* * keypad map (aN == alt 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 * +-----+-----+-----+-----+ * | 4 | 5 | 6 | , | keypad code string offsets: * | aQ | aW | aE | aR | 8 - "0" 10 - "8" 18 - "F3" * +-----+-----+-----+-----+ 9 - "1" 11 - "9" 19 - "F4" * | 1 | 2 | 3 | | A - "2" 12 - "-" 1A - "\200" * | aA | aS | aD |Enter| B - "3" 13 - "," 1B - "\b" * +-----+-----+-----+ | C - "4" 14 - "." 1C - "\003" * | 0 | . | aF | D - "5" 15 - "ENTER" 1D - "\r\n" * | aZ aX | aC | aV | E - "6" 16 - "F1" 1E *-> ansback * +-----------+-----+-----+ F - "7" 17 - "F2" 1F - "" (empty) */ /* * keymap: * keypadv[] offsets for all extended function codes */ static word keymap[0x90] = { /* 0x0_ */ 0x1f, 0x1f, 0x1f, 0x1a, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x03, /* 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, 0x1f, /* 0x4_ */ 0x1f, 0x00, 0x01, 0x03, 0x02, 0x1f, 0x1f, 0x0f, 0x10, 0x11, 0x13, 0x0c, 0x0d, 0x0e, 0x15, 0x09, /* 0x5_ */ 0x0a, 0x0b, 0x08, 0x14, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x01, 0x03, 0x02, 0x1f, 0x1f, /* 0x6_ */ 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x01, 0x03, 0x02, 0x16, 0x17, 0x18, 0x19, 0x1f, 0x1f, 0x00, 0x01, /* 0x7_ */ 0x03, 0x02, 0x12, 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[] ALTernative 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 Ctrl-Break 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; { send_brk(); flags |= Cflag; /* ie. don't queue it */ keyboom++; } /* * o_brk : temp storage for old interrupt vectors */ void interrupt (*o_brk)(); void init_kbd() { if (f_vec) return; kbflush(); /* remember old intr vector(s) */ o_brk = getvect(KEYBRK); #ifdef KB_INT o_int = getvect(KB_INT); #endif /* install new one(s) */ disable(); /* */ setvect(KEYBRK, k_brk); #ifdef KB_INT setvect(KB_INT, k_int); #endif enable(); /* */ f_vec = 1; /* vector(s) installed */ /* some important key mappings */ keymap[K_SETUP >> 8] = 0x80; /* flag the SETUP key */ #ifndef MVESC keymap[(K_SETUP >> 8)+1] = 0x80; /* ditto on F2 */ #endif 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; } void reset_kbd() { if (!f_vec) return; /* no vectors to reset, yet */ kbflush(); /* restore old intr vector(s) */ disable(); setvect(KEYBRK, o_brk); #ifdef KB_INT setvect(KB_INT, o_int); #endif enable(); f_vec = 0; /* vector(s) reset */ } /* switch newline mode */ void nlmod(sw) uchar sw; { /* shift ENTER offset, if needed */ keymap[0x21] = keymap[0x2f] = ((sw) ? 0x1d : 0x15); }