📄 llaevt.asm
字号:
PAGE 56,132
TITLE LLAEVT - GW-BASIC Event Trapping Interface
;***
; LLAEVT - GW-BASIC Event Trapping Interface
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
; ***********************************************************************
;
; This module has advanced EVENT support routines:
;
; B$RTIMR
; B$RDPEN
; B$RDPLAY
; B$RDSIG
; B$RDMOUSE
; B$RDUEVENT
; CLOCKTIC .....clock interrupt routine branches here after
; updating time of day. This routine is used to
; check for TIMER events, PEN status and TRIG
; status.
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc
useSeg _BSS
useSeg _DATA
useSeg EV ; Event handling segment(s)
INCLUDE seg.inc
INCLUDE ibmunv.inc
INCLUDE idmac.inc ; debugging macros
INCLUDE intmac.inc
INCLUDE event.inc ; bit flag constants
sBegin _DATA
externB b$EventFlags ; misc event flags
globalW b$pJoystInt,NearRet,1 ; Joystick interrupt handler
staticW TIMRN1,-1 ; stores n of ON TIMER(n) (4 bytes)
staticW TIMRN2,-1 ; start with -1 (no timeout) for OS/2
staticW SleepCnt1,0 ; number of clock ticks to wait before
staticW SleepCnt2,0 ; SLEEP statement times out
sEnd _DATA
sBegin _BSS
externB b$PLAFLG ;LLSND - playing flag
externB b$PLENBL ;LLSND - play enable flag
externW b$PLYCNT ;LLSND - play note count
externW b$SNDQCB ; Sound queue block
LPEN_MAX_ARG EQU 9 ; Maximum allowable arg value
LPEN_COORDS STRUC ; Structure for LPEN land/touch values
LPEN_STATUS DB 0 ; Used as filler as PEN(0) does not require
LPEN_DUMMY DB 0 ; any data variable
X_LAND DW 0 ; Graphics X-coord when pen last landed
Y_LAND DB 0 ; Graphics Y-coord when pen last landed
Y_LAND_HI DB 0 ; Dummy entry for high byte
LPEN_ENABLE DB FALSE ; LPEN enable/disable flag - initial disable
LAND_FLAG DB FALSE ; These used since PEN(3) does not require
; any data variable
X_TOUCH DW 0 ; Graphics X-coord when pen last touched
Y_TOUCH DB 0 ; Graphics Y-coord when pen last touched
Y_TOUCH_HI DB 0 ; Dummy entry for high byte
ROW_LAND DB 1 ; Character row when pen last landed
ROW_LAND_HI DB 0 ; Dummy entry
COL_LAND DB 1 ; Character column when pen last landed
COL_LAND_HI DB 0 ; Dummy entry
ROW_TOUCH DB 1 ; Character row when pen last touched
ROW_TOUCH_HI DB 0 ; Dummy entry
COL_TOUCH DB 1 ; Character column when pen last touched
COL_TOUCH_HI DB 0 ; Dummy entry
LPEN_COORDS ENDS
LPEN LPEN_COORDS <> ; Allocate space and initialize
TMRFLG DB 1 DUP(?) ;timer evnt flag
TMENBL DB 1 DUP(?) ;timer event enable flag
;
; The timer used $TIMRSW as an one-second downcounter, which counted
; down from 18. Although the period of 18 clock interrupts were closed
; to one second, there was about 0.0109 second difference, which was
; based on 18.2 interrupts being one second.
; Instead of using an one-second counter, current method uses the
; interrupt counter directly. When the high level code gets n from
; the statement ON TIMER (n) ... and passes it to the low level code,
; the n, in seconds, is multiplied by 18.2. The result, which is
; how many interrupts needed, is then stored in $TMCNT1 & $TMCNT2.
;
TMCNT1 DW 1 DUP(?) ;down counter
TMCNT2 DW 1 DUP(?) ;down counter is now 4 bytes
sEnd _BSS
sBegin EV_TEXT
assumes CS,EV_TEXT
externNP B$TrapEvent ;routine to set global event flag
externNP B$SCNIO ;LLINI - perform screen BIOS call
externW b$BASDSG ;LLINI - BASCOM data segment
externD b$OldClkTic ;LLINI - saved INT 1CH vector
SUBTTL B$RDPEN - Read Light-Pen Coordinates and Trigger Flag.
PAGE
;***
;B$RDPEN - Read Light-Pen Coordinates and Trigger Flag.
;OEM-interface routine
;
;Purpose:
; This routine supports the light-pen. It allows reading of
; the coordinates of the pen, deturmining its status (touching
; the screen or not touching the screen), and event support
; for ON TRIGGER(n) GOTO.
;
; See the documentation for B$POLLEV for a description of the
; event and trapping mechanisms.
;
;Definitions:
; The light pen is always in one of 2 states:
;
; "touching the screen" or "not touching the screen".
;
; In the following text, the point at which a light pen last landed on
; the screen is defined as the point where the pen last changed state
; from "not-touching the screen" to "touching the screen". The point
; at which the pen last touched the screen is defined as the last point
; at which the state of the pen was "touching the screen".
;
;Entry:
; [AL] = which value to return in [BX]
; 0: If PEN has touched screen since
; last call to B$RDPEN with [AL]=0 then return -1
; else return 0.
; 1: Return graphic X-Coordinate where pen last landed
; on the screen.
; 2: Return graphic Y-Coordinate where pen last landed
; on the screen.
; 3: If PEN is currently touching screen
; then return -1, else return 0.
; 4: Return graphics X-Coordinate where pen last
; touched the screen.
; 5: Return graphics Y-Coordinate where pen last
; touched the screen.
; 6: Return character line where pen last landed
; on the screen.
; 7: Return character column where pen last landed
; on the screen.
; 8: Return character line where pen last
; touched the screen.
; 9: Return character column where pen last
; touched the screen.
; 254: Enable light pen interrupt processing until B$RDPEN
; is called with [AL]=255. This is to increase
; system performance. It can be ignored by OEM.
; 255: Disable light pen interrupt processing until B$RDPEN
; is called with [AL]=254. This is to increase
; system performance. It can be ignored by OEM.
; When the system is initialized, light pen interrupt
; processing can be disabled.
;
;Exit:
; [BX]=return value as a signed 16-bit integer.
;
; Note - The range of Graphics Coordinates is determined by the
; current graphics mode. Character line and column coordinates
; are 1 relative.
;
;Uses:
; Per convention
;
;Exceptions:
; None.
;****
cProc B$RDPEN,<PUBLIC,NEAR>
cBegin
cCall B$SetClockInt ; check if CLOCK_INT has been installed
;if not install it
CBW ; AH = 0/-1
CMP AL,LPEN_MAX_ARG ; Check for input value
JBE PROC_LPEN ; Brif if PEN function
LPEN_ON_OFF: ; Check if request is to turn it on/off
INC AX ; AX = -1/0 (254/255)
MOV LPEN.LPEN_ENABLE,AL ; Set the enable variable appropriately
; Now, read the LPEN_STATUS once again and discard it. This is required
; to avoid spurious results next time the light pen status is read
; because the BIOS internal flag is cleared only when it is read
XCHG BX,AX ; Save it in BX
cCALL B$PENINT ; Still LPEN_STATUS is modified
AND LPEN.LPEN_STATUS,BL ; And change the status correctly
; If enabled & active then remain active
; else set to inactive
JMP SHORT LPEN_RET ; & Exit...
LPEN_3: ; Process PEN(3) function
SCNIOS vReadLightPen ; Read light pen status again (current val)
SAHF ; If AH = 1 , then CF = 1 (pen active)
XCHG AX,BX ; Save BX (returned value) in AX
SBB BX,BX ; Set BX to 0/-1 as return value
JZ LPEN_RET ; If pen not active, simply return
MOV LPEN.X_TOUCH,AX ; Current X coordinate
MOV LPEN.Y_TOUCH,CH ; Current Y coordinate
MOV LPEN.ROW_TOUCH,DH ; Current row
MOV LPEN.COL_TOUCH,DL ; Current col
JMP SHORT LPEN_RET ; Exit ...
PROC_LPEN:
; AH = 0 here
; If light pen is not enabled, then issue an error
; CMP LPEN.LPEN_ENABLE,AH ; Is it zero? (disabled)
; MOV BX,-1 ; Prepare for error
; JE LPEN_RET ; Brif disable - CF = 1 for error
; The function value requested is other than 0.
; If it is 3, then handle it as a special case
CMP AL,03 ; Is it special case?
XCHG AX,BX ; Get input arg in BX
JE LPEN_3 ; If 3, then read the current lpen status
SHL BX,1 ; Make it a word index into LPEN structure
MOV BX,[OFFSET DGROUP:LPEN+BX] ; Get the value requested
JNZ LPEN_RET ; If arg not zero then return the value
MOV LPEN.LPEN_STATUS,BH ; If arg = 0, then reset status to zero
MOV BH,BL ; Copy low byte for reporting
LPEN_RET: ; Time for returning
cEnd ; End of B$RDPEN
SUBTTL B$RDMOUSE - Read Mouse information
PAGE
SUBTTL Timer Event Routines
PAGE
;***
;B$RTIMR - Timer Event Trapping
;OEM-interface routine
;
;Purpose:
; This routine supports timer event trapping and the
; ON TIMER(n) function. This routine allows enabling and
; and disabling the timer, setting the timer interval, and
; polling if a timer event has occured.
;
; A timer event will not be generated until the timer is enabled
; and the timer interval has passed.
;
; See the documentation for B$POLLEV for a description of the
; event and trapping mechanisms.
;
;Entry:
; [AL] = Function code
; 0: Return [BX] = -1 if event occured since last
; call to B$RTIMR with [AL] = 0
; 0 if event did not occur since last
; call to B$RTIMR with [AL] = 0
; 1: Set timer interval to three byte integer [CL]:[DX]
; 254: Enable timer trapping
; 255: Disable timer trapping
; [CL]:[DX] = three byte integer timer interval (in seconds)
;
;Exit:
; [BX] = value if specified by function [AL]
; PSW.C set indicates an error in the input parameters and will
; cause an Illegal Function Call.
;
;Uses:
; Per convention
;
;Exceptions:
; None
;****
cProc B$RTIMR,<NEAR,PUBLIC>
cBegin
CALL B$SetClockInt ; check if CLOCK_INT has been installed
;if not install it
CMP AL,0 ;is [AL] = 0?
JE CHKTMR ;check for timer event
CMP AL,1
JE SETIMR ;set timer interval
INC AL ; was it 255?
JZ STPTMR ; disable timer trapping
INC AL ; was it 254?
JZ STATMR ; enable timer trapping
STC ;set carry to indicate function
JMP SHORT RDTRET ;call error and return
;
; See if timer event occurred. Returns BX as described above.
;
CHKTMR:
XOR BX,BX ; default is to report no timer event
CMP TMENBL,1 ;is timer enabled?
JNZ RDTRET ; Brif not
CMP TMRFLG,1 ;did timer event occur?
JNZ RDTRET ; Brif not
DEC BX ; else report it
MOV TMRFLG,0 ;clear the timer event flag
JMP SHORT RDTRET
;
; Set the timer event to occur in CL:DX seconds.
;
SETIMR:
CALL SCTOIC ;[CX:DX] = n * factor (OS dependant)
MOV TMCNT1,DX ;[TMCNT1:TMCNT2] = time, in os dependant terms
MOV TMCNT2,CX ; CNT is count decremented by timer int
MOV TIMRN1,DX ;[TIMRN2:TIMRN1] = same
MOV TIMRN2,CX
JMP SHORT RDTRET
;
; Start the timer
;
STATMR:
PUSH BX
MOV BX,TIMRN1 ;move n of ON TIMER(n)
MOV TMCNT1,BX ;to the down counter
MOV BX,TIMRN2 ; changed to four bytes
MOV TMCNT2,BX
POP BX
MOV TMENBL,1 ;enable trapping
JMP SHORT RDTRET
;
; Stop the timer
;
STPTMR:
MOV TMENBL,AL ; disable trapping
MOV TMRFLG,AL ; clear the timer event flag
RDTRET:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -