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

📄 llaevt.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
cEnd				

;***
;B$SetClockInt - Install CLOCKTIC interrupt if not already installed
;OEM-interface routine
;
;Purpose:
;	This routine checks to see if the CLOCKTIC has been
;	installed or not. If not installed it installs it.
;
;Entry:
;	None.
;
;Exit:
;	None.
;
;Uses:
;	Per convention
;
;Exceptions:
;	None.
;****
cProc	B$SetClockInt,<NEAR,PUBLIC>	
cBegin				
	TEST	b$EventFlags,TimerInst ; timer interrupt installed yet ?
	JZ	SET_IT		;Brif not -- install it now
NearRet:			; label to a near return
	RET
SET_IT:


	PUSH	AX
	PUSH	DX
	PUSH	DS
	IN	AL,MSKREG	;get IMR into AL
	OR	AL,01H		;mask out timer interrupt
	PAUSE
	OUT	MSKREG,AL	;write mask to IMR
	CLI			;Interrupts off during mod.
	push	bx
	push	es
	savint	cs:b$OldClkTic,timadr
	pop	es
	pop	bx
	PUSH	CS		;set [DS] = [CS]
	POP	DS
	SETVEC	TMRCTL,CLOCKTIC ;set clock interrupt
	POP	DS		;restore [DS]
	POP	DX
	OR	b$EventFlags,TimerInst ; set timer installed flag
	IN	AL,MSKREG	;get IMR into AL
	AND	AL,0FEH 	;unmask timer interrupt
	PAUSE
	OUT	MSKREG,AL	;write mask to IMR
	POP	AX		;restore [AX]
	STI			;restore interrupts

cEnd				



;***
;CLOCKTIC - The Timer Interupt vectors here AFTER updating the time-of-day.
;
;		CLOCKTIC polls the PEN Status (if ON) and stores
;		new values.  Then Joystick TRIGGERS (if ON) and
;		stores their values if fired since last time
;		read with the STRIG(0) or STRIG(2) Statement.
;
;	NOTE:	Rom clock interrupt routine saved [AX],[DX],[DS]
;
;	read the comment at the top of the file for detail.
;******************************************************************************
cProc	CLOCKTIC,<FAR>		
cBegin				
	PUSH	BP
	PUSH	DI
	PUSH	SI
	PUSH	DS
	PUSH	AX
	MOV	DS,CS:b$BASDSG ;Get DS addr for our vars.
	TEST	b$EventFlags,SLEEPtmr ; SLEEP timer on?
	JZ	NoWakeup	; brif not
	DEC	SleepCnt1	; decrement low word of SLEEP timer
	JNZ	NoWakeup	; brif not timeout/wrap
	DEC	SleepCnt2	; decrement high word of SLEEP timer
	JNS	NoWakeup	; brif not timeout
	AND	b$EventFlags,NOT (InSLEEP OR SLEEPtmr) ; break out of
				; SLEEP wait loop
NoWakeup:
	CMP	TMENBL,1	;is timer enabled?
	JNZ	TRYPEN		;Brif not
	DEC	TMCNT1		;decrement timer count
	JNZ	TRYPEN		;Brif not zero
	DEC	TMCNT2		;decrement the remaining byte
	JNS	TRYPEN		; Brif not negative
RESET:
	MOV	AX,TIMRN1	;reset the timer
	MOV	TMCNT1,AX	;count after counting
	MOV	AX,TIMRN2	; down the timer
	MOV	TMCNT2,AX	; it is word now
	MOV	TMRFLG,1	;set timer event flag
	MOV	AL,TIMOFF	; AL = trap number for B$TrapEvent
	CALL	B$TrapEvent	;set global event flag
TRYPEN:

	CMP	LPEN.LPEN_ENABLE,0 ; PEN ON?
	JE	TICTRG		; No, Try Trigger
	cCall	B$PENINT 	; Yes, Update Pen status.
TICTRG:

	CALL	b$pJoystInt	; process joystick interrupt (if present)
	POP	AX
	POP	DS
	POP	SI
	POP	DI
	POP	BP
	JMP	CS:b$OldClkTic ;go service the old interrupt 1C

cEnd	nogen			


;***
;SCTOIC -- translate number of seconds to number of interrupts
;
;Purpose:
; Converts the number of seconds to a factor as required by the operating
; system. Under DOS 2/3, we multiply [CL:DX] by 18.2 and return this number
; of clock ticks in [CX:DX]. Under DOS 5 we multiply [CL:DX] by 1000, and
; return this number of millesecodns in [CX:DX].
;
;  DOS3 NOTE: .2(n)=n/5, IDIV is used here.  Since max(n)=86400, the
;	      result will be a two-byte integer, and won't cause overflow.
;Entry:
;	[CL:DX] = number of seconds
;
;Exit:
;	[CX:DX] = number of interrupts needed
;
;Uses:
;	AX.
;****
cProc	SCTOIC,<NEAR>,<SI,DI>	
cBegin
	XOR	CH,CH
	MOV	AX,DX
	MOV	DX,CX		; store n in [DX:AX] (for IDIV)
	MOV	DI,AX
	MOV	SI,DX		; save n in [SI:DI]
	MOV	CX,5		; .2 is 1/5
	IDIV	CX		; get 0.2n in AX=[DX:AX]/[CX],
				; and remainder is in DX
	CMP	DX,2		; do we need to round ?
	JNA	NOADD1		; Brif don't
	INC	AX		; increment one
NOADD1:
	MOV	DX,DI
	MOV	CX,SI		; one more n in [CX:DX]
	CLC			; NC
	RCL	DX,1
	RCL	CX,1		; [CX:DX]=2*n
	PUSH	CX		; save CX
	MOV	CX,4		; loop count
MLOOP:				; multiple loop
	CLC			; no carry
	RCL	DI,1		; rotate left through carry
	RCL	SI,1
	LOOP	MLOOP		; when done, [SI:DI]=16*n
	POP	CX		; get back CX, so [CX|DX]=2*n
	ADD	DX,DI
	ADC	CX,SI		; [CX:DX]=18*n
	ADD	DX,AX
	ADC	CX,0		; [CX:DX]=18.2 * n (nearly)

cEnd				


;***
;B$SleepInit - set up timeout for SLEEP statement
;OEM-interface routine
;
;Purpose:
;
;Entry:
;	[DX|AX] = number of seconds to wait
;Exit:
;	[SleepCnt2|SleepCnt1] = number of clock ticks to wait
;Uses:
;	Per convention
;Preserves:
;
;Exceptions:
;	None.
;****

cProc	B$SleepInit,<NEAR,PUBLIC>
cBegin
	xchg	AX,DX			; [CL|DX] = # of seconds
	xchg	AX,CX
	call	SCTOIC			; [CX|DX] = # of clock ticks
	mov	SleepCnt1,DX		; update counter variables
	mov	SleepCnt2,CX
cEnd


	SUBTTL	PLAY
	PAGE
;***
;B$RDPLAY - play trapping and the PLAY function
;OEM-interface routine
;
;Purpose:
;	This routine supports play trapping and the play function.
;	A play event occurs when the background music queue shrinks
;	from n to n-1 notes (where n is specified in the ON PLAY(n)
;	statement). The event does not occur until PLAY trapping is
;	enabled and the background music queue has length greater
;	than n-1.
;
;	When PLAY trapping is enabled and the music queue shrinks
;	from n to n-1, the event flag and the play event flag are
;	both set.
;
;	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$RDPLAY with [AL] = 0
;				 0 if event did not occur since
;				   last call to B$RDPLAY with [AL] = 0
;		1:Return [BX] = number of notes in the queue
;			 [AH] = Voice Id (multivoice only)
;		2:Set event threshold to [BX], the number of notes
;			specified in the ON PLAY(n) statement
;		254: Enable PLAY trapping
;		255: Disable PLAY trapping
;
;Exit:
;	[BX] = value if specified by function [AL]
;	PSW.C set will cause a function call error
;	      to be declared
;
;Uses:
;	Per convention
;
;Preserves:
;	AX, CX, DX
;
;Exceptions:
;	None.
;****

cProc	B$RDPLAY,<NEAR,PUBLIC>,<SI,AX>	
cBegin				

	CMP	AL,0
	JE	CHKPLY		;check for play event
	CMP	AL,1
	JE	RTNOTE		;return # of notes in queue
	CMP	AL,2
	JE	STNOTE		;save # of notes in ON PLAY(n)
	CMP	AL,254
	JE	STPLAY		;enable play trapping
	CMP	AL,255
	JE	SPPLAY		;disable play trapping
STNOTE_ERROR:			
	STC			;set carry to indicate function
PlayExit:			
cEnd				; restore registers & return

CHKPLY:
	XOR	BX,BX		; assume no event occured (BX = 0)
	CMP	b$PLENBL,0	;is play trapping enabled?
	JE	RDPRET		; Brif not enabled
	CMP	b$PLAFLG,1	;did play event occur?
	JNE	RDPRET		; Brif not
	DEC	BX		; return -1 in BX to report it
	MOV	b$PLAFLG,0	;clear the play event flag
	JMP	SHORT RDPRET

RTNOTE:
	MOV	BX,OFFSET DGROUP:b$SNDQCB	; get the addr of sound-block
	MOV	BX,[BX].QUNOTE	; Get the remaining notes in queue
	JMP	SHORT RDPRET
STNOTE:
	OR	BX,BX		;test if zero
	JZ	STNOTE_ERROR	;if so, then error
	CMP	BX,32D		;test if greater than 32
	JA	STNOTE_ERROR	;if so, then error
	MOV	b$PLYCNT,BX	;store # of notes specified in
	JMP	SHORT RDPRET	;ON PLAY(n) statement in PLYCNT
STPLAY:
	MOV	b$PLENBL,1	;enable trapping
	JMP	SHORT RDPRET
SPPLAY:
	MOV	b$PLENBL,0	;disable trapping
RDPRET:
	CLC			;clear carry to indicate no error
	JMP	SHORT PlayExit	; and return

;***
;B$PENINT -- PEN Update
;
;		Called by Timer Interupt AFTER updating the
;		time-of-day only if PEN or STRIG are ON.
;
;		CLOCKTIC polls the PEN Status (if ON) and stores
;		new values.  Then Joystick TRIGGERS (if ON) and
;		stores their values if fired since last time
;		read with the STRIG(0), STRIG(2), STRIG(4) or
;		STRIG(6) Statement.
;
;	NOTE:	Rom clock interrupt routine saved [AX],[DX],[DS]
;****

cProc	B$PENINT,<NEAR>,<BX,CX,DX,SI>	
cBegin					

	SCNIOS	vReadLightPen		; Read Lpen
	MOV	SI,OFFSET DGROUP:LPEN	; Point to LPEN structure
					; AH 01/00 if pen down/up
	SAHF				; CF = 1/0 if pen down/up
	SBB	AX,AX			; AX = -1/0 if pen down/up
	XCHG	AH,[SI].LAND_FLAG	; Get old LAND_FLAG in AH and
					; set it to new value
	JZ	PENINT_EXIT		; If pen not down nothing else to do

;	Now, set the lpen-coords to new values as return by BIOS

	ADD	DX,0101H		; Make row/col 1-relative
	MOV	[SI].X_TOUCH,BX		; Update the TOUCH variables
	MOV	[SI].COL_TOUCH,DL	; Hi-Byte will always ramin zero
	MOV	[SI].ROW_TOUCH,DH	;  --ditto--
	MOV	[SI].Y_TOUCH,CH		;  --ditto--
	CMP	AH,AL			; Any change in the pen down status?
	JE	PENINT_EXIT		; Brif not
					; Else, update the new LAND variables
	MOV	[SI].LPEN_STATUS,AL	; Set the current status as active
	MOV	[SI].Y_LAND,CH		; Hi-Byte will remain zero always
	MOV	[SI].COL_LAND,DL	;  --ditto--
	MOV	[SI].ROW_LAND,DH	;  --ditto--
	MOV	[SI].X_LAND,BX		
	MOV	AL,PENOFF		; AL = trap number for B$TrapEvent
	cCALL	B$TrapEvent

PENINT_EXIT:			; Time to exit

cEnd				; End of B$PENINT



	SUBTTL	SIGNAL processing code
	PAGE



sEnd	EV_TEXT
	END

⌨️ 快捷键说明

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