⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kbd.8

📁 PC x386 bios source code
💻 8
📖 第 1 页 / 共 2 页
字号:
        test    byte [m_kbf3],kb_fe0    ;E0 prefix ?
        jz      i5a     ;:no
        and     al,255-kb_flsh-kb_frsh  ;extended key - force unshifted scan
        jmp     short i7
i5a:    test    al,kb_fnums
        jz      i7      ;:not set
i6:     xor     al,kb_flsh+kb_frsh      ;toggle shift
i7:     and     ax,15
        mov     bx,offset shftab        ;shift state
        cs:     xlat
        xchg    bx,ax   ;-> entry offset
        mov     ax,[cs:bx+si]   ;get scan/action code
        cmp     ax,vecmin
        jb      ikey    ;:scan code
        not     ax      ;action key: convert to jump vector
        shl     ax,1
        xchg    bx,ax

        ; Dispatch special keys.

        mov     bx,[cs:bx+vectab]       ;get vector of special key handler
        call    bx      ;call special key handler
iact2:  jmp     short i11       ;done

overrun1:       jmp     short overrun

ikey:   and     cl,cl   ;is it break ?
        js      i11     ;yes: ignore

        test    byte [m_kbf3],kb_fe0    ;E0 prefix ?
        jz      ikey9   ;:no
        test    al,al
        jnz     ikey4

        cmp     ah,96h  ;Ctrl * -> Ctrl PrtSc
        jnz     ikey1
        mov     ah,72h
        jmp     short ikey9

ikey1:  cmp     ah,1ch  ;Alt keypad enter -> A600
        jnz     ikey2
        mov     ah,0a6h

ikey2:  cmp     ah,35h  ;Alt keypad -> A400
        jnz     ikey3
        mov     ah,0a4h

ikey3:  cmp     ah,84h  ;high extended keys -> no change
        jae     ikey9
        mov     al,0e0h ;remember this was a extended key
        jmp     short ikey9

ikey4:  cmp     ah,1ch  ;keypad enter ?
        jz      ikey8
        cmp     ah,35h  ;keypad / ?
        jnz     ikey9
ikey8:  mov     ah,0e0h ;extended key, translated back by
                        ;kb_xlat
ikey9:  call    putbuf  ;put scan code in buffer
        jnb     i11     ;:ok
overrun:        cli
        mov     al,eoi  ;reset interrupt controller
        out     pic0,al
        call    beep
        jmp     short done2
i11:
i12:    and     byte [m_kbf3],255-kb_fe0-kb_fe1 ;reset prefix flag

#if ! def       XTKBD           ;if AT

        cli
        mov     al,eoi  ;reset interrupt controller
        out     pic0,al
        call    enakbd
        jmp     short done3
#endif

done:   cli
        mov     al,eoi  ;reset interrupt controller
        out     pic0,al
done2 :

#if ! def       XTKBD
        call    enakbd
#endif

done3:  pop     es
        pop     ds
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        iret
        ;
        ; INT 16 entry
        ;
int16:  sti             ;enable interrupts
        push    bx
        push    cx
        push    dx
        push    ds

        xor     dx,dx   ;access BIOS segment
        mov     ds,dx
        add     dl,ah   ;command code
        jz      kb_get  ;AH=00: get key
        dec     dx
        jz      kb_check        ;AH=01: check if key available
        dec     dx
        jz      kb_shift        ;AH=02: return shift status
        dec     dx
        jz      kb_rate ;AH=03: set repetition rate
        dec     dx
        dec     dx
        jz      kb_write        ;AH=05: place scan code in buffer
        sub     dl,11
        jz      kb_extrd        ;AH=10: extended read
        dec     dx
        jz      kb_extst        ;AH=11: extended status
        dec     dx
        jz      kb_extsh        ;AH=12: extended shift status
kb_exit:        pop     ds
        pop     dx
        pop     cx
        pop     bx
        iret
        ;
        ; AH=00: get key from buffer
        ;
kb_get: call    kb_getch        ;get character from buffer
        call    kb_xlat ;translate extended characters
        jb      kb_get  ;:extended character, try again
        jmp     kb_exit
        ;
        ; AH=01: check if key available
        ;
kb_check0: call kb_getch        ;skip extended character
kb_check:       call    kb_chk  ;check for character
        jz      kb_exitst       ;:nothing available
        call    kb_xlat ;check if extended character
        jb      kb_check0       ;:extended character, skip
kb_extst2: inc  dx      ;clear Z flag
kb_exitst: pop  ds      ;exit, flags modified
        pop     dx
        pop     cx
        pop     bx
        retf    2
        ;
        ; AH=10: extended read
        ;
kb_extrd:       call    kb_getch        ;get character
        call    kb_exlat        ;convert extended codes
        jmp     kb_exit
        ;
        ; AH=11: extended status
        ;
kb_extst:       call    kb_chk  ;check status
        jz      kb_exitst       ;:nothing, return Z flag
        call    kb_exlat
        jmp     kb_extst2       ;return result
        ;
        ; AH=12: extended shift status
        ;
kb_extsh:       xor     ah,ah
        mov     al,[m_kbf1]     ;system request shift
        test    al,kb_fsys      ;system request ?
        jz      kb_extsh2
        mov     ah,80h  ;yes: set bit 7
kb_extsh2: and  al,01110011xb
        or      ah,al
        mov     al,[m_kbf3]     ;right control and alt keys
        and     al,00001100xb
        or      ah,al
        ;
        ; AH=02: return current shift status
        ;
kb_shift:       mov     al,[m_kbf]      ;get shift status
        jmp     kb_exit
        ;
        ; AH=03: set key repetition rate
        ;
kb_rate:        cmp     al,5    ;correct command ?
        jnz     kb_exit
        cmp     bl,31   ;test rate
        ja      kb_exit
        cmp     bh,3    ;test delay
        ja      kb_exit
        push    ax      ;save AX
        shl     bh,5
        mov     al,0f3h ;set repeat rate / delay command
        call    kb_send ;send to keyboard
        mov     al,bl   ;combine delay, rate
        add     al,bh
        call    kb_send
        pop     ax      ;restore AX
        jmp     kb_exit
        ;
        ; AH=05: place scan code in buffer
        ;
kb_write:       mov     al,1    ;error status
        cli             ;prevent conflict
        mov     bx,[m_kbtail]   ;^kb buffer
        inc     bx      ;increment
        inc     bx
        cmp     bx,[m_kbend]    ;at end ?
        jnz     kb_write2
          mov   bx,[m_kbstart]  ;yes: go to start
kb_write2: cmp  bx,[m_kbhead]   ;buffer full ?
        jz      kb_write3       ;:yes
        xchg    bx,[m_kbtail]   ;update tail, get old value
        dec     ax      ;clear AL
        mov     [bx+bofs],cx    ;store scan code
kb_write3: sti          ;end of critical section
        jmp     kb_exit
        ;
        ; get scan code from buffer
        ;
kb_getch0: sti          ;reenable interrupts
        hlt             ;wait for next event
kb_getch:       cli             ;critical section
        mov     bx,[m_kbhead]   ;^head of buffer
        cmp     bx,[m_kbtail]   ;= tail of buffer ?
        jz      kb_getch0       ;yes: wait
        mov     ax,[bx+bofs]    ;get scan code
        inc     bx      ;increment pointer
        inc     bx
        cmp     bx,[m_kbend]    ;at end ?
        jnz     kb_getch2
          mov   bx,[m_kbstart]  ;yes: go to start
kb_getch2: mov  [m_kbhead],bx   ;update pointer
        sti             ;end of critical section
        ret
        ;
        ; check if there is anything in buffer (Z set if not)
        ;
kb_chk: cli             ;critical section
        mov     bx,[m_kbhead]   ;^head of buffer
        cmp     bx,[m_kbtail]   ;= tail of buffer ?
        sti             ;end of critical section
        mov     ax,[bx+bofs]    ;get scan code
        ret
        ;
        ; check if extended character, set C if yes
        ;
kb_xlat:        cmp     ah,84h  ;extended ?
        jbe     kb_xlat83
        cmp     ah,0e0h
        jnz     kb_stc1 ;:bad
        mov     ah,1ch  ;keypad Enter fixed code
        cmp     al,13   ;keypad Enter ?
        jz      kb_xlatok       ;:yes
        cmp     al,10   ;keypad ^Enter
        jz      kb_xlatok       ;:yes
        mov     ah,35h  ;keypad /
        jmp     short kb_xlatok

kb_xlat83: cmp  ax,00e0h        ;extension ?
        jz      kb_xlatok
        cmp     ax,00f0h
        jz      kb_xlatok
        cmp     al,0f0h ;fill-in ?
        jz      kb_stc1
        cmp     al,0e0h
        jnz     kb_xlatok
        mov     al,0
kb_xlatok: clc          ;ok to use
        ret

kb_stc1:        stc             ;extended code - bad
        ret
        ;
        ; translate extended characters
        ;
kb_exlat:       cmp     al,0f0h ;special ?
        jnz     kb_exlat2
        or      ah,ah   ;0: more special
        jz      kb_exlat2
        mov     al,0
kb_exlat2: ret
        ;
        ; initialize keyboard controller
        ;
kb_ini:

#if ! def       XTKBD

#if def NO_KBC          ;bail quickly if no KBC present
        in      al,kb_stat      ;check status
        cmp     al,0ffh ;nothing ?
        jnz     kb_ini0
        mov     byte [tmp_kbc],0ffh     ;set flag - KBC not present
        stc
        ret
kb_ini0:
#endif
        xor     cx,cx
kb_ini1:        in      al,kb_stat      ;check status
        mov     bl,al
        and     al,1    ;buffer full ?
        jz      kb_ini2
        in      al,kb_dat       ;flush data
kb_ini2:        and     bl,2
        jz      kb_ini3 ;:empty
        loop    kb_ini1
kb_ini9:        stc             ;error
        ret

kb_ini3:        mov     al,0aah ;self test command
        call    kb_cmd
        jb      kb_ini9 ;:timeout
        call    kb_read ;wait for data
        jb      kb_ini9
        cmp     al,55h  ;expect $55 response
        jnz     kb_ini9

        mov     al,0abh ;test interface
        call    kb_cmd
        jb      kb_ini9 ;:timeout
        call    kb_read ;wait for data
        jb      kb_ini9
        cmp     al,0    ;expect 0 response
        jnz     kb_ini9

        mov     al,60h  ;write mode register
        call    kb_cmd
        jb      kb_ini9
        mov     al,6dh  ;initial mode (keep system flag off,
                        ;disable mouse interface)
        call    kb_writ
        jb      kb_ini9

#else   ;XT keyboard

        in      al,port61
        out     iowait,ax
        or      al,0c0h ;set reset bit
        out     port61,al
        out     iowait,ax
        and     al,7fh  ;clear reset bit
        out     port61,al
#endif
kb_clc1:        clc             ;ok
        ret
        ;
        ; send keyboard command AL
        ;
kb_cmd: out     kb_stat,al      ;send command
kb_cmd1:        out     iowait,ax
        ;
        ; wait until input (to 8042) buffer empty, C if timeout
        ;
kb_ibf: xor     cx,cx
kb_ibf2:        out     iowait,ax
        in      al,kb_stat
        and     al,2    ;input buffer full ?
        jz      kb_clc1 ;:ok return
        loop    kb_ibf2
        stc
        ret
        ;
        ; send keyboard data AL
        ;
kb_writ:        out     kb_dat,al
        jmp     kb_cmd1
        ;
        ; wait until output (from 8042) buffer full, read data -> AL
        ;
kb_read:        xor     cx,cx
kb_obf2:        out     iowait,ax
        in      al,kb_stat
        and     al,1    ;output buffer full ?
        jnz     kb_obf3
        loop    kb_obf2
        stc
        ret

kb_obf3:        in      al,kb_dat
        clc
        ret
        ;
        ; second keyboard initialization (after base memory test)
        ;
kb_inb:

#if def NO_KBC          ;skip if no KBC present
        ror     byte [tmp_kbc],1
        jb      kb_inb9
#endif

        call    kb_ibf  ;wait for 8042 ready

        in      al,kb_stat      ;anything in 8042 output buffer ?
        and     al,1
        jz      kb_inb2 ;:no
        in      al,kb_dat
        mov     [tmp_kbd],al    ;save keyboard response
        cmp     al,0aah ;keyboard test ok ?
        jz      kb_inb9 ;:yes, don't reset again

kb_inb2:        mov     al,0ffh ;reset keyboard
        out     kb_dat,al
        call    kb_read ;get acknowledge

kb_inb9:        mov     byte [m_kbf],kb_fnums   ;set Numlock
        mov     byte [m_kbf3],kb_fkbx   ;assume enhanced keyboard
        mov     ax,m_kbbuf-bofs ;initialize keyboard buffer pointers
        mov     [m_kbstart],ax
        mov     [m_kbhead],ax
        mov     [m_kbtail],ax
        mov     word [m_kbend],m_kbbuf9-bofs
        ret
        ;
        ; third keyboard initialization (after extended memory test)
        ;
kb_inc:
#if def NO_KBC          ;skip if no KBC present
        ror     byte [tmp_kbc],1
        jnb     kb_inc1
        ret
kb_inc1:
#endif
        cmp     byte [tmp_kbd],0aah     ;keyboard reset ok ?
        jz      kb_inc2 ;:yes
        call    kb_read ;wait until data in buffer
        jb      kb_err
        cmp     al,0aah ;AA = keyboard response
        jz      kb_inc2 ;:ok
kb_err:
;       jb      kb_err2 ;&
;       call    hexbyt  ;&
;kb_err2:                       ;&
        inc     byte [tmp_kbfail]
#if ! def       NO_KBC
        mov     si,offset msg_kbd       ;"Keyboard failure"
        call    v_msg
#endif
kb_inc2:        call    kb_ibf  ;wait for 8042 ready
        mov     al,0f4h ;enable keyboard
        out     kb_dat,al
        jmp     kb_read ;get acknowledge
        ;
        ; set keyboard LEDs, enable keyboard
        ;
kb_ind:
#if def NO_KBC          ;skip if no KBC present
        ror     byte [tmp_kbc],1
        jnb     kb_ind1
        ret
kb_ind1:
#endif

#if def KEY_RATE
        mov     ax,0305h        ;set keyboard repeat rate
        mov     bx,KEY_RATE
        int     16h
#endif

        call    disakbd ;disable keyboard interface

#if def LED_UPDATE
        mov     dx,iowait
        call    setleds ;set keyboard LEDs
#endif
        ;-> fall through
        ;
        ; enable AT kbd
        ;
enakbd:         cli
        call    waitkbd
        mov     al,0aeh
        out     kb_stat,al
        sti
        ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -