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

📄 kbd.8

📁 tiny bios--了解BIOS非常好的资料
💻 8
📖 第 1 页 / 共 2 页
字号:
	;
	; Keyboard BIOS
	;
	; (C)1997-2001 Pascal Dornier / PC Engines; All rights reserved.
	; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
	;
	; Limitations:
	;
	; - Doesn't call INT15 on key wait, system request key
	; - Screen dump is called, but not implemented by BIOS. This function
	;   considered risky for embedded systems, and is also highly
	;   printer specific. Recommend implementation as TSR if required.
	; - We currently don't detect whether the keyboard is enhanced
	;   (101 key) or not. Most keyboards are, so we set the status bit
	;   kb_fkbx.
	;
	; Note:
	;
	; - If interrupt latency is critical, recommend disabling keyboard
	;   LED updates -> comment out option LED_UPDATE.
	;

	;
	; Flag bit definitions
	;

	; m_kbf bits
	
kb_frsh	equ	01h	;right shift pressed
kb_flsh	equ	02h	;left shift pressed
kb_fcsh	equ	04h	;control pressed
kb_fash	equ	08h	;alt pressed
kb_fscrs	equ	10h	;scroll lock active
kb_fnums	equ	20h	;num lock active
kb_fcaps	equ	40h	;caps lock active
kb_finss	equ	80h	;ins active

	; m_kbf1 bits
	
kb_flct	equ	01h	;left control pressed
kb_flal	equ	02h	;left alt pressed
kb_fsys	equ	04h	;system key pressed
kb_fhld	equ	08h	;hold active
kb_fscr	equ	10h	;scroll lock pressed
kb_fnum	equ	20h	;num lock pressed
kb_fcap	equ	40h	;caps lock pressed
kb_fins	equ	80h	;ins key pressed

	; m_kbf2 bits

kb_fled	equ	07h	;led mask
kb_fscrl	equ	01h	;scroll lock led
kb_fnuml	equ	02h	;num lock led
kb_fcapl	equ	04h	;caps lock led
kb_fack	equ	10h	;kbd ACK received
kb_fres	equ	20h	;kbd RESEND received
kb_fcled	equ	40h	;led update
kb_ferr	equ	80h	;kbd transmit error
	
	; m_kbf3 bits

kb_fe1	equ	01h	;e1 prefix was last
kb_fe0	equ	02h	;e0 prefix was last
kb_frct	equ	04h	;right control pressed
kb_fral	equ	08h	;right alt pressed
kb_fkbx	equ	10h	;enhanced kbd installed
kb_fnumf	equ	20h	;force num lock if kbx
kb_fab	equ	40h	;ab read ID was last
kb_fid	equ	80h	;doing a read ID
	;
	; put keystroke in buffer
	;
putbuf: 	mov 	si,[m_kbtail]
 	mov 	di,si
 	inc 	si
 	inc 	si
 	cmp 	si,[m_kbend]	;end of buffer ?
 	jnz 	pb1	;:no
 	mov 	si,[m_kbstart]	;:restart at beg
pb1: 	cmp 	si,[m_kbhead]	;buffer full ?
 	jz 	pbovr	;:overrun;:yes
 	mov 	[di.bofs],ax	;store keystroke
 	mov 	[m_kbtail],si
 	clc		;ok
 	ret
pbovr: 	stc		;overrun: return error
 	ret
	;
	; wait for AT kbd
	;
waitkbd: 	push 	cx
 	xor 	cx,cx	;timeout
wk1: 	out	iowait,ax
	in 	al,kb_stat	;read status port
 	test 	al,2	;input buffer full ?
 	loopnz 	wk1	;:yes
 	pop 	cx
 	ret
	;
	; disable AT kbd
	;
disakbd: 	cli
 	call 	waitkbd
 	mov 	al,0adh	;disable
 	out 	kb_stat,al
 	sti
 	ret
	;
	; send command to AT kbd
	;
kb_send: 	push 	ax	;save
 	push 	cx
 	mov 	ah,3	;3 retries
sk1: 	cli
 	and 	byte [m_kbf2],kb_fled+kb_fcled+8	;clear error bits
 	push 	ax
 	call 	waitkbd
 	pop 	ax
 	out 	kb_dat,al	;store command
 	sti
 	mov 	cx,2000h	;wait
sk2: 	test 	byte [m_kbf2],kb_fack+kb_fres
 	jnz 	sk4	;:response
 	out	iowait,ax
 	loop 	sk2	;wait
sk3: 	dec 	ah
 	jnz 	sk1	;:another retry
 	or 	byte [m_kbf2],kb_ferr	;set error bit
 	jmp 	short sk9	;done

sk4: 	test 	byte [m_kbf2],kb_fres	;resend flag ?
 	jnz 	sk3	;:retry
sk9: 	cli
 	pop 	cx
 	pop 	ax
 	ret
	;
	; read char from kbd
	;
readchar:
#if ! def	XTKBD

 	call 	disakbd
 	cli
 	call 	waitkbd
 	in 	al,kb_dat	;read scan code
 	sti
 	cmp 	al,0feh	;resend ?
 	jz 	rch3	;:yes
 	cmp 	al,0fah	;ack ?
 	jnz 	setled	;:no
 	mov 	al,kb_fack
 	jmp 	short rch4

rch3: 	mov 	al,kb_fres
rch4: 	cli
 	or 	byte [m_kbf2],al
 	pop 	bx
 	jmp 	done

setled:

#if def	LED_UPDATE
	cli
	push	dx
	mov	dx,pic0
	call	setleds	;set mode LEDs
	pop	dx
#endif
 	sti
 	ret

#else	;XT keyboard

 	in 	al,kb_dat	;read char
 	xchg 	bx,ax
 	in 	al,port61	;restore kbd
 	mov 	ah,al
 	or 	al,80h
 	out 	port61,al
 	mov 	al,ah
 	out 	port61,al
 	xchg 	bx,ax	;scan code -> AL
 	ret
#endif

#if def	LED_UPDATE
	;
	; update LEDs
	;
setleds:	push	ax
 	mov 	ah,[m_kbf]	;current mode flags
 	rol	ah,4	;-> low bits
 	mov 	al,[m_kbf2]	;current LED status
 	and	ax,0707h	;LED bits only
 	cmp 	ah,al	;same ?
 	jz 	setled9	;:done
 	test 	byte [m_kbf2],kb_fcled	;led update pending ?
 	jnz 	setled9	;:yes, don't reenter
 	or 	byte [m_kbf2],kb_fcled	;set update flag
 	mov 	al,eoi	;reset interrupt controller
	out 	dx,al	;(or iowait, depending on DX)
 	mov 	al,0edh	;set mode indicators
 	call 	kb_send	;send kbd command
 	test 	byte [m_kbf2],kb_ferr	;transmit error ?
 	jnz 	setled8	;:yes
 	mov 	al,ah	;send mode
 	call 	kb_send
 	test 	byte [m_kbf2],kb_ferr	;transmit error ?
 	jnz 	setled8	;:yes
 	and 	byte [m_kbf2],255-kb_fled	;set new state
 	or 	[m_kbf2],ah
setled8: 	and 	byte [m_kbf2],3fh	;reset update flag
setled9:	pop	ax
	ret
#endif
	;
	; invalid key: ignore
	;
kinval: 	ret
	;
	; left shift
	;
kshlt: 	mov 	al,kb_flsh
kshlt1: 	test	byte [m_kbf3],kb_fe0	;did we get E0 prefix ?
	jnz	kshlt2	;yes: ignore (extended key)
	or 	[m_kbf],al	;set flag
 	and 	cl,cl	;break ?
 	jns 	kshlt2
 	xor 	[m_kbf],al	;:clear flag
kshlt2: 	ret
	;
	; right shift
	;
kshrt: 	mov 	al,kb_frsh
 	jmp 	kshlt1
	;
	; left control
	;
kctlt: 	or 	byte [m_kbf1],kb_flct	;set flag
 	and 	cl,cl	;break ?
 	jns 	kctlt1
 	xor 	byte [m_kbf1],kb_flct	;:clear flag
kctlt1: 	or 	byte [m_kbf],kb_fcsh	;set left & right flag
 	test 	byte [m_kbf1],kb_flct
 	jnz 	kctlt2 	;:ok
 	test 	byte [m_kbf3],kb_frct
 	jnz 	kctlt2	;:ok
 	xor 	byte [m_kbf],kb_fcsh	;clear control flag
 	ret
kctlt2: 	pop 	ax	;don't clear hold flag
 	jmp 	i12
	;
	; right control
	;
kctrt: 	test 	byte [m_kbf3],kb_fe0+kb_fe1	;no E0/E1: caps lock
 	jz 	kcaps
kctrt1: 	or 	byte [m_kbf3],kb_frct	;set flag
 	and 	cl,cl	;break ?
 	jns 	kctlt1
 	xor 	byte [m_kbf3],kb_frct	;:clear flag
 	jmp 	kctlt1
	;
	; left alt
	;
kallt: 	test 	byte [m_kbf3],kb_fe0	;E0: right alt
 	jnz 	kalrt
 	or 	byte [m_kbf1],kb_flal	;set flag
 	and 	cl,cl	;break ?
 	jns 	kallt1
 	xor 	byte [m_kbf1],kb_flal	;:clear flag
kallt1: 	or 	byte [m_kbf],kb_fash	;set left & right flag
 	test 	byte [m_kbf1],kb_flal
 	jnz 	kallt2	;:ok
 	test 	byte [m_kbf3],kb_fral
 	jnz 	kallt2	;:ok
 	xor 	byte [m_kbf],kb_fash	;clear alt flag
 	xor 	ax,ax	;any char entered via alt ?
 	xchg 	al,[m_kbnum]
 	and 	al,al
 	jz 	kallt2	;:no
 	call 	putbuf	;put it in buffer
kallt2: 	ret
	;
	; right alt
	;
kalrt: 	or 	byte [m_kbf3],kb_fral	;set flag
 	and 	cl,cl	;break ?
 	jns 	kallt1
 	xor 	byte [m_kbf3],kb_fral	;:clear flag
 	jmp 	kallt1
	;
	; handle toggle keys &pd fixed autorepeat 980115
	;
kcaps:	mov	ch,kb_fcaps	;caps lock
	jmp	short ktog
kscrl:	mov	ch,kb_fscrs	;scroll lock
	jmp	short ktog
knums:	mov	ch,kb_fnums
ktog:	and	cl,cl	;break ?
	jns	knums2	;:no
	not	ch	;clear key pressed flag
	and	[m_kbf1],ch
knums1:	ret

knums2:	test	[m_kbf1],ch	;already pressed ?
	jnz	knums3	;:don't toggle again
	xor	[m_kbf],ch	;toggle numlock flag
knums3:	or	[m_kbf1],ch	;set pressed flag
 	ret
	;
	; pause
	;
kpaus: 	and	cl,cl	;break ?
	js	knums1	;:ignore
	test	byte [m_kbf1],kb_fhld	;in hold mode ?
	jnz	knums1	;:yes -> ret
 	or 	byte [m_kbf1],kb_fhld	;set hold flag
 	mov 	al,eoi	;reset interrupt controller
 	out 	pic0,al
 	call	enakbd	;enable keyboard
kpaus1: 	sti		;wait for next event
	hlt
	test 	byte [m_kbf1],kb_fhld	;still on ?
 	jnz 	kpaus1	;yes: hold
 	pop 	ax	;remove return address
 	jmp 	done2	;exit
	;
	; print screen
	;
kprts: 	and	cl,cl
	js	knums1	;:ignore break
	cli
 	mov 	al,eoi	;reset interrupt controller
 	out 	pic0,al
 	int 	5	;do screen dump
 	pop 	ax	;remove return address
 	jmp 	done2	;return
	;
	; reboot system
	;
kboot: 	mov 	word [m_rstflg],1234h	;set cookie
 	jmp	far 0f000h:0fff0h	;reset jump
	;
	; system request
	;
ksysr: 	mov 	al,eoi	;reset interrupt controller
 	out 	pic0,al
 	mov 	ax,8500h
 	and 	cl,cl
 	jns 	ksysr1	;:make
 	inc 	ax	;break code
ksysr1:	int 	15h	;sys req interrupt
 	pop 	ax	;remove return address
 	jmp 	done2	;exit
	;
	; break
	;
kbrk:	and	cl,cl	;ignore key release
	js	knums1
	or 	byte [m_brkflg],128	;set break flag
 	mov 	ax,[m_kbstart]	;clear kbd buffer
 	mov 	[m_kbhead],ax
 	mov 	[m_kbtail],ax
 	int 	1bh	;break interrupt
 	xor 	ax,ax
 	jmp 	putbuf	;put break char
	;
	; alt + digit
	;
kdigtab: 	db 	7,8,9,0,4,5,6,0,1,2,3,0

kdig: 	and	cl,cl	;ignore break
	js	kdig1
	test 	byte [m_kbf3],kb_fe0	;E0 prefix ?
	jnz	kdig2	;yes: cursor keys, not Alt-number
	mov 	al,cl
 	mov 	bx,offset kdigtab-47h
 	cs: 	xlat
 	mov 	ch,al
 	mov 	al,[m_kbnum]	;old value * 10
 	mov 	ah,10
 	mul 	ah
 	add 	al,ch	;add digit
 	mov 	[m_kbnum],al
kdig1: 	ret
 	
kdig2:	mov	ah,cl	;handle Alt-cursor keys
	add	ah,50h
	mov	al,0
	jmp	putbuf
	;
	; action vector table
	;
vectab: 	dw	kinval	;FFFF = ignore key
 	dw 	kshlt 	;FFFE = left shift
 	dw 	kshrt 	;FFFD = right shift
 	dw 	kctlt 	;FFFC = left control
 	dw 	kctrt 	;FFFB = right control
 	dw 	kallt 	;FFFA = left alt
 	dw 	kalrt 	;FFF9 = right alt
 	dw 	kcaps 	;FFF8 = caps lock
 	dw 	knums 	;FFF7 = num lock
 	dw 	kscrl 	;FFF6 = scroll lock
 	dw 	kpaus 	;FFF5 = pause
 	dw 	kprts 	;FFF4 = print screen
 	dw 	kboot 	;FFF3 = reboot system
 	dw 	ksysr 	;FFF2 = system request
 	dw 	kbrk 	;FFF1 = break
 	dw 	kctrt1 	;FFF0 = right control
 	dw 	kdig 	;FFEF = alt + digit
	;
	; shift offset table
	;
shftab: 	db 	1,3,3,3,5,5,5,5,7,7,7,7,9,9,9,9
	;
	; kbd interrupt routine
	;
irq1: 	sti		;enable interrupt
 	push 	ax	;save registers
	push 	bx
 	push 	cx
 	push 	dx
 	push 	si
 	push 	di
 	push 	ds
 	push 	es
 	cld		;forward direction
 	xor	ax,ax	;BIOS segment
 	mov 	ds,ax
 	call 	readchar
 	stc		;give TSRs an opportunity to grap
 	mov	ah,4fh	;this key: call Int15 AH=4F
 	int	15h
 	jb	irq1a	;:not taken
 	jmp	i11	;skip this key
 	
irq1a: 	mov 	cl,al	;copy scan code
	cmp 	al,0e0h	;prefix code ?
 	jnz 	i1
 	or 	byte [m_kbf3],kb_fe0	;set prefix flag
 	jmp 	done
 	
i1: 	cmp 	al,0e1h	;prefix code ?
 	jnz 	i2
 	or 	byte [m_kbf3],kb_fe1	;set prefix flag
 	jmp 	done
 	
i2: 	cmp 	al,0ffh	;overrun ?
	jnz	i2a	;:no
 	jmp 	overrun
 	
i2a: 	test 	byte [m_kbf1],kb_fhld	;hold mode ?
 	jz 	i3	;:no
 	and 	cl,cl	;make code ?
 	js 	i3	;no - break
 	xor 	byte [m_kbf1],kb_fhld	;clear hold mode
i3: 	and 	al,127	;make = break
 	jz	overrun1	;zero: ignore
 	cmp 	al,maxscan	;too high ?
 	ja 	overrun1	;yes: ignore char
 	mov	ah,11	;11 bytes per key entry
 	mul	ah
 	add	ax,offset kb_tab-11	;add offset of key table
 	mov	si,ax
 	mov 	ah,[cs:si]	;get control byte
 	mov 	al,[m_kbf]	;get shift flag
 	test 	al,kb_flsh+kb_frsh	;shift set ?
 	jz 	i4	;:no
 	or 	al,kb_flsh+kb_frsh	;set both bits
i4: 	shr 	ah,1	;caps lock ?
 	jnb 	i5	;:no
 	test 	al,kb_fcaps
 	jnz 	i6	;:set
i5: 	shr 	ah,1	;num lock ?
 	jnb 	i7	;:no

⌨️ 快捷键说明

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