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

📄 llcevt.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	LLCEVT - Core GW-BASIC Event Interface
	PAGE	56,132
;***
; LLCEVT - Core GW-BASIC Event Interface
;
;	Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
;	This module has the CORE EVENT support routines:
;
;	1. B$RDKYBD
;	2. B$KBDTRP....This is the keyboard interrupt handler. All keys
;			are filtered through this interrupt routine.
;			In case the key hit is not a trappable key
;			it is allowed to pass through the ROM keyboard
;			interrupt handler.
;
;	The following is the relationship of several tables used in this
;	module.  TRTBL2, USRTBL2 & TRTBL4 are the table of flags, and
;	TRTBL1 & USRTBL1 are the tables of definitions of keys (either
;	the scan code or user's definitions).  In order to support the
;	IBM advanced 101-key keyboard (ronco keyboard), there are four
;	entries paded after USRTBL2.  This is for the convenience of
;	table search for key number.
;
;	The definition of the flag, please refer the comments for
;	PPBEBL below.
;
;	TRTBL2 -->|--|	TRTBL1 -->|--| <-- Scan code of F1-F10
;		  |--|		  |--|		(10 keys)
;	(flags) ->|--|		  |--|
;		  \  \  	  \  \
;		  \  \  	  \  \
;		  |--|		  |--|
;		  |--|		  |--| <-- Scan code of cursor move key
;		  \  \  	  \  \  	(4 keys)
;		  \  \  	  \  \
;	USRTBL2 ->|--|	USRTBL1 ->|--|--| <-- user key definition
;		  |--|		  |--|--|	(11 keys)
;		  \  \  	  \  \  \
;		  \  \  	  \  \  \
;		  |--|		  |__|__|
;	(dummy) ->|--|
;	(0,4 keys)\  \  		(no corresponding table)
;		  \  \
;	TRTBL4 -->|--|			(no corresponding table)
;		  |--|
;		  |__|
;
;******************************************************************************
	INCLUDE switch.inc
	INCLUDE rmacros.inc	

	useSeg	_BSS		
	useSeg	CONST		
	useSeg	_DATA		
	useSeg	EV_TEXT 	

	INCLUDE seg.inc 	
	INCLUDE ibmunv.inc
	INCLUDE idmac.inc	
	INCLUDE intmac.inc
	INCLUDE oscalls.inc	
	INCLUDE baslibma.inc	
	INCLUDE event.inc	
	INCLUDE const.inc	

	SUBTTL	local constant definitions	
	page

;Number of keys 		
	OrgFky		= 10	; normally, there is 10 function keys
	CsrMovKy	= 4	; four cursor movement keys
	ExtFky		= 2	; extended function keys (F11/F12)

;Scan codes			
	ScanPrtsc	= 37H	; scan code for Prtsc
	ScanPause	= 45H	; scan code for Pause
	ScanBreak	= 46H	; scan code for Break
	ScanF11 	= 57H	; scan code for F11
	ScanF12 	= 58H	; scan code for F12
	ScanExt1	= 0E0H	; scan code for extended keys
	ScanExt2	= 0E1H	; scan code for extended keys

	CTRLDown	= 04H	; bit for CTRL been pressed
	ALTDown 	= 08H	; bit for ALT been pressed


	SUBTTL	data definitions
	page

sBegin	_DATA			

externB b$IOFLAG		
externW b$IPOLKEY		
externB b$CtrlFlags		
staticB PPBEBL,07H		;This byte is used in the following way:
				;Bit 0 used for CTRL BRK enable/disable
				;Bit 1 used for CTRL PAUSE enb/disb
				;Bit 2 used for CTRL PRTSC enb/disb
				;ENABLE=1 and DISABLE=0

staticB TRTBL2,4,OrgFky+CsrMovKy; validate the first 14 keys (*)
staticB USRTBL2,0,NUM_UKEYS	; invalidate NUM_UKEYS user defined keys (*)

; Constants used in TRTBL2 and USRTBL2
TRP_OCCURED	EQU	1	; Bit 0 indicates occurence of a trap
TRP_ENABLED	EQU	2	; Bit 1 indicates trapping enb/disb
TRP_VALID	EQU	4	; Bit 2 indicates def valid/invalid

staticB ,0,NUM_GAP		; there is a gap between the last user
				;  defined key and F11
staticB TRTBL4,4,ExtFky 	; flags for F11/F12, NOTE: TRTBL2, USRTBL2
				;  and TRTBL4 has to be contiguous and in
				;  this order
sEnd	;_DATA			

sBegin	CONST			

staticB TRTBL1,<59,60,61,62,63>
staticB ,<64,65,66,67,68>	; 10 function keys
staticB ,<72,75,77,80>		; 4 cursor control keys
				; currently, there is no need to use a
				;  table for F11/F12, since there are only
				;  two of them.  Within the code, it checks
				;  the scan code of F11/F12 directly.  But
				;  the trap flag table, TRTBL4, is needed.
staticB SHFTBL,<52H,3AH,45H,46H>; used to check for shift keys in SHKEYS
staticB ,<38H,1DH,2AH,36H>	; The last 3 entries must remain last!


sEnd	;CONST			

sBegin	_BSS			

staticB WasE0E1,0		; the value will be either 00H or 80H, to
				;  indicate the extended keys

	externB b$NetCard	; defined in LLINI.ASM
				; b$NetCard=1 --> network installed and
				; running on 3.xx
				; b$NetCard=0 --> network not installed

staticW USRTBL1,,NUM_UKEYS	; NUM_UKEYS user defined keys
staticW KEYHIT,,1		
staticB LPTFLG,,1		; line printer echo key flag
staticB POSFLG,,1		; pause key flag
staticB BRKFLG,,1		; break key flag
staticB KEYFLG,,1		; trapped key flag
staticB KEYTRP,,1		; key trapping enable/disable flag
staticB WASPOS,,1		; helps in handling the CTRL PAUSE key.
				; A value of 0 indicates that the CTRL
				; PAUSE is not active, whereas a value
				; of 0FFH indicates that the CTRL PAUSE
				; is active. (used in B$KBDTRP & B$RDKYBD)

externB	b$EventFlags		; misc event flags

sEnd	;_BSS			


	SUBTTL	code externals	
	page

externFP B$IBreak		;interp call back to notify of CTRL-BREAK


sBegin	EV_TEXT 		
assumes CS,EV_TEXT		

	externNP B$TrapEvent	
	externNP B$TestTrap	
	externNP B$ReqTrap	
	externNP B$Wakeup	
	externNP B$GETDS	

	SUBTTL	B$RDKYBD - Keyboard control routine
	PAGE
;***
;B$RDKYBD - Support for Keyboard Events
;OEM-interface routine
;
;Purpose:
;	This routine allows the caller to do one of the following:
;	(1) Check whether the key trap happened.
;	(2) Define the user definable trap keys. The key definition syntax
;		specifies a string.This string is passed directly to B$RDKYBD.
;	(3) Start trapping keys.
;	(4) Stop trapping keys.
;	(5) Enable trapping for a specific key#
;	(6) Disable trapping for specific key#
;
;	See the documentation for B$POLLEV for a description of the
;	event and trapping mechanisms.
;
;	The string that is passed in as a parameter in function number
;	1 is directly from the user.  It has to be checked for proper
;	length and contents before it can be used.  In this implementation,
;	the length of this string must be 2.  If the string is incorrect,
;	return with PSW.C set and an ILLEGAL FUNCTION CALL will be
;	generated.
;
;Entry:
;	[AL] = 0: Return in [BX]
;			0 if no keyboard trap occurred
;			key number if a trap key was detected
;			-1 if ctrl-break was encountered
;			-2 if pause was encountered
;			-3 if LPTECHO was encountered
;	       1: define a user definable key for trapping
;			[BX] = address of the key definition string
;			[CX] = length of the key definition string
;			[DX] = key number
;	       252: start trapping keys
;	       253: stop trapping keys
;	       254: enable trapping for key # [DX]
;			Key number range is [-3,(max key index)]
;			Key numbers are one relative, Key 0 not used.
;	       255: disable trapping for key # [DX]
;			Key number range is [-3,(max key index)]
;			Key numbers are one relative, Key 0 not used.
;	[BX] = value as specified by function [AL]
;	[CX] = value as specified by function [AL]
;	[DX] = value as specified by function [AL]
;
;Exit:
;	[BX] = value, if specified by function [AL]
;	[DX] = value, if specified by function [AL]
;	PSW.C set will cause a function call error
;
;Uses:
;	Per Convention
;
;Exceptions:
;	None.
;******************************************************************************
;
;ALGORITHM:
;
;	case [AL] of
;		0: begin
;			if LPTFLG then
;			    begin
;			       set [BX] to -3
;			       clear LPTFLG
;			    end
;			if (any trap key flag set ) then
;			      begin
;				set [BX] to trap key #
;				clear corr. trap key flag
;			      end
;			else
;			    if POSFLG then
;				begin
;				  set [BX] to -2
;				  clear POSFLG
;				end
;			    else
;				if BRKFLG then
;				  begin
;				    set [BX] to -1
;				    clear BRKFLG
;				  end
;				else
;				   set [BX] to 0
;		   end
;		1: begin
;		     if (( [CX] < 1 ) or ( [CX] > 2 )) then
;			set carry  to indicate function
;			call error
;		     else
;			redefine key # [DX] using
;			the address in [BX]
;		   end
;		252: enable
;		253: clear enable flag for all trappable keys
;		254: set enable flag for
;		      key # [DX]
;		255: clear enable flag for
;		      key # [DX]
;		otherwise : set carry to indicate error
;			    in function call
;	endcase
;
;DATA STRUCTURE:
;	The trap table has NUM_TKEYS rows, each row made up of
;	2 bytes. The two bytes are required for the definition
;	of a key string. There is another table having 20 rows
;	each row having a byte. This byte is used to store
;	three flags, namely
;	   1. Definition valid or not
;	   2. Key enabled or not
;	   3. Trap occurred or not
;	The mask is defined as follows:
;	   Bit 0 corresponds to the occurence of a key trap.
;	   Bit 1 corresponds to key Enable/Disable.
;	   Bit 2 corresponds to key definition validation.
;
;#****

cProc	B$RDKYBD,<NEAR,PUBLIC>,ES 
cBegin				


	PUSH	DS		
	POP	ES		
	CALL	B$SetKybdInt	; install keyboard handler if not already
				; installed
	OR	AL,AL		;test if key trapping status
	JNZ	RDK1A		;if not, then process normally
	XOR	BX,BX		;preset BX to zero
	XCHG	BL,KEYFLG	;swap zero and key trapping flag
	OR	BX,BX		;test if flag was set
RDK1A:
	PUSH	SI
	push	ax		; save [ax]
	JZ	RDKRET		; if flag was not set, then don't process it
	ADD	AL,4		;[7] check if [AL] is within limits
	JS	RDKERR
	CMP	AL,6		; no LOC/LOF support (one less entry)
	JNB	RDKERR
RDK2:
	CBW			; since all positive, save one byte
	SHL	AX,1
	MOV	SI,AX		;[SI] = word index into table
	PUSH	ES
	PUSH	CX
	PUSH	DI
	PUSH	DS		
	POP	ES		; make ES=DS
	CALL	CS:RDKOFST[SI]
	POP	DI
	POP	CX
	POP	ES
	JMP	SHORT	RDKRET
RDKERR:
	STC
RDKRET:
	pop	ax		; restore [ax]
	POP	SI

cEnd				


RDKOFST DW	TRPEBL
	DW	TRPDIS
	DW	ENABL
	DW	DISABL
	DW	KEYRTN
	DW	KEYDEF

	SUBTTL	B$SetKybdInt - Install keyboard handler
	PAGE
;***
;B$SetKybdInt, B$InstKybdInt - install keyboard interrupt handler
;OEM-Interface Routine
;
;PURPOSE:
;	These routines install the keyboard interrupt service
;	routine. B$SetKybdInt checks to see if the routine has already
;	been installed and returns without doing anything if it has
;	been.  B$InstKybdInt does not check if there is already a keyboard
;	servrice routine.
;
;Preserves:
;	AX
;
;********************************************************************
cProc	B$SetKybdInt,<NEAR,PUBLIC>
cBegin

	TEST	b$EventFlags,KybdInst ; keyboard service routine installed ?
	JZ	B$InstKybdInt 	; brif not -- install it
	RET			; otherwise, just return

labelNP	<B$InstKybdInt>		


	CLI			;clear interrupts
	PUSH	DS
	PUSH	DX
	PUSH	AX
	PUSH	CS
	POP	DS		;[DS] := [CS]
	SETVEC	KYBINT,B$KBDTRP ;install new keyboard service routine
	POP	AX
	POP	DX
	POP	DS
	OR	b$EventFlags,KybdInst		; set init flag
	STI			;restore interrupts


cEnd				

;**
;This routine returns the key that was most
;recently struck. Actually it returns a value
;in [BX] corresponding to the key struck.

KEYRTN:
	CMP	LPTFLG,1	;was it the line printer echo?
	JNE	TRPKYS		;no, check for the trap keys
	MOV	LPTFLG,0	;clear the printer echo flag
	MOV	BX,-3		;return a -3 in BX
	JMP	SHORT KEYRET
TRPKYS:
	MOV	DI,OFFSET DGROUP:TRTBL2 ;[DI] = offset of trap table 2
	MOV	CX,NUM_TKEYS	; [CX] = count of total function keys
				;  including the gap (which is always 0)
				; this number including the 4 padding
				; entries
	MOV	AL,07H		;[AL] = 00000111B
	CLD			;just to be safe
	REPNZ	SCASB		;search for a trapped key
	JNZ	POSBRK		; Brif none found, the original code used
				;  count=(total number of keys)+1 and JCXZ
				;  here, it was OK.	I use JNZ and count=
				;  (total number of keys) instead.  The
				;  effect is waste one byte, but save one
				;  comparison.
	SUB	CX,NUM_TKEYS	; getting the 1-relative key
	NEG	CX		;number in [CX]
	DEC	DI		;adjust [DI] to point to found key
	AND	BYTE PTR[DI],0FEH ;clear the trap flag for this key
	MOV	BX,CX		;return the key number in [BX]
	JMP	SHORT KEYRET
POSBRK:
	CMP	POSFLG,1	;was it the pause key?
	JNE	CHKBRK		;no, check for BRK
	MOV	POSFLG,0	;yes, clear the pause key flag
	MOV	BX,-2		;return -2 in BX
	NOT	WASPOS		;WASPOS indicates whether
				;CTRL PAUSE is active or not
	JMP	SHORT	KEYRET
CHKBRK:
	CMP	BRKFLG,1	;was it the break key
	JNE	NOKEYS		;no, jump to no keys trapped
	MOV	BRKFLG,0	;clear the break flag
	MOV	BX,-1		;return -1 in BX
	JMP	SHORT	KEYRET
NOKEYS:
	XOR	BX,BX		; return 0 to indicate no keys
				;  and XOR clear the carry flag
	RET			; return with NC & BX=0
KEYRET:
	MOV	KEYFLG,1	;set flag to process again
	CLC			;indicate no error
	RET

;**
;This routine is used to define a user defined
;trap key.
; DI is used. (caller, B$RDKYBD preserves AX,CX,SI,DI)
; BX is preserved.

KEYDEF:
	CMP	CX,2		;is CX = 2 as it should be
	STC			; assume error
	JNE	DEFRET		; Brif CX <> 2, return with CY (error)
	PUSH	BX		; save BX
	MOV	CX,[BX] 	;get the key definition in [CX]
	XCHG	CH,CL		;swap before storing
	TEST	CH,3		; left/right shift been pressed ?
	JZ	NO_SHIFT	; Brif not
	OR	CH,3		; make both the same
NO_SHIFT:
	MOV	DI,DX			; # in DI
	SUB	DI,OrgFky+CsrMovKy+1	; map 15,16,... to 0,1,...
	MOV	BX,OFFSET DGROUP:USRTBL2; [BX] = offset of trap table 2
	OR	BYTE PTR [BX+DI],TRP_VALID  ; validate the new definition
	MOV	BX,OFFSET DGROUP:USRTBL1; [BX] = offset of trap table 1
	SHL	DI,1			; get the word offset
	MOV	WORD PTR[BX+DI],CX	; store the new key definition
	POP	BX		; get back BX
	CLC
DEFRET:
	RET

;**
;enables key trapping

TRPEBL:
	MOV	KEYTRP,1
	CLC			; original code exit via TRPDIS, slower
	RET

;**
;disables key trapping

TRPDIS:
	MOV	KEYTRP,0
	CLC
	RET

;**
;enables trapping for key # [DX]

ENABL:
	PUSH	DX		;save [DX]
	OR	DX,DX		; is [DX]>0 ? NOTE: [DX]=0 isn't taken care
	JG	ENABL1		;Brif so
	NEG	DX		;else complement [DX]
	CMP	DL,3		;if [DL]=3 then [DL]:=4
	JB	ENABL0		;Brif not
	INC	DL		;else make [DL]=4
ENABL0:
	OR	PPBEBL,DL	;enable the corresponding key
				; carry is cleared
	JMP	SHORT ENABL2
ENABL1:
	MOV	DI,OFFSET DGROUP:TRTBL2-1 ; [DI] = (offset of trap table2)-1
	ADD	DI,DX		;get byte offset in table
	OR	BYTE PTR[DI],02H ;enable the key
				; carry is cleared
ENABL2:
	POP	DX		;restore [DX]
	RET			; with NC

;**
;disables trapping for key # [DX]

DISABL:
	PUSH	DX		;save [DX]
	OR	DX,DX		; is [DX]>0 ? NOTE: [DX]=0 isn't taken care
	JG	DISBL1		;Brif so
	DEC	DX		;disable the corresponding key
;Bug fixed April 12,1984
	CMP	DL,0FCH 	;is low nibble of [DL]=1100 ?
	JA	DISBL0		;Brif not
	DEC	DL		;else make it 1011
DISBL0:
	AND	PPBEBL,DL	;leaving the others intact
				; carry is cleared
	JMP	SHORT DISBL2
DISBL1:
	MOV	DI,OFFSET DGROUP:TRTBL2-1 ; [DI] = (offset of trap table2)-1

⌨️ 快捷键说明

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