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

📄 llcevt.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	ADD	DI,DX		;get byte offset in table
	AND	BYTE PTR[DI],0FDH ;disable the corr. key
				; carry is cleared
DISBL2:
	POP	DX		;restore [DX]
	RET			; with NC

	SUBTTL	B$KBDTRP - Keyboard interrupt / monitor loop
	PAGE
;***
;B$KBDTRP
;
;PURPOSE:
;	The keyboard interrupt handler first branches to
;	this routine to see if any of the following keys
;	were typed in that order:
;	1. The NUM_TKEYS trappable keys including the NUM_UKEYS user
;	   defined trap keys.
;	2. PRTSC key, LPT echo toggle key, Pause key
;	   or the Break key.
;	If any of the above keys were hit, B$KBDTRP sets
;	Event flag and the corresponding key flag and
;	returns.
;	If none of the above keys were hit then the
;	routine branches to the ROM keyboard interrupt
;	handler.
;
;ALGORITHM:
;	if (key typed is the LPTECHO key) then
;	   begin
;		set LPTFLG
;		set EVTFLG and KEYFLG
;	   end
;	If (key typed is a valid trap key for which
;	    trapping is enabled) then
;	   begin
;	      set the corr. TRAP key flag in the TRAPTABLE
;	      set the EVTFLG and KEYFLG
;	   end
;	else
;	     if (key typed is PAUSE key and CTRL PAUSE
;			trapping enabled) then
;		begin
;		  set PAUSE key flag
;		  set EVTFLG and KEYFLG
;		end
;	     else
;		if (key typed is BREAK key and CTRL BREAK
;			trapping enabled) then
;		      begin
;			set BREAK key flag
;			set EVTFLG and KEYFLG
;		      end
;	     else
;		continue with ROM keyboard interrupt
;		handler
;
;DATA STRUCTURE:
;	This routine also uses the TRAP TABLE data
;	structure described above in B$RDKYBD.
;
;ENTRY:
;	None
;
;EXIT:
;	Set the EVTFLG, KEYFLG and the corresponding key
;	flag if any of the enabled trap keys were typed.
;
;MODIFIED:
;	None
;
;***********************************************************************

dbpub	B$KBDTRP			
B$KBDTRP:					

	ENABLE			;enable further interrupts
	PUSH	AX
	PUSH	BX
	PUSH	CX
	PUSH	DS
	PUSH	DI
	PUSH	ES
	XOR	CX,CX
	MOV	DS,CX		;zero DS
	MOV	BX,KBDFLG	;set BX to special status flag's addr
	MOV	AH,BYTE PTR[BX] ;get the mask in AH
	CALL	B$GETDS
	MOV	DS,BX		;get the addr of basic data seg
	MOV	ES,BX		;make [ES] = [DS]
	IN	AL,KBDATA	;else get keyboard data in acc.
				; when enter here,
				;  [AX]=[shift status|scan code]
	MOV	KEYHIT,AX	; store the key hit
	CMP	AL,ScanExt1	; is extended scan code (E0H) ?
	JZ	SetExtFlg	; Brif yes
	CMP	AL,ScanExt2	; is extended scan code (E1H) ?
	JNZ	SetToggle	; Brif not
SetExtFlg:			
	MOV	WasE0E1,80H	; set extended scan code flag
	JMP	NONE		; let ROM handles it
SetToggle:			
	AND	AH,6FH		;throw away INS & SCROLL (80H & 10H)
				;and continue with the INT handler.
	OR	AH,WasE0E1	; or the flag for extended key
	MOV	WasE0E1,0	; reset extended scan code flag
	TEST	AH,3		; was either right or left shift ?
	JZ	NO_SHFT 	; Brif not
	OR	AH,3		; make them the same
NO_SHFT:

	TEST	b$EventFlags,InSLEEP ; in sleep statement?
	JZ	NoWakeup	; brif not -- nothing to wake up
	OR	AL,AL		; BREAK scan code?
	JS	NoWakeup	; brif so -- don't wake up SLEEP
	CALL	B$Wakeup	; key hit -- force SLEEP statement wakeup
NoWakeup:			

	CALL	CHKLPT		;check for CTRL PRTSC
	CMP	WASPOS,0	;Pause active ?
	JE	NOPAUS		;Brif not
	AND	AL,07FH 	;else strip bit 7
NOPAUS:
	CALL	B$CHKTRP	; check for trap keys
	JC	KBDRET		;Brif found
	CALL	OTHERS		;check for CTRL PAUSE and CTRL BRK
	JC	KBDRET		;Brif found
	JMP	NONE

KBDRET: 			

	MOV	KEYFLG,1	;set flag for key event
	CALL	B$TrapEvent	;set global event flag

	IN	AL,KBDATA+1	;get keyboard control port
	MOV	AH,AL		;save it in AH
	OR	AL,80H		;keyboard reset bit
	PAUSE			;make sure instruction fetch has occurred
	OUT	KBDATA+1,AL	;Ack so keyboard can Int again
	MOV	AL,AH		;get control bits back
	PAUSE			;make sure instruction fetch has occurred
	OUT	KBDATA+1,AL	;restore keyboard mode
	MOV	AL,EOI		;send End of Interrupt
	PAUSE			;make sure instruction fetch has occurred
	OUT	INTA0,AL	;to 8259
	STC			;carry since we processed char
ROMINT:
				;CF indicates whether we processed
				;character or not
	POP	ES
	POP	DI
	POP	DS
	POP	CX
	POP	BX
	POP	AX
	JC	REALRT
	INT	ROMKBD
REALRT:
	IRET

	SUBTTL
	PAGE
;**
;This routine checks for CTRL PRTSC
;and if CTRL PRTSC is down it sets LPTFLG
;and the event flags

CHKLPT:
	TEST	AH,CTRLDown	; CTRL down ?
	JZ	LPTRET		;Brif not
	CMP	AL,ScanPrtsc	; was it the PRTSC key ?
	JNE	LPTRET		;Brif not
	TEST	PPBEBL,04H	;PRTSC key trapping enabled ?
	JZ	LPTRET		;Brif not
	MOV	LPTFLG,1	;else set printer echo flag
	MOV	KEYFLG,1	;set flag for key event
	CALL	B$TrapEvent	;set the global event flag
LPTRET:
	RET


;**
;This routine checks for any of the
;NUM_TKEYS trappable keys and if found sets
;the trap flag for the corresponding key

dbpub	B$CHKTRP		
B$CHKTRP:			
	CMP	KEYTRP,1	;key trapping enabled ?
	JNE	NoTrap		;Brif not
				; check F11/F12, or F1-F10 & cursor movement
				;  keys, and then user defined keys
	XOR	CX,CX		; CX=0, in case it is F11
	CMP	AL,ScanF11	; is F11/F12
	JB	SetTbl1 	; Brif not
	MOV	BX,OFFSET DGROUP:TRTBL4 ; [BX]=offset of trap table 4
	JZ	IsTrapable	; Brif F11, TRAPPED need BX & CX
	DEC	CX		; CX=-1, TRAPPED need negative 0-relatived #
	CMP	AL,ScanF12	; is F12 ?
	JZ	IsTrapable	; Brif yes, TRAPPED need BX & CX
	JMP	SHORT UsrKeys	; search user defined keys
SetTbl1:			
	TEST	AH,80H		; is new set of cursor moving keys ?
	JNZ	UsrKeys 	; Brif yes
	MOV	DI,OFFSET DGROUP:TRTBL1 ; [DI]=offset of trap table 1
	MOV	CX,OrgFky+CsrMovKy	; [CX]=count of keys
	MOV	BX,OFFSET DGROUP:TRTBL2 ; [BX]=offset of trap table 2
	CLD			;just to be safe
	REPNZ	SCASB		;search for a trappable key
	JNZ	UsrKeys 	; Brif none found
	SUB	CX,OrgFky+CsrMovKy-1	; get negative 0-relative key
IsTrapable:			
	CALL	TRAPPED 	; trappable ?
	JC	SHORT TrpExit	; is a trapped key, return with CY
UsrKeys:			
	MOV	DI,OFFSET DGROUP:USRTBL1;[DI]=offset of user trap_table 1
	MOV	CX,NUM_UKEYS	; [CX]=count of keys
	MOV	BX,OFFSET DGROUP:USRTBL2;[BX]=offset of user trap_table 2
	CLD			; just to be safe
Loop2:
	REPNZ	SCASW		;search for a trappable key
	JNZ	NoTrap		; Brif none found
	SUB	CX,NUM_UKEYS-1	; get the negative 0-relative key #
	PUSH	BX		; save BX for next run, BX is needed by
				;  TRAPPED and is ruined in it
	CALL	TRAPPED 	; trappable ? on return CX=positive
				;  0-relative key #, CY indicate the key is
				;  trapable, ZR or NC indicate not trapable
	POP	BX		; get BX back
	JC	TrpExit 	; exit with carry set if found
	SUB	CX,NUM_UKEYS-1	; get back count in [CX]
	JCXZ	NoTrap		; if zero, then done, no trap key found
	NEG	CX
	JMP	SHORT Loop2	; look for other trappable keys
NoTrap:
	CLC			;CLC to indicate none found
TrpExit:			; exit
	RET

TRAPPED:			; this routine returns with
				; CF set if the key is trappable
				; else returns with Z flag set & NC
	NEG	CX		;number
	ADD	BX,CX		;get byte offset into table
	TEST	BYTE PTR[BX],TRP_VALID ; key valid?
	JZ	NOTFOUND	; Brif not -- return with carry clear
	TEST	BYTE PTR[BX],TRP_ENABLED ; key trapping enabled?
	JZ	NOTFOUND	; Brif not -- return with carry clear
	OR	BYTE PTR[BX],TRP_OCCURED ; else set the trap key flag
GotKeyBreak:			
	STC			;STC to indicate that a trappable
NOTFOUND:
	RET			;key was found
;**
;This routine checks for CTRL PAUSE and CTRL BRK
;in that order and if found returns with carry set
;else returns with carry clear.

OTHERS:
	TEST	AH,CTRLDown	; CTRL down ? (carry reset NC)
	JZ	NOTFND		;Brif not
	CMP	AL,ScanPause	; was it CTRL PAUSE ?
	JNE	BRKCHK		;Brif not
	TEST	AH,ALTDown	; was ALT also down ?
	JNZ	OTHRET		;EAT CTRL ALT PAUSE
	TEST	PPBEBL,02H	;PAUSE key trapping enabled ?
	JZ	BRKCHK		;Brif not
	CMP	WASPOS,0	;CTRL PAUSE active ?
	JZ	SETPOS		;Brif not (^S not active, so treat
				;this as ^S)
	JMP	SHORT OTHRET	;else just eat the character
SETPOS:
	MOV	POSFLG,1	;else set the PAUSE key flag
	JMP	SHORT OTHRET	;and return
BRKCHK:
	CMP	AL,ScanBreak	;was it CTRL BRK ?
	JNE	NOTFND		;Brif not
	CMP	b$NetCard,1	; network installed ?
	JNZ	NetNotFound	; brif not,
	TEST	AH,ALTDown	; alt key down ?
	JNZ	NOTFND		; brif so, without eating ctrl-alt-brk
NetNotFound:			
	TEST	AH,ALTDown	; was ALT also down ?
	JNZ	OTHRET		;EAT CTRL ALT BRK
	TEST	PPBEBL,01H	;BREAK key trapping enabled ?
	JZ	NOTFND		;Brif not
	CMP	WASPOS,0	;CTRL PAUSE active ?
	JZ	BRKCH1		;Brif not
	JMP	SHORT SETPOS	;else report this as ^S
BRKCH1:
	MOV	BRKFLG,1	;else set BREAK key flag
	CALL	B$IBreak	;notify interpreter of BREAK

OTHRET:
	STC			;indicates key found
	RET
NOTFND:
	CLC			;indicates key not found
	RET

;**
;Control branches here if no trappable key was
;hit. This routine lets all other keys to go
;through the ROM keyboard interrupt handler
;IF AND ONLY IF CTRL PAUSE is NOT active. If
;CTRL PAUSE is active then it reports that key as
;another CTRL PAUSE if it is NOT any of the SHIFT
;keys.

NONE:

	CMP	WASPOS,0	;CTRL PAUSE active ?
	JZ	NONE2		;Brif not
	CALL	SHKEYS		;else check for shift keys
	JC	NONE1		;Brif it is a shift key
	MOV	POSFLG,1	;else report it as CTRL PAUSE
	JMP	KBDRET		;set EVTFLG and return
NONE1:
	CMP	CX,3		; was it CTRL, LEFT-SHIFT or RIGHT-SHIFT?
	JBE	NONE2		; brif so -- let it go through
	JMP	KBDRET		;EAT ALL OTHER SHIFT KEYS
NONE2:				;comes here if CTRL PAUSE not
				;active and no trapping occured
	CLC			;clear carry
	MOV	AX,KEYHIT	; restore key hit
	JMP	ROMINT		;pass control to ROM INTERRUPT
				;i.e. pass the key to the input stream


;******************************************************
;SHKEYS is used to find out if the key hit
;is one of the following:
;	INS, CAPSLOCK, NUMLOCK, SCROLLLOCK, ALT,
;	CTRL, LEFTSHIFT, RIGHTSHIFT.
;	If the key hit is one of the above it returns
;	with carry set else returns with carry clear.
;	Also if it is the CTRL key it returns the
;	value 3 in [CX]. If PAUSE is active then typing
;	any of these keys will not release pause, and
;	except for CTRL all other shift keys are EATEN
;	by B$KBDTRP.
;******************************************************
SHKEYS:				; AL = scan code
	MOV	DI,OFFSET DGROUP:SHFTBL
	MOV	CX,9		;count of 8 keys
	CLD			;to be safe
	REPNZ	SCASB		;search for a shift key
	CLC			; clear carry
	JCXZ	SHKRET		; Brif none found
	STC
SHKRET:
	RET
	PAGE
;***
;B$HookKbd - Hook keyboard interrupt
;
;Purpose:
;	Added with revision [13].
;	The QB4 user interface needs to have control of the
;	keyboard interrupt when it is active to avoid conflicts
;	with TSR programs like SIDEKICK.  When the user interface
;	is exitting, it will deinstall it's handler and call
;	this routine so that the runtime can reinstall our keyboard
;	handler.
;Entry:
;	None.
;Exit:
;	None.
;Uses:
;	Per Convention.
;Exceptions:
;	None.
;******************************************************************************
cProc	B$HookKbd,<PUBLIC,FAR>
cBegin
	AND 	b$EventFlags,NOT KybdInst	; force re-installation of
						; keyboard interrupt handler
	XOR	AL,AL				; get current key status,
						; flush keystrokes, and
	CALL	B$RDKYBD			; hook int 9
cEnd
	PAGE
;***
;B$UnHookKbd - UnHook runtime keyboard interrupt
;
;Purpose:
;	The QB4 user interface needs to have control of the
;	keyboard interrupt when it is active to avoid conflicts
;	with TSR programs like SIDEKICK.  When the user interface
;	is entering, it will call this routine and the runtime will
;	unhook itself from the keyboard interrupt chain.  The user
;	interface will then install its keyboard handler.
;Entry:
;	None.
;Exit:
;	None.
;Uses:
;	Per Convention.
;Exceptions:
;	None.
;******************************************************************************
cProc	B$UnHookKbd,<PUBLIC,FAR>
cBegin
	XFRINT	KYBINT,KBDVEC/4 	;restore original INT 9 (saved in EF)
cEnd

;***
;B$InitKeys1 - Init some event stuff
;OEM-interface routine
;
;Purpose:
;	Init some event stuff.
;
;Entry:
;	AL = value to pass to B$RDKYBD when DX = Ctl_Creak
;
;Exit:
;	None.
;
;Uses:
;	Per Convention.
;
;Exceptions:
;	None.
;
;******************************************************************************
cProc	B$InitKeys1,<PUBLIC,NEAR>
cBegin
	MOV	[B$IPOLKEY],EV_TEXTOFFSET B$POLKEY 
	TEST	b$CtrlFlags,DSwitch ;has B$DBINI done this already?
	jnz	inidon		;brif so
	PUSH	AX		;save this value for later

	MOV	SI,EV_TEXTOFFSET B$RDKYBD ;stick in reg to make

	mov	al,enable_trap		  ;  code smaller & faster
	mov	dx,printer_echo ;enable the printer echo
	call	si

	mov	dx,pause_key	;enable pause key
	call	si

	POP	AX		;retrieve input value
	mov	dx,Ctl_Break	;en/disable ^Break trapping (depending on AL)
	call	si

	mov	al,start_key	;start key trapping
	call	si

inidon:
cEnd				

	SUBTTL	Keyboard Interrupt/Trap Checking in an Operating System Environment
	PAGE

;***
;B$POLKEY -
;OEM-interface Routine
;
;Purpose:
;	Process keys trapped by the OEM/machine dependent keytrapping
;	support.
;	Algorithm:
;
;	Set b$CntlC to 0
;	Call OEM routine B$RDKYBD to detect if a key event has occurred.
;	If trapped key then
;		report to KEYTRP
;	If ^C then
;		Set b$CntlC to 1
;	If ^S then
;		toggle the ^S flag
;	If <printer-echo>
;		toggle the printer echo flag
;	Loop to call B$RDKYBD until no more key events are reported.
;	If ^S flag is set then
;		loop to call B$RDKYBD until another ^S event is detected.
;Entry:
;	none
;
;Exit:
;	none
;
;Uses:
;	none
;
;Exceptions:
;	none
;
;****

cProc	B$POLKEY,<PUBLIC,NEAR>,<AX,BX>
cBegin				; - this routine was completely
				; rewritten - mostly taken from
				; the interpreter
Pollop:
	xor	ax,ax		;Read trapped keys function code
	call	B$RDKYBD	;OEM dependent key trap routine
	dec	bx
	jns	Waskey		;Function, arrow, or user def. key trapped
	inc	bx
	jz	Polkyx		;No key was trapped
	inc	bx
	jz	Wasctc		;^C / <break> function
	inc	bx
	jz	Wascts		;^S / <pause> function
	inc	bx
	jnz	Pollop		;Not <print-screen> func. - ignore, poll next

Wasctp: 			;<printer echo> function
	XOR	b$IOFLAG,LPR_ECHO ; Toggle the printer echo flag
	jmp	short Pollop	;Key found, so there may be more

Waskey:
	; Trap zero relative key if event is ON
	xchg	ax,bx		
	ADD	AL,KEYOFF	; [AL] = 0-relative event id
	CALL	B$TestTrap	
	JZ	Pollop		
	CALL	B$ReqTrap	    ; Trap enabled, Issue Request
	jmp	short Pollop	; Key found, so there may be more

Wascts: 			;^S / <pause> function
	XOR	b$EventFLags,PAUSEF ; Toggle the pause flag
	jmp	short Pollop	;Key found, so there may be more

Wasctc: 			;flag ^Break found
	OR	b$EventFlags,CNTLC ; ^Break is reported last so
	AND	b$EventFlags,NOT PAUSEF ; turn off pause and exit

Polkyx:
	TEST	b$EventFlags,PAUSEF ; Test for pause processing
	jnz	Pollop		;Pause in process, wait for "unpause"
cEnd
sEnd	EV_TEXT 		
	END

⌨️ 快捷键说明

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