home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / SRC26_2.ZIP / SRC / KEY98.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-05  |  32.1 KB  |  1,334 lines

  1. /*
  2.  * key98.c: hterm keyboard decoder for NEC-PC9801
  3.  *                 and
  4.  *            TSR program 'hkey' which provides hterm like keyboard environment
  5.  * 
  6.  *
  7.  * Author: HIRANO Satoshi
  8.  * (C) 1989  Halca Computer Science Laboratory TM
  9.  *           University of Tokyo
  10.  *
  11.  * NOTE:
  12.  *    Quoting is used to pass HTERM CONTROL KEY to hterm.
  13.  *        See putBuf()
  14.  *
  15.  *  'hkey' program should be compiled without stack checking
  16.  *    and be linked with crt.obj.
  17.  *        masm -Mx crt.asm;
  18.  *        cl -DPC98 -DTSR -Ox -c key98.c
  19.  *        link crt+key98,hkey;
  20.  *
  21.  * 2.2 89/05/16 Halca.Hirano remove all of kana char in source code
  22.  *    ---- V2.2 distribution -----
  23.  * 2.3 89/06/15 Halca.Hirano
  24.  *     1  remove #else
  25.  * 2.4 89/06/20 Halca.Hirano support front end processor
  26.  *     change Function-Key send code
  27.  * 2.5 89/06/26 Halca.Hirano fix FEP state bug.
  28.  *    restore shift/ctrl status on exit to BIOS
  29.  *    add send break
  30.  * 2.6 89/06/29 Halca.Hirano change the way to get a key entirely
  31.  *    old: use own interrupt handler, and pass key to hterm directly
  32.  *    new: get key from BIOS
  33.  * 2.7 89/07/04 Halca.HIrano change the way to get a key entirely again!!
  34.  *    old: get key from BIOS
  35.  *    BUT this can not be used with VJE, NEC-AI....
  36.  *    new: use original key interrupt handler.
  37.  *        Thank you Shikita@titec & Yocchan@kao (UEC ultra-key).
  38.  * 2.8 89/07/18 Halca.Hirano add cursor key, keypad (normal/application mode)
  39.  *    add editPFKey function
  40.  * 2.9 89/07/20 Halca.Hirano add shift/ctrl lock
  41.  * 2.10 89/07/26 Halca.Hirano pass kana if fepMode
  42.  *    add history Editor, add fep invokation key sequence limitation
  43.  *    ----- V2.3.-1 distribution ----
  44.  * 2.11 89/08/03 Halca.Hirano add DOS mode (true BIOS emulator)
  45.  * 2.12 89/08/05 Halca.Hirano add mouse functions
  46.  * 2.13 89/09/14 Halca.Hirano add PC98XA by Mr. blackROSe
  47.  *    fix DOS mode space key bug (We could't generate SPACE key.) OH MY GOD!!
  48.  *    ---- V2.4.0 distribution ----
  49.  * 2.14 89/09/29 Halca.Hirano 
  50.  *    add short wait between outp() and inp(). This is needed for PC98XA.
  51.  * 2.15 89/10/14 Halca.Hirano
  52.  *    add PC98XA short/long break
  53.  *    add PC98XA dos mode ten key
  54.  * 2.16 89/11/28 naka_j@huie.hokudai.ac.jp
  55.  *    old MATUTAKE(FEP) eats DEL, then add code change.
  56.  * 2.17 89/11/29 Halca.Hirano
  57.  *    fix PC98XA nop bug (increase nullFunction calling)
  58.  *    fix set-up mode tenkey bug
  59.  *    fix normal keypad mode HOME, HELP key bug
  60.  * 2.18 89/12/03 Halca.Hirano
  61.  *    add BS key watcher
  62.  * 2.19 89/12/08 Halca.Hirano
  63.  *    re-initialize keyboard bios at exit (but I've abandoned!)
  64.  * 2.20 90/01/16 Halca.Hirano
  65.  *    hkey TSR
  66.  *    meta-key can be used in DOS mode.
  67.  * 2.21 90/04/30 Halca.Hirano
  68.  *     write special C-startup for hkey.exe
  69.  *     old size in memory $11030 bytes + environment area
  70.  *     new size in memory $1190 bytes
  71.  *    support STOP/COPY interrupt if OS mode or TSR mode
  72.  * 2.22 90/05/27 Halca.Hirano
  73.  *    new feature!  key swapping table
  74.  *        now we can assign arbitrary key to arbitrary key.
  75.  * 2.23 90/06/21 Halca.Hirano
  76.  *    change key table size from short to u_char
  77.  *
  78.  * $Header: key98.cv  1.17  90/07/05 03:05:38  hirano  Exp $
  79.  *
  80.  */
  81.  
  82. #include <stdio.h>
  83. #include <string.h>
  84. #include <io.h>
  85. #include <stdlib.h>
  86. #include "option.h"
  87. #include "config.h"
  88. #include "hterm.h"
  89. #include "default.h"
  90. #include "hkey.h"
  91.  
  92. #ifdef TSR
  93. #undef BS_WATCHER
  94. #undef MOUSE
  95. #else
  96. #include "global.h"
  97. #endif /* TSR */
  98.  
  99. /*
  100.  * key table magics 
  101.  */
  102. #define BS_SCAN_CODE    0x0e    /* BS key scan code        */
  103. #define QUOTE_CHAR    'H'            /* keyHander->hterm quote    */
  104.  
  105. #include "keytab98.h"            /* key board conversion table    */
  106.  
  107. /*
  108.  * shift state of BIOS work KB_SHFT
  109.  */
  110. #define S_SHIFT(x) ((x) & 0x01)
  111. #define S_CAPS(x)  ((x) & 0x02)
  112. #define S_KANA(x)  ((x) & 0x04)
  113. #define S_GRAPH(x) ((x) & 0x08)
  114. #define S_CTRL(x)  ((x) & 0x10)
  115. #define S_NFER(x)  ((x) & 0x20)
  116. #define S_XFER(x)  ((x) & 0x02)
  117.  
  118. struct _BIOS_WORK {
  119.     short KB_BUF[17];        /* not 16        */
  120.     short KB_HEAD;
  121.     short KB_TAIL;
  122.     short KB_COUNT;
  123.     char  KB_STS[16];
  124.     char  KB_SHFT;
  125. };
  126.  
  127. /*
  128.  * static storage should be initialized for TSR
  129.  */
  130. int meta = 0;
  131. int fepMode = 0;                /* 1=FEP mode        */
  132. int ctrlLocked = 0;                /* CTRL is locked    */
  133. int shiftLocked = 0;            /* SHIFT is locked    */
  134.  
  135. #ifdef TSR
  136. int clickFlag = 0;
  137. int applKeypad = 0;
  138. int applCursor = 0;
  139. int asckey = 0;
  140. int bsDel = 0;
  141. int shiftLock = 0;
  142. int fepInvoke = 0;
  143. int mouseSpeed = 0;
  144. int bsKeyCount = 0;
  145. int bsKeyRatio = 0;
  146. int keyCount = 0;
  147. int ctrlSpace = 0;
  148. void keyInit();
  149. int mode = 0;
  150. void (interrupt FAR *getVect(unsigned))();
  151. #else
  152. int ctrlSpace;
  153. #endif /* TSR */
  154.  
  155. #ifdef PC98XA
  156. short    XAspecial[MAX_FUNKEY] = {0,};
  157. int     XAcount = 0;
  158. int     XAsplpos = 0;
  159.  
  160. #define KEY_CODE_PF11    0x52
  161. #define    KEY_CODE_PF15    0x56
  162. #endif /* PC98XA */
  163.  
  164. void (interrupt FAR *keyVector)() = 0;        /* original key handler    */
  165.  
  166. u_char *ctrltbl = 0;
  167. u_char *noshiftbl = 0;
  168. u_char *shiftbl = 0;
  169. u_char *kanatbl = 0;
  170. u_char *shkanatbl = 0;
  171. #ifndef TSR
  172. static u_char keiUnConv[76] = {
  173.     0x9f, 0xaa, 0xa0, 0xab, 0x9f, 0xaa, 0xa0, 0xab,
  174.     0x9f, 0xaa, 0xa0, 0xab, 0xa1, 0xa1, 0xa1, 0xac,
  175.     0xa2, 0xa2, 0xa2, 0xad, 0xa4, 0xa4, 0xa4, 0xaf,
  176.     0xa3, 0xa3, 0xa3, 0xae, 0xa5, 0xba, 0xa5, 0xa5,
  177.     0xb5, 0xa5, 0xa5, 0xb0, 0xa7, 0xbc, 0xa7, 0xa7,
  178.     0xb7, 0xa7, 0xa7, 0xb2, 0xa6, 0xa6, 0xa6, 0xb6,
  179.     0xbb, 0xa6, 0xa6, 0xb1, 0xa8, 0xa8, 0xa8, 0xb8,
  180.     0xbd, 0xa8, 0xa8, 0xb3, 0xa9, 0xa9, 0xa9, 0xb9,
  181.     0xa9, 0xa9, 0xbe, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
  182.     0xa9, 0xa9, 0xa9, 0xb4
  183. };
  184. #endif /* TSR */
  185.  
  186. static void INTERRUPT FAR keyHandler();
  187. static  int keyCtrl(unsigned char keyCode);
  188. void putFunkey(unsigned char key,unsigned char inCode,unsigned char (*keyTable)[MAX_FUNKEY]);
  189. void putBuf(short c,int recFlag);
  190. void mouseSetHandler(int onOff);
  191. void mouseOnOff(int onOff);
  192. void mouseSetPosition(int x,int y);
  193. void far mouseEvent(int event,int x,int y);
  194. #ifdef TSR
  195. void nullFunction(void);
  196. void keyReInit(void);
  197. void keySetup(void);
  198. void keyEnd(void);
  199. void keyMode(void);
  200. void setBSDel(int);
  201. void mouseEnd(void);
  202. void mouseInit(void);
  203. #endif
  204.  
  205. #ifdef TSR
  206. char endAddress = 0;            /* break off mark        */
  207. /*
  208.  * data below are detached at exit
  209.  */
  210. char hkeyVersion[] = HKEY_MARK;
  211. char TSRMsg[] = "\
  212.  (C) 1990 Halca Computer Science Laboratory (HIRANO)\r\n$";
  213.  
  214. char syntax1[] = "\
  215. : hterm like keyboard environment TSR for PC9801\r\n\
  216. syntax: hkey [-options]\r\n\
  217. options and special keys: (C-S-x = CTRL-SHIFT-x)\r\n\
  218. \t-a (C-S-1) ascii keyboard\r\n\
  219. \t-p (C-S-2) pc9801 keyboard (default)\r\n\
  220. \t-c (C-S-3) key click\r\n\
  221. \t-s (C-S-4) silent; no key click (default)\r\n\
  222. \t-C (C-S-5) CTRL-XFER FEP (default)\r\n\
  223. $";
  224. char syntax2[] = "\
  225. \t-S (C-S-6) SHIFT-XFER FEP\r\n\
  226. \t-B (C-S-7) CTRL- or SHIFT-XFER FEP\r\n\
  227. \t-N (C-S-8) NO FEP\r\n\
  228. \t-@ (C-S-9) toggle CTRL-SPACE enable/disable\r\n\
  229. \t-H (C-S-HELP) CTRL/SHIFT lock\r\n\
  230. \t   (C-S-HOME) No CTRL/SHIFT lock (default)\r\n\
  231. \t   (C-S-STOP) reset system\r\n\
  232. $";
  233. /* \tC-S-ESC terminate hkey\r\n\ */
  234.  
  235. main(argp)
  236. char FAR *argp;
  237. {
  238.     char FAR *p;
  239.     char *q;
  240.     int i;
  241.     extern int pspSeg;
  242.  
  243.     keyInit();
  244.     putMsg(hkeyVersion);
  245.     for (p = argp; *p != CR; p++) {
  246.         switch (*p) {
  247.         case ' ': case '\t': case '-': break;
  248.         case 'a':    asckey = YES; break;
  249.         case 'p':    asckey = NO; break;
  250.         case 'c':    clickFlag = YES; break;
  251.         case 's':    clickFlag = NO; break;
  252.         case 'C':    fepInvoke = FEP_CTRLXFER; break;
  253.         case 'S':    fepInvoke = FEP_SHIFTXFER; break;
  254.         case 'B':    fepInvoke = FEP_BOTHXFER; break;
  255.         case 'N':    fepInvoke = FEP_NOXFER; break;
  256.         case 'H':    shiftLock = YES; break;
  257.         case '@':    ctrlSpace = !ctrlSpace; break;
  258.         default:
  259.             putMsg(syntax1); putMsg(syntax2);
  260.             keyEnd();
  261.             _exit(1);
  262.         }
  263.     }
  264.     /*
  265.      * copy command name to parameter area in PSP
  266.      */
  267.     FP_SEG(p) = pspSeg;
  268.     FP_OFF(p) = 0x80;
  269.     *p++ = SIZE_OF_HKEY_MARK;        /* size of "hkey1.2"            */
  270.     q = hkeyVersion;                /* TSRMsg begins with "hkey1.2" */
  271.     for (i = 0; i < SIZE_OF_HKEY_MARK; i++)
  272.         *p++ = *q++;
  273.     *p = CR;
  274.     /*
  275.      * print banner
  276.      */
  277.     putMsg(TSRMsg);
  278.     mode = M_OS;
  279.     fepMode = NO;
  280.     keySetup();
  281.  
  282.     /*
  283.      * terminate but stay the program
  284.      * (in crt:__main)
  285.      */
  286. }
  287.  
  288. void click()
  289. {
  290.     int i;
  291.  
  292.     outp(PORT_C, 0x06);            /* buzzar on        */
  293.     for (i = 0; i < CLICK_BEEP; i++)
  294.         nullFunction();            /* short wait        */
  295.     outp(PORT_C, 0x07);
  296. }
  297.  
  298. void nullFunction()
  299. {}
  300. #endif /* TSR */
  301.  
  302. void keyInit()
  303. /*
  304.  * iniz keyboard mode; set defaults
  305.  */
  306. {
  307.     clickFlag = DEFAULT_KEY_CLICK;
  308.     applKeypad = DEFAULT_APP_KEYBOARD;
  309.     applCursor = DEFAULT_CURSOR_KEY_MODE;
  310.     asckey = DEFAULT_KEYBOARD;
  311.     bsDel = DEFAULT_BS_KEY;
  312.     shiftLock = DEFAULT_SHIFT_LOCK;
  313.     fepInvoke = DEFAULT_FEP_INVOKE;
  314.     mouseSpeed = DEFAULT_MOUSE_SPEED;
  315.     shiftLocked = ctrlLocked = NO;
  316.     bsKeyCount = keyCount = 0;
  317.     bsKeyRatio = DEFAULT_BS_KEY_RATIO;
  318.     ctrlSpace = YES;
  319.     meta = fepMode = ctrlLocked = shiftLocked = NO;
  320.     keyVector = 0;
  321.     keyReInit();
  322.  }
  323.  
  324. void keyReInit()
  325.  /*
  326.   * re-initialize keyboard
  327.   */
  328.  {
  329.     /*
  330.      * set key interrupt handler
  331.      */
  332. #ifdef TSR
  333.     keyVector = getVect(9);
  334.     setVect(9, keyHandler);
  335. #else
  336.     keyVector = GET_DOSVECT(9);
  337.     SET_DOSVECT(9, keyHandler);
  338. #endif
  339.     mouseInit();
  340. }
  341.  
  342. void keySetup()
  343. /*
  344.  * setup keyboard mode 
  345.  */
  346. {
  347.     keyMode();
  348.     setBSDel(bsDel);
  349. }
  350.  
  351. void keyEnd()
  352. {
  353.     /*
  354.      * restore key handler
  355.      */
  356.     if (keyVector) {
  357. #ifdef TSR
  358.         setVect(9, keyVector);        /* use own library    */
  359. #else
  360.         SET_DOSVECT(9, keyVector);
  361. #endif    /* TSR */
  362.         mouseEnd();
  363.     }
  364.     keyVector = 0;
  365. }
  366.  
  367. void keyMode()
  368. /*
  369.  * change key board mode (PC9801 or ASCII)
  370.  */
  371. {
  372.     if (asckey) {
  373.         ctrltbl = actrltbl; noshiftbl = anoshiftbl;
  374.         shiftbl = ashiftbl; kanatbl = akanatbl;
  375.         shkanatbl = ashkanatbl;
  376.     } else {    
  377.         ctrltbl = pctrltbl; noshiftbl = pnoshiftbl;
  378.         shiftbl = pshiftbl; kanatbl = akanatbl;
  379.         shkanatbl = ashkanatbl;
  380.     }
  381. }
  382.  
  383. void setBSDel(bsDelFlag)
  384. /*
  385.  * switch BS -> DEL or BS -> BS
  386.  */
  387. {
  388.     if (bsDelFlag == BS_BS) {
  389.         anoshiftbl[BS_SCAN_CODE] = 
  390.         akanatbl[BS_SCAN_CODE] = 
  391.         ashkanatbl[BS_SCAN_CODE] = 
  392.         pnoshiftbl[BS_SCAN_CODE] = BS;
  393.     } else {
  394.         anoshiftbl[BS_SCAN_CODE] = 
  395.         akanatbl[BS_SCAN_CODE] = 
  396.         ashkanatbl[BS_SCAN_CODE] = 
  397.         pnoshiftbl[BS_SCAN_CODE] = DEL;
  398.     }
  399. }
  400.  
  401. #ifndef TSR
  402. short keyin()
  403. /* 
  404.  * return charactor code if data available, else return -1
  405.  *
  406.  * INTERFACE:
  407.  *
  408.  * if key is hterm special control key, return code is xx00
  409.  * if key is KANJI char, return code is xxyy (JIS without preamble)
  410.  * else    return code is 00xx
  411.  *
  412.  * NOTE:
  413.  * we should NOT call outPort() (serial output) in this procedure.
  414.  *
  415.  */
  416. {
  417.     register short c;
  418.     register short cl;
  419.  
  420. #ifdef SOFT_FONT
  421.     if (softFont && blinkCursor && (blinkTimer <= 0)) {
  422.         blinkSoftCursor();
  423.     }
  424. #endif /* SOFT_FONT */
  425.  
  426. #ifdef PC98XA
  427.     /* first try to get hterm special key */
  428.     if (XAcount > 0) {
  429.         c = XAspecial[XAsplpos];
  430.         ++XAsplpos;
  431.         --XAcount;
  432.     } else {
  433.         /* try to get from DOS */
  434.         XAsplpos = 0;
  435.         if ((c = directConsoleIO()) == -1)
  436.             return(-1);
  437.     }
  438. #else
  439.     /* try to get from DOS */
  440.     if ((c = directConsoleIO()) == -1)
  441.         return(-1);
  442. #endif /* PC98XA */
  443.     /*
  444.      * reset screen saver timer because user hits keyboard.
  445.      */
  446.     timerValue = timerLoadValue;
  447.     /*
  448.      * if FEP mode, build hterm kanji code
  449.      */
  450.     if (fepMode) {
  451.         /* THIS IS DANGEROUS, for fast CTRL-XFER */
  452.         if (isSJIS1(c)) {
  453.             /* get SJIS second byte */
  454.             while ((cl = directConsoleIO()) == -1)
  455.                 ;
  456.             /*
  457.              * if NEC keisen, convert to JIS-83 keisen
  458.              */
  459.             if (c == 0x86 && 0xa2 <= cl && cl <= 0xed) {
  460.                 c = 0x84;
  461.                 cl = keiUnConv[cl - 0xa2];
  462.             }
  463.             return(SJIStoJIS(c, cl));
  464.         }
  465.         return(c);
  466.     }
  467. #ifdef PC98XA
  468.     /* quoting is not used on PC98XA */
  469. #else
  470.     /*
  471.      * deconpose quoted char if required
  472.      */
  473.     c &= 0x7f;
  474.     if (c == QUOTE_CHAR) {
  475.         /* get quoted char (kana or hterm ctrl char) */
  476.         while ((c = directConsoleIO()) == -1)
  477.             ;
  478.         if (c != QUOTE_CHAR) {
  479.             c |= 0x80;
  480.             if (c == (NE_KEY>>8))
  481.                 c = 0xc8;        /* kana 'ne' key */
  482.             if (c == DELK_THRU_MTTK) 
  483.                 c = DEL_KEY;        /* matutake taisaku */
  484.         }
  485.     }
  486. #endif /* PC98XA */
  487.     /*
  488.      * treat break signal here
  489.      */
  490.     if (c == SHORT_BREAK) {
  491.         sendBreak(1);
  492.         return(-1);
  493.     } else if (c == LONG_BREAK) {
  494.         sendBreak(2);
  495.         return(-1);
  496.     }
  497.     /*
  498.      * return hterm internal char code. 
  499.      * if special key then $xx00, else $00xx 
  500.      */
  501.     return(isHtermCtrl(c) ? (c << 8): c);
  502. }
  503. #endif /* TSR */
  504.  
  505. void interrupt FAR keyHandler()
  506. /*
  507.  * convert scan code to ASCII code, put chars in BIOS buffer
  508.  *
  509.  * This may look like too complex, but don't worry!
  510.  */
  511. {
  512.     register u_char keyCode;
  513.     register short inCode = 0;
  514.     int    pullFlag;
  515.     register struct _BIOS_WORK FAR *w = 
  516.             (struct _BIOS_WORK FAR *)BIOS_KEY_WORK;
  517.     register char shiftState;
  518.  
  519.     outp(ADDR_KEY_STATUS, 0x16);    /* no retry            */
  520.     nullFunction();            /* short wait            */
  521.     nullFunction();            /* short wait            */
  522.     nullFunction();            /* short wait            */
  523.  
  524.     keyCode = inp(ADDR_KEY_DATA);    /* get key code from keyboard    */
  525.     pullFlag = (keyCode & 0x80);
  526.     keyCode &= 0x7f;
  527.  
  528.     /*
  529.      * key swapping
  530.      */
  531.     if (keyCode < sizeof(keySwapTable)) {
  532.         if ((keyCode = keySwapTable[(int)keyCode]) == 0xff)
  533.             goto end;
  534.         keyCode &= 0x7f;
  535.     }
  536.  
  537.     /*
  538.      * set/clear key status table
  539.      */
  540.     shiftState = 1 << (keyCode & 0x7);
  541.     if (!shiftLock || (keyCode != 0x70/*shift*/ && keyCode != 0x74/*ctrl*/)) {
  542.           w->KB_STS[keyCode/8] ^= shiftState;    /* update BIOS key table   */
  543.         w->KB_SHFT = w->KB_STS[0x0e];        /* update BIOS shift status*/
  544.         if (keyCode/8 == 0x0e)        /* return if shift/ctrl/kana.. key */
  545.             goto end;
  546.     } else if (!pullFlag) {
  547.         /*
  548.          * process shift/ctrl lock feature 
  549.          * CAUTION complex logic
  550.          */
  551.         if (S_SHIFT(shiftState)) {
  552.             if (shiftLocked == 2) {    /* double shift */
  553.                 w->KB_STS[keyCode/8] = (w->KB_SHFT &= ~0x01);
  554.                 shiftLocked = NO;
  555.             } else if (shiftLocked == 1) { /* single shift */
  556.                 shiftLocked++;
  557.                 click();
  558.                 click();
  559.             } else {        /* no shift    */
  560.                 w->KB_STS[keyCode/8] = (w->KB_SHFT |= 0x01);
  561.                 shiftLocked++;
  562.                 click();
  563.             }
  564.         } else if (S_CTRL(shiftState)) {
  565.             if (ctrlLocked == 2) {    /* double shift    */
  566.                 w->KB_STS[keyCode/8] = (w->KB_SHFT &= ~0x10);
  567.                 ctrlLocked = NO;
  568.             } else if (shiftLocked == 1) { /* single shift */
  569.                 shiftLocked++;
  570.                 click();
  571.                 click();
  572.             } else {        /* no shift */
  573.                 w->KB_STS[keyCode/8] = (w->KB_SHFT |= 0x10);
  574.                 ctrlLocked++;
  575.                 click();
  576.             }
  577.         }
  578.         goto end;
  579.     }
  580.  
  581.     if (pullFlag)
  582.         goto end;
  583.  
  584.     /*
  585.      * set shift status
  586.      */
  587.     meta = 0;
  588.     shiftState = w->KB_SHFT;
  589.  
  590.     if (S_NFER(w->KB_STS[6]) || S_XFER(w->KB_STS[0x0a]))
  591.         meta = YES;
  592.  
  593.     /*
  594.      * check keyboard control sequence; CTRL-SHIFT
  595.      * otherwise key with shift & ctrl is treated as with ctrl
  596.      */
  597.     if (S_SHIFT(shiftState) && S_CTRL(shiftState)) {
  598.         if (keyCtrl(keyCode))
  599.             goto end;
  600.         shiftState &= ~0x01;        /* strip shift    */
  601.     }
  602.  
  603.     if (clickFlag == YES)
  604.         click();
  605.     /*
  606.      * key is pressed. reset shift/ctrl lock if single shift
  607.      */
  608.     if (shiftLocked == 1) {
  609.         w->KB_STS[0x0e] = (w->KB_SHFT &= ~0x01);
  610.         shiftLocked = 0;        /* reset shiftlock    */
  611.     }
  612.     if (ctrlLocked == 1) {
  613.         w->KB_STS[0x0e] = (w->KB_SHFT &= ~0x10);
  614.         ctrlLocked = 0;            /* reset ctrllock    */
  615.     }
  616. #ifdef PC98XA
  617.     inCode = shiftState;        /* 98XA's inCode is shift state */
  618.     if (keyCode == BS_SCAN_CODE)
  619.         if (noshiftbl[BS_SCAN_CODE] == DEL)
  620.             keyCode = 0x39;
  621. #endif /* PC98XA */
  622.  
  623. #ifdef PC98XA
  624.       /*
  625.      * CTRL-ESCAPE / Shift-ESCAPE
  626.      */
  627.     if (keyCode == 0x00) {
  628.         if (S_KANA(shiftState) && fepMode) {
  629.             /* put kana without quoting */
  630.             putBuf((keyCode << 8) | inCode, 1);
  631.         }
  632.         else if (S_CTRL(shiftState)) {
  633.             putBuf(SHORT_BREAK, 0);
  634.         }
  635.         else if (S_SHIFT(shiftState)) {
  636.             putBuf(LONG_BREAK, 0);
  637.         }
  638.         else {
  639.             putBuf((keyCode<<8) | inCode, 1);
  640.         }
  641.     }
  642.     /*
  643.      * typewriter keys
  644.      */
  645.     else if (0 < keyCode && keyCode <= LAST_KEY_TABLE) {
  646.         /* We don't support key mapping on PC98XA */
  647.         if (S_KANA(shiftState) && fepMode) {
  648.             /* put kana without quoting */
  649.             putBuf((keyCode << 8) | inCode, 1);
  650.         } else {
  651.             if (meta)
  652.                 putBuf((0x0 /* ESC */<<8) | inCode, 0);
  653.             putBuf((keyCode << 8) | inCode, 0);
  654.         }
  655. #else
  656.     /*
  657.      * typewriter keys
  658.      */
  659.     if (0 <= keyCode && keyCode <= LAST_KEY_TABLE) {
  660.         if (S_CTRL(shiftState))            /* CTRL-    */
  661.             inCode = ctrltbl[keyCode];
  662.         else if (S_KANA(shiftState))        /* KANA-    */
  663.             inCode = S_SHIFT(shiftState) ? shkanatbl[keyCode] : kanatbl[keyCode];
  664.         else                    /* NORMAL    */
  665.             inCode = S_SHIFT(shiftState) ? shiftbl[keyCode] : noshiftbl[keyCode];
  666.  
  667.         if (S_CAPS(shiftState)) {    /* CAPS    */
  668.             if (S_SHIFT(shiftState) && isUpper(inCode))
  669.                 inCode += 0x20;
  670.             else if (!S_SHIFT(shiftState) && isLower(inCode))
  671.                 inCode -= 0x20;
  672.         }
  673.         if (inCode != NA) {
  674.             if (meta && !fepMode)
  675.                 putBuf(ESC, 0);
  676.             if (S_KANA(shiftState) && (fepMode || mode == M_OS)) {
  677.                 /* put kana without quoting */
  678.                 putBuf(inCode, 1);
  679.             } else {
  680.                 if (inCode == 0xc8)    /* kana NE key */
  681.                     inCode = (NE_KEY >> 8);
  682.                 putBuf(inCode, 0);
  683.             }
  684.         }
  685. #endif /* PC98XA */
  686.     /*
  687.      * NFER
  688.      */
  689.     } else if (keyCode == 0x51) {
  690.         if (fepMode) {
  691.             if (S_SHIFT(shiftState) || S_CAPS(shiftState)) keyCode = 0xa1;
  692.             else if (S_CTRL(shiftState)) keyCode = 0xb1;
  693.             else keyCode = 0x51;
  694.             putBuf((keyCode << 8), 0);
  695.         } /* else ignore NFER, it's meta key */
  696.     /*
  697.      * XFER
  698.      */
  699.     } else if (keyCode == 0x35) {
  700.         if (mode == M_OS || mode == M_COMM || mode == M_HISTORY) {
  701.             if ((fepInvoke == FEP_CTRLXFER && S_CTRL(shiftState)) || 
  702.                 (fepInvoke == FEP_SHIFTXFER && S_SHIFT(shiftState)) ||
  703.                 (fepInvoke == FEP_BOTHXFER && (S_CTRL(shiftState) || S_SHIFT(shiftState)))) {
  704.                 fepMode = !fepMode;
  705.                 putBuf(S_CTRL(shiftState) ? 0xb500: 0xa500, 0);
  706.             } else if (fepMode) {
  707. #if 0
  708.                 putBuf((S_SHIFT(shiftState) || S_CAPS(shiftState)) ? 0xa500 : 0x3500, 0);
  709. #else
  710.                 putBuf(0x3500, 0);
  711. #endif
  712.             }
  713.         }
  714.     /*
  715.      * CTRL-SPACE
  716.      */
  717. #ifdef PC98XA
  718.     } else if (keyCode == 0x34) {
  719.         if (S_CTRL(shiftState)) {
  720.             keyCode = 0x1a;            /* CTRL-@    */
  721.             inCode = shiftState;
  722.         } else {
  723.             keyCode = 0x34;            /* Space */
  724.             inCode = 0;
  725.         }
  726.         if (meta)
  727.             putBuf((0<<8) /* ESC */ | inCode, 0);
  728.         putBuf((keyCode << 8) | inCode, 0);
  729. #else
  730.     } else if (keyCode == 0x34) {
  731.         if (ctrlSpace && S_CTRL(shiftState)) {
  732.             inCode = 0;
  733.             keyCode = 0x1a;            /* CTRL-@    */
  734.         } else {
  735.             inCode = SPACE;
  736.             keyCode = 0x34;
  737.         }
  738.         if (meta && !fepMode)
  739.             putBuf((0<<8) | ESC, 0);
  740.         putBuf((keyCode << 8) | inCode, 0);
  741. #endif /* PC98XA */
  742.     /*
  743.      * function keys
  744.      */
  745.     } else if (KEY_CODE_PF1 <= keyCode && keyCode <= KEY_CODE_PF10) {
  746.         if (fepMode || mode == M_OS) {
  747. #ifdef PC98XA
  748.             /* scan code will be built in BIOS INT18H */
  749.             putBuf((keyCode << 8)| inCode, 0);
  750. #else
  751.             if (S_SHIFT(shiftState))
  752.                 keyCode += 0x20;
  753.             else if (S_CTRL(shiftState))
  754.                 /* 
  755.                  * CTRL-PF with ATOK makes hterm brain damaged! 
  756.                  * but this is needed for WXP.
  757.                  */
  758.                 keyCode += 0x30;
  759.             /* else normal is ok */
  760.             putBuf((keyCode << 8), 0);
  761. #endif /* PC98XA */
  762. #ifndef TSR
  763.         } else {    /* communication mode */
  764.             if (S_SHIFT(shiftState)) {
  765.                 putFunkey(keyCode-KEY_CODE_PF1, 0/*inCode*/, SHIFTFunkey);
  766.             } else if (S_CTRL(shiftState)) {
  767.                 putBuf(CTRLFunkey[keyCode - KEY_CODE_PF1]>>8, 0);
  768.             } else if (meta) {
  769.                 putBuf(METAFunkey[keyCode - KEY_CODE_PF1]>>8, 0);
  770.             } else {
  771.                 putFunkey(keyCode-KEY_CODE_PF1, 0/* inCode*/, NORMALFunkey);
  772.             }
  773. #endif /* TSR */
  774.         }
  775. #ifdef PC98XA
  776.     /*
  777.      * function keys  PF11 ~ PF15   Sorry, but I want.
  778.      */
  779.     } else if (keyCode >= KEY_CODE_PF11 &&  keyCode <= KEY_CODE_PF15) {
  780.         putBuf((keyCode << 8) | inCode, 0);
  781. #endif /* PC98XA */
  782.     /*
  783.      * cursor keys and ten keys
  784.      */
  785.     } else if (SCAN_PAD_BEGIN <= keyCode && keyCode <= SCAN_PAD_END) {
  786.         if (fepMode || mode == M_OS) {
  787. #ifdef PC98XA
  788.             /* scan code will be built in BIOS INT18H */
  789.             putBuf((keyCode << 8)| inCode, 0);
  790. #else
  791.             if (keyCode >= 0x40)    /* ten key    */
  792.                 putBuf(CTRLPad[keyCode-SCAN_PAD_BEGIN], 0);
  793.             else
  794.                 putBuf((keyCode << 8), 0);
  795. #endif /* PC98XA */
  796. #ifndef TSR
  797.         } else if (mode == M_HISTORY || mode == M_SETUP) {    /* CTRL-keypad */
  798.             putBuf(CTRLPad[keyCode-SCAN_PAD_BEGIN], 0);
  799.         } else {        /* normal condition in comm. mode */
  800. #ifdef PC98XA
  801.             /* according to BlackROSE@ROS, HOME and HELP key belong to cursor key */
  802.              if ((keyCode >= 0x40 && !applKeypad) || (keyCode < 0x40 && !applCursor)) {
  803. #else
  804.              if ((keyCode >= 0x3e && !applKeypad) || (keyCode < 0x3e && !applCursor)) {
  805. #endif /* PC98XA */
  806.                 putFunkey(keyCode-SCAN_PAD_BEGIN, 0/* inCode*/, NORMALPad);
  807.             } else {
  808.                 putFunkey(keyCode-SCAN_PAD_BEGIN, 0/* inCode*/, APPLPad);
  809.             }
  810. #endif /* TSR */
  811.         }
  812.     /*
  813.      * copy/stop  (set-up/exit)
  814.      */
  815.     } else if (keyCode == KEY_CODE_COPY || keyCode == KEY_CODE_STOP) {
  816. #ifndef TSR
  817.         if (!fepMode && mode != M_OS) {
  818.             if (!(S_CTRL(shiftState) || S_SHIFT(shiftState)))
  819.                 putBuf(((keyCode == KEY_CODE_COPY) ? SETUP_KEY : STOP_KEY)>>8, 0);
  820.         } else if (mode == M_OS)
  821. #endif /* TSR */
  822.         {
  823. #ifdef TSR
  824.             outp(ICR, EOI);
  825.             if (keyCode == KEY_CODE_STOP)
  826.                 int6();
  827.             else 
  828.                 int5();
  829.             return;
  830. #endif /* TSR */
  831.         }
  832.     }
  833.     /*
  834.      * else ignore
  835.      */    
  836. end:
  837.     outp(ICR, EOI);            /* end of interrupt    */
  838. }
  839.  
  840. static int keyCtrl(keyCode)
  841. /*
  842.  * control TSR program from the keyboard by CTRL-SHIFT-keyCode
  843.  */
  844. register u_char keyCode;
  845. {
  846.     struct SREGS segRegs;
  847.     void (FAR *boot)();
  848.     int done = YES;
  849.  
  850.     switch (keyCode) {
  851.     case 0:    /* ESC:     terminate hkey    */
  852.         outp(ICR, EOI);            /* end of interrupt        */
  853.         keyEnd();                /* restore key interrupt vector    */
  854. #if 0
  855.         /*
  856.          * we should check in dos flag
  857.          */
  858.         segread(&segRegs);
  859.         segRegs.es = pspSegment;
  860.         rg.h.ah = 0x49;
  861.         int86x(0x21, &rg, &rg, &segRegs);    /* free memory        */
  862.         rg.x.ax = 0x4c00;
  863.         intdos(&rg, &rg);        /* terminate process    */
  864. #endif
  865.         break;
  866.     case KEY_CODE_STOP:            /* stop: reset system    */
  867.         outp(ICR, EOI);
  868.         outp(0x37, 0x0b);
  869.         outp(0x37, 0x0f);        /* ???        */
  870.         outp(0x0f0, 0x00);        /* reset CPU        */
  871.         FP_SEG(boot) = 0xffff;
  872.         FP_OFF(boot) = 0;
  873.         (*boot)();                /* reboot            */
  874.         break;
  875.     case 0x4a:        /* ten key 1: ascii keyboard    */
  876.         asckey = YES; keyMode(); break;
  877.     case 0x4b:        /* ten key 2: pc98 keyboard        */
  878.         asckey = NO; keyMode(); break;
  879.     case 0x4c:        /* ten key 3: key click on        */
  880.         clickFlag = YES; break;
  881.     case 0x46:        /* ten key 4: key click off        */
  882.         clickFlag = NO;    break;
  883.     case 0x47:        /* ten key 5: CTRL-XFER fep        */
  884.         fepInvoke = FEP_CTRLXFER; break;
  885.     case 0x48:        /* ten key 6: SHIFT-XFER fep    */
  886.         fepInvoke = FEP_SHIFTXFER; break;
  887.     case 0x42:        /* ten key 7: BOTH-XFER fep        */
  888.         fepInvoke = FEP_BOTHXFER; break;
  889.     case 0x43:        /* ten key 8: NO-XFER fep        */
  890.         fepInvoke = FEP_NOXFER; break;
  891.     case 0x44:        /* ten key 9: toggle CTRL-SPACE    */
  892.         ctrlSpace = !ctrlSpace; break;
  893.     case 0x3f:        /* ten key HELP: shift/ctrl lock    */
  894.         shiftLock = YES; break;
  895.     case 0x3e:        /* ten key HELP: shift/ctrl lock    */
  896.         shiftLock = NO; break;
  897.     default:
  898.         done = NO;
  899.     }
  900.     return(done);
  901. }
  902.  
  903. #ifndef TSR
  904. static void putFunkey(key, inCode, keyTable)
  905. /*
  906.  * put a string into BIOS key buffer
  907.  */
  908. u_char key, inCode;
  909. u_char (*keyTable)[MAX_FUNKEY];
  910. {
  911.     u_char *p;
  912.  
  913. #ifdef PC98XA
  914.     XAcount = 0;
  915.     for (p = keyTable[key]; *p; p++) {
  916.         XAspecial[XAcount++] = *p;
  917.         if (XAcount >= MAX_FUNKEY)
  918.             break;
  919.     }
  920. #else
  921.     for (p = keyTable[key]; *p; p++) 
  922.         putBuf((inCode << 8) | *p, 0);
  923. #endif /* PC98XA */
  924. }
  925. #endif /* TSR */
  926.  
  927. /*
  928.  * put a char to BIOS key buffer
  929.  */
  930. static void putBuf(c, recFlag)
  931. short c;
  932. int recFlag;        /* recursive flag */
  933. {
  934.     register struct _BIOS_WORK FAR *w = 
  935.             (struct _BIOS_WORK FAR *)BIOS_KEY_WORK;
  936.     short FAR *p;
  937.     u_char c0 = (c & 0xff);
  938.  
  939. #ifdef BS_WATCHER
  940.     /*
  941.      * BS key watcher
  942.      */
  943.     if (recFlag == NO) {
  944. #ifdef PC98XA
  945.         if ((c >> 8) == 0x39/*DEL*/ || (c >> 8) == BS_SCAN_CODE)
  946. #else
  947.         if (c0 == BS || c0 == DEL)
  948. #endif /* PC98XA */
  949.             bsKeyCount++;
  950.         keyCount++;
  951.     }
  952. #endif /* BS_WATCHER */
  953.  
  954. #ifdef PC98XA
  955.     /* 
  956.      * if special ctrl char, put it on own buffer
  957.      */
  958.     if (!recFlag && mode != M_OS && (c0 > 0x80)) {
  959.         XAspecial[0] = c;
  960.         XAcount = 1;
  961.         return;
  962.     }
  963. #else
  964.     /* 
  965.      * if special ctrl char, quote it
  966.      */
  967.     if (!fepMode && !recFlag && mode != M_OS && ((c0 > 0x80) || c0 == QUOTE_CHAR || c0 == DEL_KEY)) {
  968.         putBuf(QUOTE_CHAR, 1);
  969.         if(c0 == DEL_KEY)
  970.             c = DELK_THRU_MTTK;
  971.         c0 = c &= 0x7f;
  972.     }
  973. #endif /* PC98XA */
  974.     if (w->KB_COUNT > 16) {
  975.         click();
  976.         return;
  977.     }
  978.     w->KB_COUNT++;
  979.     FP_SEG(p) = 0;
  980.     FP_OFF(p) = w->KB_TAIL;
  981. #ifdef  PC98XA
  982.     /*
  983.      * XA's code is XXYY where XX is scan code and YY is shift state.
  984.      */
  985. #else
  986.     /*
  987.      * generate scan code
  988.      * upper 8 bit is scan code, lower 8 bit is incode
  989.      */
  990.     if (((c & 0xff00) == 0) && (c0 != ESC))
  991.         c |= ((short)(ASCIItoSCAN[c0]) << 8);
  992. #endif /* PC98XA */
  993.     /*
  994.      * OK put it on buffer
  995.      */
  996.     *p++ = c;
  997.     if (p >= &(w->KB_BUF[16]))
  998.         p = w->KB_BUF;
  999.     w->KB_TAIL = FP_OFF(p);
  1000. }
  1001.  
  1002. #ifndef TSR
  1003. int checkKey()
  1004. /*
  1005.  * return non 0 if some key is pressed
  1006.  */
  1007. {
  1008.     /* check keycode buffer */
  1009.     rg.h.ah = 1;            /* sense only        */
  1010.     int86(KEY_BIOS, &rg, &rg);
  1011.     if (rg.h.bh)
  1012.         return(1);
  1013.  
  1014.     /* check non lock type ctrl key */
  1015.     rg.h.ah = 2;
  1016.     int86(KEY_BIOS, &rg, &rg);    /* ksens1 */
  1017.     if (S_SHIFT(rg.h.al) || S_CTRL(rg.h.al) || meta)
  1018.         return(1);
  1019.     return(0);
  1020. }
  1021.  
  1022. #ifdef SETUP
  1023. void editNormalKeys()
  1024. {
  1025. #ifndef PC98XA
  1026.     editKeyTable(normalKeyName, (u_char (*)[MAX_FUNKEY])noshiftbl, NUM_NORMAL_KEY, 1, NORMAL_KEY_NAME_LEN);
  1027. #endif
  1028. }
  1029.  
  1030. void editShiftKeys()
  1031. {
  1032. #ifndef PC98XA
  1033.     editKeyTable(shiftKeyName, (u_char (*)[MAX_FUNKEY])shiftbl, NUM_NORMAL_KEY, 1, NORMAL_KEY_NAME_LEN);
  1034. #endif
  1035. }
  1036.  
  1037. void editCtrlKeys()
  1038. {
  1039. #ifndef PC98XA
  1040.     editKeyTable(normalKeyName, (u_char (*)[MAX_FUNKEY])ctrltbl, NUM_NORMAL_KEY, 1, NORMAL_KEY_NAME_LEN);
  1041. #endif
  1042. }
  1043.  
  1044. void editKanaKeys()
  1045. {
  1046. #ifndef PC98XA
  1047.     editKeyTable(normalKeyName, (u_char (*)[MAX_FUNKEY])akanatbl, NUM_NORMAL_KEY, 1, NORMAL_KEY_NAME_LEN);
  1048. #endif
  1049. }
  1050.  
  1051. void editShKanaKeys()
  1052. {
  1053. #ifndef PC98XA
  1054.     editKeyTable(normalKeyName, (u_char (*)[MAX_FUNKEY])ashkanatbl, NUM_NORMAL_KEY, 1, NORMAL_KEY_NAME_LEN);
  1055. #endif
  1056. }
  1057.  
  1058. void editPFKey()
  1059. {
  1060.     editKeyTable(funkeyName, NORMALFunkey, NUM_FUNKEY, MAX_FUNKEY, FUNKEY_NAME_LEN);
  1061. }
  1062.  
  1063. void editSPFKey()
  1064. {
  1065.     editKeyTable(funkeyName, SHIFTFunkey, NUM_FUNKEY, MAX_FUNKEY, FUNKEY_NAME_LEN);
  1066. }
  1067.  
  1068. void editCursorKey()
  1069. {
  1070.     editKeyTable(keypadName, NORMALPad, NUM_PADKEY, MAX_FUNKEY, KEYPAD_NAME_LEN);
  1071. }
  1072.  
  1073. void editAppCursorKey()
  1074. {
  1075.     editKeyTable(keypadName, APPLPad, NUM_PADKEY, MAX_FUNKEY, KEYPAD_NAME_LEN);
  1076. }
  1077.  
  1078. void editAppKeyPad()
  1079. {
  1080.     putStatus("IBM-PC only (Use Appl. Cursor Keys)");
  1081. }
  1082.  
  1083. void editBinding()
  1084. {
  1085.     editKeyTable(bindName, (u_char (*)[MAX_FUNKEY])bindTab, NUM_BIND, 1, BIND_NAME_LEN);
  1086. }
  1087.  
  1088. void editKeySwapTable()
  1089. {
  1090. #define NUM_LINE 13
  1091.     int i, end = NO;
  1092.     char buf[8], *junk;
  1093.     u_char oldKey, kc;
  1094.  
  1095.     for (;;) {
  1096.         clearCopyright();
  1097.         locate(0, 0);
  1098.         conPrint("Current key swapping...");
  1099.         for (kc = i = 0; kc < sizeof(keySwapTable); kc++) {
  1100.             if (keySwapTable[kc] == kc)
  1101.                 continue;
  1102.             locate((i/NUM_LINE)*(14), i%NUM_LINE+1);
  1103.             sprintf(tmpBuf, "$%02x -> $%02x", kc, keySwapTable[kc]);
  1104.             conPrint(tmpBuf);
  1105.             i++;
  1106.         }
  1107.         if (i == 0)
  1108.             conPrint("none");
  1109.         if (end)
  1110.             break;
  1111.         locate(40, 13);
  1112.         conPrint("Caution! Effects immediately");
  1113.         locate(40, 14);
  1114.         conPrint("Enter swappee key code");
  1115.         locate(40,15);
  1116.         conPrint("ESC for end");
  1117.         buf[0] = '\0';
  1118.         if (emacs("From Key code: $", buf, 6, E_NO_HELP) == ERR || buf[0] == '\0') {
  1119.             end = YES;
  1120.             continue;
  1121.         }
  1122.         if ((oldKey = (u_char)strtol(buf, &junk, 16)) > sizeof(keySwapTable))
  1123.             continue;
  1124.         sprintf(tmpBuf, "$%02x -> $", oldKey);
  1125.         buf[0] = '\0';
  1126.         if (emacs(tmpBuf, buf, 6, E_NO_HELP) == ERR || buf[0] == '\0')
  1127.             continue;
  1128.         keySwapTable[oldKey] = (u_char)strtol(buf, &junk, 16);
  1129.     }
  1130. }
  1131.  
  1132. void saveKey(fd)
  1133. int fd;
  1134. /*
  1135.  * save key pad string, cursor key string, pf key string
  1136.  */
  1137. {
  1138.     write(fd, (char *)NORMALFunkey, sizeof(NORMALFunkey));
  1139.     write(fd, (char *)SHIFTFunkey, sizeof(SHIFTFunkey));
  1140.     write(fd, (char *)NORMALPad, sizeof(NORMALPad));
  1141.     write(fd, (char *)APPLPad, sizeof(APPLPad));
  1142.     write(fd, (char *)keySwapTable, sizeof(keySwapTable));
  1143.     write(fd, (char *)anoshiftbl, sizeof(anoshiftbl));
  1144.     write(fd, (char *)actrltbl, sizeof(actrltbl));
  1145.     write(fd, (char *)ashiftbl, sizeof(ashiftbl));
  1146.     write(fd, (char *)akanatbl, sizeof(akanatbl));
  1147.     write(fd, (char *)pnoshiftbl, sizeof(pnoshiftbl));
  1148.     write(fd, (char *)pctrltbl, sizeof(pctrltbl));
  1149.     write(fd, (char *)pshiftbl, sizeof(pshiftbl));
  1150.     write(fd, (char *)pctrltbl, sizeof(pctrltbl));
  1151.     write(fd, (char *)bindTab, sizeof(bindTab));
  1152. }
  1153. #endif /* SETUP */
  1154.  
  1155. void loadKey(fd)
  1156. int fd;
  1157. /*
  1158.  * load key pad string, cursor key string, pf key string
  1159.  */
  1160. {
  1161.     read(fd, (char *)NORMALFunkey, sizeof(NORMALFunkey));
  1162.     read(fd, (char *)SHIFTFunkey, sizeof(SHIFTFunkey));
  1163.     read(fd, (char *)NORMALPad, sizeof(NORMALPad));
  1164.     read(fd, (char *)APPLPad, sizeof(APPLPad));
  1165.     read(fd, (char *)keySwapTable, sizeof(keySwapTable));
  1166.     read(fd, (char *)anoshiftbl, sizeof(anoshiftbl));
  1167.     read(fd, (char *)actrltbl, sizeof(actrltbl));
  1168.     read(fd, (char *)ashiftbl, sizeof(ashiftbl));
  1169.     read(fd, (char *)akanatbl, sizeof(akanatbl));
  1170.     read(fd, (char *)pnoshiftbl, sizeof(pnoshiftbl));
  1171.     read(fd, (char *)pctrltbl, sizeof(pctrltbl));
  1172.     read(fd, (char *)pshiftbl, sizeof(pshiftbl));
  1173.     read(fd, (char *)pctrltbl, sizeof(pctrltbl));
  1174.     read(fd, (char *)bindTab, sizeof(bindTab));
  1175. }
  1176. #endif /* TSR */
  1177.  
  1178. #ifdef MOUSE
  1179.  
  1180. /*
  1181.  *
  1182.  * mouse related functions
  1183.  *
  1184.  */
  1185. int mouseExists;
  1186. int mouseOn;
  1187. int mouseX, mouseY, mouseOriginX, mouseOriginY;
  1188. int mouseLowX, mouseHighX, mouseLowY, mouseHighY;
  1189. void (FAR *mouseHandler)();
  1190. #define INT_MOUSE 0x33
  1191.  
  1192. void mouseInit()
  1193. /*
  1194.  * initialize mouse
  1195.  */
  1196. {
  1197.     rg.x.ax = 0;
  1198.     int86(INT_MOUSE, &rg, &rg);    /* check mouse environment    */
  1199.     if (rg.x.ax == 0) 
  1200.         return;            /* no mouse            */
  1201.     /* set horizontal mouse space */
  1202.     rg.x.ax = 0x10;
  1203.     rg.x.cx = 0;
  1204.     rg.x.dx = 639;
  1205.     int86(INT_MOUSE, &rg, &rg);
  1206.     /* set vertical mouse space */
  1207.     rg.x.ax = 0x11;
  1208.     rg.x.cx = 0;
  1209.     rg.x.dx = 399;
  1210.     int86(INT_MOUSE, &rg, &rg);    
  1211.     /* get current position */
  1212.     rg.x.ax = 3;
  1213.     int86(INT_MOUSE, &rg, &rg);
  1214.     mouseOriginX = mouseX = rg.x.cx;
  1215.     mouseOriginY = mouseY = rg.x.dx;
  1216.     mouseLowX = mouseOriginX - 100; mouseHighX = mouseOriginX + 100;
  1217.     mouseLowY = mouseOriginY - 80; mouseHighY = mouseOriginY + 80;    
  1218.     mouseSetHandler(YES);
  1219. }
  1220.  
  1221. void mouseEnd()
  1222. {
  1223.     mouseSetHandler(NO);        /* remove handler        */
  1224. }
  1225.  
  1226. void mouseSetHandler(onOff)
  1227. int onOff;
  1228. {
  1229.     struct SREGS segRegs;
  1230.  
  1231.     mouseHandler = getMouseIntAddress();
  1232.     segread(&segRegs);
  1233.     rg.x.ax = 0x0c;
  1234.     /*
  1235.      * if onOff = YES, set move, left/right press handler
  1236.      * else mask all event
  1237.      */
  1238.     rg.x.cx = onOff ? 0x0b : 0;
  1239.     segRegs.es = FP_SEG(mouseHandler);
  1240.     rg.x.dx = FP_OFF(mouseHandler);
  1241.     int86x(INT_MOUSE, &rg, &rg, &segRegs);    /* set interrupt handler */
  1242. }
  1243.  
  1244. void mouseOnOff(onOff)
  1245. int onOff;
  1246. {
  1247.     rg.x.ax = onOff ? 1 : 2;
  1248.     int86(INT_MOUSE, &rg, &rg);
  1249. }
  1250.  
  1251. void mouseSetPosition(x, y)
  1252. int x, y;
  1253. {
  1254.     rg.x.ax = 4;
  1255.     rg.x.cx = x;
  1256.     rg.x.dx = y;
  1257.     int86(INT_MOUSE, &rg, &rg);
  1258. }
  1259.  
  1260. void FAR mouseEvent(event, x, y)
  1261. /*
  1262.  * mouse event interrupt handler
  1263.  */
  1264. int event, x, y;
  1265. {
  1266.     u_short c = 0;
  1267.     int dx = x - mouseX;
  1268.     int dy = y - mouseY;
  1269.     int thresh = (mouseSpeed + 1) * MOUSE_SPEED_BASE;
  1270.  
  1271.     spl7();
  1272.     switch (event) {
  1273.     case 1:    /* cursor is moved. */
  1274.         if (mode != M_COMM) {
  1275.             if (mode == M_SETUP)
  1276.                 thresh *= 2;    /* for selecting menu */
  1277.             if (dy > thresh)
  1278.                 c = DOWN_KEY >> 8;
  1279.             else if (dy < -thresh)
  1280.                 c = UP_KEY >> 8;
  1281.             if (c) {
  1282.                 putBuf(c, 0);
  1283.                 mouseY = y;
  1284.                 c = 0;
  1285.             }
  1286.             if (dx > thresh)
  1287.                 c = RIGHT_KEY >> 8;
  1288.             else if (dx < -thresh)
  1289.                 c = LEFT_KEY >> 8;
  1290.             if (c)
  1291.                 mouseX = x;
  1292.         }
  1293.         if (x < mouseLowX || x > mouseHighX || y < mouseLowY || y > mouseHighY) {
  1294.             /* recenter mouse position        */
  1295.             mouseSetPosition(mouseOriginX, mouseOriginY);
  1296.             mouseX = mouseOriginX;
  1297.             mouseY = mouseOriginY;
  1298.         }
  1299.         break;
  1300.     case 2:    /* left botton is pressed. */        
  1301.         if (mode == M_HISTORY)
  1302.             c = INS_KEY >> 8;
  1303.         else if (mode == M_SETUP)
  1304.             c = CR;
  1305.         else /* communication mode */
  1306.             c = PF_HIST_EDIT >> 8;    /* call history editor */
  1307.         break;
  1308.     case 8: /* right botton is pressed. */
  1309.         if (mode == M_HISTORY)
  1310.             c = CR;
  1311.         else if (mode == M_SETUP)
  1312.             c = ESC;
  1313.         else /* communication mode */
  1314.             c = SETUP_KEY >> 8;    /* call set-up    */
  1315.         break;
  1316.     }
  1317.     /* 
  1318.      * put emulated key into BIOS key buffer
  1319.      */
  1320.     if (c)
  1321.         putBuf(c, 0);
  1322.     /*
  1323.      * THIS may be bug!
  1324.      */
  1325.     splx();
  1326. }
  1327. #else
  1328. void FAR mouseEvent(int event, int x, int y) {}
  1329. void mouseOnOff(int onOff) {}
  1330. void mouseSetPosition(int x, int y) {}
  1331. void mouseEnd() {}
  1332. void mouseInit() {}
  1333. #endif /* MOUSE */
  1334.