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

📄 kbd.8

📁 tiny bios--了解BIOS非常好的资料
💻 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 + -