Annotation of Net2/arch/i386/netboot/kbd.c, revision 1.1

1.1     ! root        1: /* netboot
        !             2:  *
        !             3:  * kbd.c,v
        !             4:  * Revision 1.1  1993/07/08  16:04:00  brezak
        !             5:  * Diskless boot prom code from Jim McKim ([email protected])
        !             6:  *
        !             7:  * Revision 1.2  1993/06/30  20:16:13  mckim
        !             8:  * Clean up compiler error msg.
        !             9:  *
        !            10:  * Revision 1.1.1.1  1993/05/28  11:41:07  mckim
        !            11:  * Initial version.
        !            12:  *
        !            13:  *
        !            14:  * source in this file came from
        !            15:  * the original 386BSD boot blocks.
        !            16:  *
        !            17:  * Copyright (c) 1990 The Regents of the University of California.
        !            18:  * All rights reserved.
        !            19:  *
        !            20:  * This code is derived from software contributed to Berkeley by
        !            21:  * William Jolitz.
        !            22:  *
        !            23:  * Redistribution and use in source and binary forms, with or without
        !            24:  * modification, are permitted provided that the following conditions
        !            25:  * are met:
        !            26:  * 1. Redistributions of source code must retain the above copyright
        !            27:  *    notice, this list of conditions and the following disclaimer.
        !            28:  * 2. Redistributions in binary form must reproduce the above copyright
        !            29:  *    notice, this list of conditions and the following disclaimer in the
        !            30:  *    documentation and/or other materials provided with the distribution.
        !            31:  * 3. All advertising materials mentioning features or use of this software
        !            32:  *    must display the following acknowledgement:
        !            33:  *     This product includes software developed by the University of
        !            34:  *     California, Berkeley and its contributors.
        !            35:  * 4. Neither the name of the University nor the names of its contributors
        !            36:  *    may be used to endorse or promote products derived from this software
        !            37:  *    without specific prior written permission.
        !            38:  *
        !            39:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            40:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            41:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            42:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            43:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            44:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            45:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            46:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            47:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            48:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            49:  * SUCH DAMAGE.
        !            50:  *
        !            51:  *     @(#)kbd.c       7.4 (Berkeley) 5/4/91
        !            52:  */
        !            53: 
        !            54: #include "proto.h"
        !            55: 
        !            56: #define        KBSTATP 0x64    /* kbd status port */
        !            57: #define                KBS_INP_BUF_FUL 0x02    /* kbd char ready */
        !            58: #define        KBDATAP 0x60    /* kbd data port */
        !            59: 
        !            60: #define K_RDWR                 0x60            /* keyboard data & cmds (read/write) */
        !            61: #define K_STATUS       0x64            /* keyboard status */
        !            62: #define K_CMD          0x64            /* keybd ctlr command (write-only) */
        !            63: 
        !            64: #define K_OBUF_FUL     0x01            /* output buffer full */
        !            65: #define K_IBUF_FUL     0x02            /* input buffer full */
        !            66: 
        !            67: #define KC_CMD_WIN     0xd0            /* read  output port */
        !            68: #define KC_CMD_WOUT    0xd1            /* write output port */
        !            69: #define KB_A20         0x9f            /* enable A20,
        !            70:                                           enable output buffer full interrupt
        !            71:                                           enable data line
        !            72:                                           disable clock line */
        !            73: 
        !            74: #define        L               0x01    /* locking function */
        !            75: #define        SHF             0x02    /* keyboard shift */
        !            76: #define        ALT             0x04    /* alternate shift -- alternate chars */
        !            77: #define        NUM             0x08    /* numeric shift  cursors vs. numeric */
        !            78: #define        CTL             0x10    /* control shift  -- allows ctl function */
        !            79: #define        CPS             0x20    /* caps shift -- swaps case of letter */
        !            80: #define        ASCII           0x40    /* ascii code for this key */
        !            81: #define        STP             0x80    /* stop output */
        !            82: 
        !            83: static u_char action[128] = {
        !            84: 0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,                /* scan  0- 7 */
        !            85: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,                /* scan  8-15 */
        !            86: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,                /* scan 16-23 */
        !            87: ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,                /* scan 24-31 */
        !            88: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,                /* scan 32-39 */
        !            89: ASCII, ASCII, SHF  , ASCII, ASCII, ASCII, ASCII, ASCII,                /* scan 40-47 */
        !            90: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,  SHF,  ASCII,                /* scan 48-55 */
        !            91:   ALT, ASCII, CPS|L,     0,     0, ASCII,     0,     0,                /* scan 56-63 */
        !            92:     0,     0,     0,     0,     0, NUM|L, STP|L, ASCII,                /* scan 64-71 */
        !            93: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,                /* scan 72-79 */
        !            94: ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,                /* scan 80-87 */
        !            95: 0,0,0,0,0,0,0,0,
        !            96: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
        !            97: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,      } ;
        !            98: 
        !            99: static u_char unshift[128] = { /* no shift */
        !           100: 0,     033  , '1'  , '2'  , '3'  , '4'  , '5'  , '6'  ,                /* scan  0- 7 */
        !           101: '7'  , '8'  , '9'  , '0'  , '-'  , '='  , 0177 ,'\t'  ,                /* scan  8-15 */
        !           102: 
        !           103: 'q'  , 'w'  , 'e'  , 'r'  , 't'  , 'y'  , 'u'  , 'i'  ,                /* scan 16-23 */
        !           104: 'o'  , 'p'  , '['  , ']'  , '\r' , CTL  , 'a'  , 's'  ,                /* scan 24-31 */
        !           105: 
        !           106: 'd'  , 'f'  , 'g'  , 'h'  , 'j'  , 'k'  , 'l'  , ';'  ,                /* scan 32-39 */
        !           107: '\'' , '`'  , SHF  , '\\' , 'z'  , 'x'  , 'c'  , 'v'  ,                /* scan 40-47 */
        !           108: 
        !           109: 'b'  , 'n'  , 'm'  , ','  , '.'  , '/'  , SHF  ,   '*',                /* scan 48-55 */
        !           110: ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,                /* scan 56-63 */
        !           111: 
        !           112:     0,     0,     0,     0,     0, NUM|L, STP|L,   '7',                /* scan 64-71 */
        !           113:   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',                /* scan 72-79 */
        !           114: 
        !           115:   '2',   '3',   '0',   '.',     0,     0,     0,     0,                /* scan 80-87 */
        !           116: 0,0,0,0,0,0,0,0,
        !           117: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
        !           118: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,      } ;
        !           119: 
        !           120: static u_char shift[128] = {   /* shift shift */
        !           121: 0,     033  , '!'  , '@'  , '#'  , '$'  , '%'  , '^'  ,                /* scan  0- 7 */
        !           122: '&'  , '*'  , '('  , ')'  , '_'  , '+'  , 0177 ,'\t'  ,                /* scan  8-15 */
        !           123: 'Q'  , 'W'  , 'E'  , 'R'  , 'T'  , 'Y'  , 'U'  , 'I'  ,                /* scan 16-23 */
        !           124: 'O'  , 'P'  , '['  , ']'  , '\r' , CTL  , 'A'  , 'S'  ,                /* scan 24-31 */
        !           125: 'D'  , 'F'  , 'G'  , 'H'  , 'J'  , 'K'  , 'L'  , ':'  ,                /* scan 32-39 */
        !           126: '"'  , '~'  , SHF  , '|'  , 'Z'  , 'X'  , 'C'  , 'V'  ,                /* scan 40-47 */
        !           127: 'B'  , 'N'  , 'M'  , '<'  , '>'  , '?'  , SHF  ,   '*',                /* scan 48-55 */
        !           128: ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,                /* scan 56-63 */
        !           129:     0,     0,     0,     0,     0, NUM|L, STP|L,   '7',                /* scan 64-71 */
        !           130:   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',                /* scan 72-79 */
        !           131:   '2',   '3',   '0',   '.',     0,     0,     0,     0,                /* scan 80-87 */
        !           132: 0,0,0,0,0,0,0,0,
        !           133: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
        !           134: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,      } ;
        !           135: 
        !           136: static u_char ctl[128] = {     /* CTL shift */
        !           137: 0,     033  , '!'  , 000  , '#'  , '$'  , '%'  , 036  ,                /* scan  0- 7 */
        !           138: '&'  , '*'  , '('  , ')'  , 037  , '+'  , 034  ,'\177',                /* scan  8-15 */
        !           139: 021  , 027  , 005  , 022  , 024  , 031  , 025  , 011  ,                /* scan 16-23 */
        !           140: 017  , 020  , 033  , 035  , '\r' , CTL  , 001  , 013  ,                /* scan 24-31 */
        !           141: 004  , 006  , 007  , 010  , 012  , 013  , 014  , ';'  ,                /* scan 32-39 */
        !           142: '\'' , '`'  , SHF  , 034  , 032  , 030  , 003  , 026  ,                /* scan 40-47 */
        !           143: 002  , 016  , 015  , '<'  , '>'  , '?'  , SHF  ,   '*',                /* scan 48-55 */
        !           144: ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,                /* scan 56-63 */
        !           145: CPS|L,     0,     0,     0,     0,     0,     0,     0,                /* scan 64-71 */
        !           146:     0,     0,     0,     0,     0,     0,     0,     0,                /* scan 72-79 */
        !           147:     0,     0,     0,     0,     0,     0,     0,     0,                /* scan 80-87 */
        !           148:     0,     0,   033, '7'  , '4'  , '1'  ,     0, NUM|L,                /* scan 88-95 */
        !           149: '8'  , '5'  , '2'  ,     0, STP|L, '9'  , '6'  , '3'  ,                /*scan  96-103*/
        !           150: '.'  ,     0, '*'  , '-'  , '+'  ,     0,     0,     0,                /*scan 104-111*/
        !           151: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,      } ;
        !           152: 
        !           153: static u_char shfts, ctls, alts, caps, num, stp;
        !           154: static u_char chr;
        !           155: static int is_chr_queued = 0;
        !           156: 
        !           157: static int
        !           158: ProcessKbdEvent(void) {
        !           159:   /* Returns 1 if event result is an ascii char, 0 otherwise (or no event).
        !           160:    * As a side effect, it digests keyboard events and queues bona fide
        !           161:    * characters for subsequent reading.
        !           162:    */
        !           163:   u_char dt, brk, act;
        !           164:   if ((inb(KBSTATP) & 0x01) == 0)
        !           165:     return is_chr_queued;
        !           166:   dt = inb(KBDATAP);
        !           167:   brk = dt & 0x80;
        !           168:   dt = dt & 0x7f;
        !           169: 
        !           170:   act = action[dt];
        !           171:   if (act & SHF) {
        !           172:     if (brk)
        !           173:       shfts = 0;
        !           174:     else
        !           175:       shfts = 1;
        !           176:   }
        !           177:   if (act & ALT) {
        !           178:     if (brk)
        !           179:       alts = 0;
        !           180:     else
        !           181:       alts = 1;
        !           182:   }
        !           183:   if (act & NUM) {
        !           184:     if (act & L) {
        !           185:       if (!brk)
        !           186:        num ^= 1;
        !           187:     } else
        !           188:       if(brk)
        !           189:        num = 0;
        !           190:       else
        !           191:        num = 1;
        !           192:   }
        !           193:   if (act & CTL) {
        !           194:     if (brk)
        !           195:       ctls = 0;
        !           196:     else
        !           197:       ctls = 1;
        !           198:   }
        !           199:   if (act & CPS) {
        !           200:     if (act & L) {
        !           201:       if (!brk)
        !           202:        caps ^= 1;
        !           203:     } else
        !           204:       if (brk)
        !           205:        caps = 0;
        !           206:       else
        !           207:        caps = 1;
        !           208:   }
        !           209:   if (act & STP) {
        !           210:     if (act & L) {
        !           211:       if (!brk)
        !           212:        stp ^= 1;
        !           213:     } else
        !           214:       if (brk)
        !           215:        stp = 0;
        !           216:       else
        !           217:        stp = 1;
        !           218:   }
        !           219:   if (ctls && alts && dt == 83)
        !           220:     exit(1);
        !           221:   if ((act & ASCII) && !brk) {
        !           222:     if (shfts) {
        !           223:       chr = shift[dt];
        !           224:     } else {
        !           225:       if (ctls) {
        !           226:        chr = ctl[dt];
        !           227:       } else {
        !           228:        chr = unshift[dt];
        !           229:       }
        !           230:     }
        !           231:     if (caps && (chr >= 'a' && chr <= 'z')) {
        !           232:       chr -= 'a' - 'A' ;
        !           233:     }
        !           234:     is_chr_queued = 1;
        !           235:   }
        !           236:   return is_chr_queued;
        !           237: }
        !           238: 
        !           239: int
        !           240: IsKbdCharReady(void) {
        !           241: #ifdef USE_BIOS
        !           242:   int result;
        !           243:   asm("
        !           244:        push    %%ebx
        !           245:        call    _prot_to_real
        !           246:        mov     $1, %%ax
        !           247:        int     $0x16
        !           248:        setz    %%bl
        !           249:        .byte   0x66
        !           250:        call    _real_to_prot
        !           251:        movsbl  %%bl, %0
        !           252:        pop     %%ebx
        !           253:        " : "=g" (result));
        !           254:   return result;
        !           255: #else
        !           256:   return ProcessKbdEvent();
        !           257: #endif
        !           258: }
        !           259: 
        !           260: static int
        !           261: scankbd(void) {
        !           262:        
        !           263: #ifdef notdef
        !           264:   u_char c;
        !           265:        c = inb(KBDATAP);
        !           266:        if (c == 83) exit();
        !           267:        /*if (c == 0xaa) return (0);
        !           268:        if (c == 0xfa) return (0);*/
        !           269: 
        !           270:        if (bdt == 0) {  bdt = c&0x7f; return(0); }
        !           271: 
        !           272:        if(odt) return(1);
        !           273: 
        !           274:        c &= 0x7f;
        !           275:        
        !           276:        if (bdt == c) return(0);
        !           277:        odt = c;
        !           278: #endif
        !           279:        return 1;
        !           280: }
        !           281: 
        !           282: static void
        !           283: kbdreset(void) {
        !           284:        u_char c;
        !           285: 
        !           286:        /* Enable interrupts and keyboard controller */
        !           287:        while (inb(KBSTATP)&2); outb(KBSTATP,0x60);
        !           288:        while (inb(KBSTATP)&2); outb(KBDATAP,0x4D);
        !           289: 
        !           290:        /* Start keyboard stuff RESET */
        !           291:        while (inb(KBSTATP)&2); /* wait input ready */
        !           292:        outb(KBDATAP,0xFF);     /* RESET */
        !           293: 
        !           294:        while((c=inb(KBDATAP))!=0xFA) ;
        !           295: 
        !           296:        /* While we are here, defeat gatea20 */
        !           297:        while (inb(KBSTATP)&2); /* wait input ready */
        !           298:        outb(KBSTATP,0xd1);     
        !           299:        while (inb(KBSTATP)&2); /* wait input ready */
        !           300:        outb(KBDATAP,0xdf);     
        !           301:        while (inb(KBSTATP)&2); /* wait input ready */
        !           302:        inb(KBDATAP);
        !           303: }
        !           304: 
        !           305: /* TBD  - what does this do?, used by ResetCpu() */
        !           306: void
        !           307: KbdWait(int n) {
        !           308:        int v;
        !           309: 
        !           310:        v = 0;
        !           311:        while(n-- && (v = scankbd()) == 0);
        !           312:        if (v) kbdreset();
        !           313: }
        !           314: 
        !           315: /*
        !           316:  * Gate A20 for high memory
        !           317:  */
        !           318: u_char x_20 = KB_A20;
        !           319: 
        !           320: void
        !           321: gateA20(void) {
        !           322:   while (inb(K_STATUS) & K_IBUF_FUL);
        !           323:   while (inb(K_STATUS) & K_OBUF_FUL)
        !           324:     (void)inb(K_RDWR);
        !           325: 
        !           326:   outb(K_CMD, KC_CMD_WOUT);
        !           327:   while (inb(K_STATUS) & K_IBUF_FUL);
        !           328:   outb(K_RDWR, x_20);
        !           329:   while (inb(K_STATUS) & K_IBUF_FUL);
        !           330: }
        !           331: 
        !           332: int
        !           333: getc(void) {
        !           334: #ifdef USE_BIOS
        !           335:   int rslt;
        !           336:   asm("
        !           337:        push    %%ebx
        !           338:        call    _prot_to_real
        !           339:        movb    $0x0, %%ah
        !           340:        sti
        !           341:        int     $0x16
        !           342:        cli
        !           343:        movb    %%al, %%bl
        !           344:        .byte   0x66
        !           345:        call    _real_to_prot
        !           346:        xor     %%eax, %%eax
        !           347:        movb    %%bl, %0
        !           348:        pop     %%ebx
        !           349:        " : "=g" (rslt));
        !           350:   return rslt;
        !           351: #else
        !           352:   while (!is_chr_queued) {
        !           353:     ProcessKbdEvent();
        !           354:   }
        !           355:   is_chr_queued = 0;
        !           356:   return chr;
        !           357: #endif
        !           358: }
        !           359: 
        !           360: int
        !           361: getchar(void) {
        !           362:   int c;
        !           363: 
        !           364:   if ((c=getc()) == '\r')
        !           365:     c = '\n';
        !           366:   if (c == '\b') {
        !           367:     putchar('\b');
        !           368:     putchar(' ');
        !           369:   }
        !           370:   putchar(c);
        !           371:   return c;
        !           372: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.