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

📄 woaswapi.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	smov	es,cs			;make es:bx point to Our_Ver_Struc
	mov	bx,StubSegOFFSET Our_ver_Struc
	xor	ax,ax			;also clears carry
	ret

GetVersion endp
;----------------------------------------------------------------------------;
; TestMemoryRegion:							     ;
;                Entry:							     ;
;			AX = 1						     ;
;		     ES:DI = start of buffer				     ;
;		        CX = size of buffer (0=64K)			     ;
;		     Interrupts are disabled and may not be enabled.         ;
;		     DOS calls may NOT be made.				     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0	If entire buffer is in global memory         ;
;			AX = 1	If partially in global memory		     ;
;			AX = 2	If entire buffer is in local memory	     ;
;									     ;
; Note: The are which is swapped out by the switcher starts at CS:0 and      ;
;       extends for 'WoaSwapAreaParaSize' paragraphs. This is the only area  ;
;       that we are going to treat as local, everything else is local.	     ;
;								             ;
;       There are 5 cases marked below with the appropriate return code.     ;
;			   						     ;
;									     ;
;			  |-------------------|				     ;
;			  | local memory      |				     ;
;  CASE:   1		2 |	    3	      |	4	   5		     ;
;       |------|    |--------|	 |-------| |-------|   |--------|	     ;
;       |------|    |--------|	 |-------| |-------|   |--------|	     ;
;  RETS:   0		1 |----------2--------|	1	   0		     ;
;									     ;
;----------------------------------------------------------------------------;
TestMemoryRegion proc near

	pushem	bx,cx,dx,si,di		;save
	xor	ax,ax
	mov	bx,es	  		;ax:bx has the start segment
	dec	cx			;one less than size

REPT 	4
	shl	bx,1			;shift AX:BX left by 1
	rcl	ax,1
ENDM

	add	bx,di			;add in start offset
	adc	ax,0			;AX:BX has start linear address

; compare AX:BX to CS:0, If AX:BX is less we have case 1 or 2, else 3, 4 or 5

	mov	di,cs			;get CS
	xor	si,si			;SI:DI will have left edge of LocalMem
REPT 	4
	shl	di,1			;shift AX:BX left by 1
	rcl	si,1
ENDM

	call	CompareAXBXtoSIDI	;do the comparision
	jnc	short TMR_Case3or4or5	;beyong left edge of LocalMemory

; we have case 1 or 2.

	add	bx,cx
	adc	ax,0			;AX:BX has the rt edge of the buffer

; compare the right edge of the buffer to the left edge of global memory

	call	CompareAXBXtoSIDI	;do the comparision
	jc	TMR_RetCase1or5		;case 1.
	jmp	short TMR_RetCase2or4	;case 2

TMR_Case3or4or5:

; get the right edge of global memory.

	mov	di,cs			;get CS
	add	di,cs:[WoaSwapAreaParaSize];add in size of the local memory
	xor	si,si			;SI:DI will have left edge of LocalMem
REPT 	4
	shl	di,1			;shift AX:BX left by 1
	rcl	si,1			;SI:DI is one byte beyond right edge
ENDM
	
; figure out if it is case 5 or not. AX:BX is left edge of buffer and SI:DI
; is one byte beyond right edge of local memory.

	call	CompareAXBXtoSIDI	;do the comparision
	jnc	TMR_RetCase1or5		;case 5.

; we have case 3 or 4. Get the right edge of buffer.

	add	bx,cx
	adc	ax,0			;AX:BX has the rt edge of the buffer

; figure out whether it is case 3 or 4.

	call	CompareAXBXtoSIDI	;do the comparision
	jnc	TMR_RetCase2or4		;case 4

TMR_RetCase3:

	mov	ax,2			;buffer is totally local.
	jmp	short TMR_Ret		;done.

TMR_RetCase1or5:

	xor	ax,ax			;totally global
	jmp	short TMR_Ret		;done.

TMR_RetCase2or4:

	mov	ax,1			;partially in local memory

TMR_Ret:

	popem	bx,cx,dx,si,di		;restore
	ret

TestMemoryRegion  endp
;----------------------------------------------------------------------------;
; SuspendSwitcher:							     ;
;									     ;
;                Entry:							     ;
;			AX = 2						     ;
;		     ES:DI = Switcher call in of new task switcher,	     ;
;			     or 0:0 if not supported.			     ;
;		     Interrupts are enabled.				     ;
;		     DOS calls can be made.				     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0	If the switcher is now suspended.	     ;
;			AX = 1	If the switcher cannot be suspended.         ;
;			AX = 2  Not suspended, others may start.	     ;
;----------------------------------------------------------------------------;
SuspendSwitcher proc near

; set a flag bit to disabled the Switcher.

	or	cs:[SwitcherDisabled], SD_SWAPI_DISABLE				
	xor	ax,ax			;switcher being disabled, clears carry
	ret

SuspendSwitcher endp
;----------------------------------------------------------------------------;
; ResumeSwitcher:							     ;
;									     ;
;                Entry:							     ;
;			AX = 3						     ;
;		     ES:DI = Switcher call in of new task switcher.	     ;
;		     Interrupts are enabled.				     ;
;		     DOS calls can be made.				     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0	(required for future extensibility)	     ;
;----------------------------------------------------------------------------;
ResumeSwitcher proc near

; reset a flag bit which tells us that the switchet is disabled by another
; task switcher.

	and	cs:[SwitcherDisabled], NOT SD_SWAPI_DISABLE
	xor	ax,ax			;return code, clears carry
	ret

ResumeSwitcher endp
;----------------------------------------------------------------------------;
; HookCallout:								     ;
;									     ;
;                Entry:							     ;
;			AX = 4						     ;
;		     ES:DI = address of routine to add to call out chain.    ;
;		     Interrupts are enabled.				     ;
;		     DOS calls can be made.				     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0	(required for future extensibility)	     ;
;----------------------------------------------------------------------------;
HookCallOut proc near

	xor	ax,ax			;we generate INT 2f every time, carry clear
	ret

HookCallOut endp
;----------------------------------------------------------------------------;
; UnHookCallout:  							     ;
;									     ;
;                Entry:							     ;
;			AX = 5						     ;
;		     ES:DI = address of routine to delete from call out chain;
;		     Interrupts are enabled.				     ;
;		     DOS calls can be made.				     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0	(required for future extensibility)	     ;
;----------------------------------------------------------------------------;
UnHookCallOut proc near

	xor	ax,ax			;we generate INT 2f every time, carry clear
	ret

UnHookCallOut endp
;----------------------------------------------------------------------------;
; QueryAPISupport:							     ;
;									     ;
;                Entry:							     ;
;			AX = 6						     ;
;		        BX = API Code.					     ;
;		     Interrupts will not be enabled if the call is being from;
;		     within a call out from the switcher else they will be.  ;
;		     DOS calls will not be made				     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0	(required for future extensibility)	     ;
;		     ES:BX = address of the API_Info_Struc belonging to the  ;
;			     respondent with the best level of support for   ;
;			     this API.					     ;
;----------------------------------------------------------------------------;
QueryAPISupport proc near

	pushem	cx,si,ds		;save
	mov	cx,bx			;get the API code

; if the call back chain is still valid we whould not try to build the chain
; again.

	les	bx,cs:[lpCallBackChain]	;load it, in case it is vcalid
	cmp	cs:[CallBackAddrValid],0;is the call back address valid ?
	jnz	QAPIS_Walk_Chain	;it is valid

; will the chain again.

	cCall	BuildCallBackChain	;ES:BX points to start of chain

QAPIS_Walk_Chain:

	xor	si,si			;ds:si -> best handler's structure.
	mov	ds,si

QAPIS_WalkChainLoop:

	push	ax			;save
	mov	ax,es			;is es:bx 0 ?
	or	ax,bx			;end of chain ?
	pop	ax			;restore
	jz	QAPIS_DoneWithWalk	;yes, we have the results.

; get to the correct API node.

	pushem	es,bx,ax		;save
	les	bx,es:[bx.SCBI_API_Ptr]	;start of the pointer.
	mov	ax,es			;is it a valid node
	or	ax,bx			;NULL pointer ?
	jz	QAPIS_SameNode		;yes, skip this one.

QAPIS_SubLoop:

	mov	ax,es:[bx.AIS_Length]	;get the length 
	or	ax,ax			;is this the end ?
	jz	QAPIS_SameNode		;have exhausted the list
	cmp	es:[bx.AIS_API],cx	;is it the right API
	jz	QAPIS_FoundAPINode	;yes, got it!
	add	bx,ax			;es:bx -> next API node
	jmp	short QAPIS_SubLoop	;keep looking for node

QAPIS_FoundAPINode:

; check to see if this is a betther handler.

	call	CompareAPILevels	;compare levels
	jnc	QAPIS_SameNode		;current best is still best

; es:bx points to a better node's structure. Save it in DS:SI.

	smov	ds,es			;ds:si = es:bx
	mov	si,bx

QAPIS_SameNode:

	popem	es,bx,ax		;restore

; continue walking down the line.

	les	bx,es:[bx.SCBI_Next]	;load the pointer to the next node.
	jmp	short QAPIS_WalkChainLoop;continue checking.

QAPIS_DoneWithWalk:

; ds:si -> API_Info_Struc of best handler. Compare this with ours and if the
; current one is better or equal retain it.

	smov	es,cs			;es:bx -> to our API info structure
	mov	bx,StubSegOFFSET Our_NB_API_Info
	call	CompareAPILevels	;see if DS:SI still points to best
	jc	QAPIS_Ret		;ES:BX -> best handler's API struc

; DS:SI points to the best, put it in ES:BX

	smov	es,ds			
	mov	bx,si			

QAPIS_Ret:

	popem	cx,si,ds		;save
	ret

QueryAPISupport endp
;----------------------------------------------------------------------------;
; CompareAPILevels:							     ;
;									     ;
; Entry:								     ;
;	ES:BX -> first API Info structure.				     ;
;	DS:SI -> second API Info structure.				     ;
; Exit:									     ;
;	Carry clear if the second structure is still the better handler.     ;
; Uses:									     ;
;	Flags.								     ;
;----------------------------------------------------------------------------;

CompareAPILevels proc near
	
	push	ax			;save
	mov	ax,ds			;is there a valid second guy ?
	or	ax,si
	jz	CAPIL_FirstBest		;first one is the best.

	mov	ax,[si.AIS_Major_Ver]	;major ver of second one
	cmp	ax,es:[bx.AIS_Major_Ver];major ver of first one
	jb	CAPIL_FirstBest		;we have a new node
	ja	CAPIL_Ret		;second is better, carry clear
	mov	ax,[si.AIS_Minor_Ver]	;minor ver of second one.
	cmp	ax,es:[bx.AIS_Minor_Ver];minor ver of first guy.
	jb	CAPIL_FirstBest		;we have a new node
	ja	CAPIL_Ret		;the current one is better
	mov	ax,[si.AIS_Support_Level];level of second guy
	cmp	ax,es:[bx.AIS_Support_Level]
	jae	CAPIL_Ret		;second guy is better

CAPIL_FirstBest:

	stc				;first guy is better

CAPIL_Ret:

	pop	ax			;restore
	ret

CompareAPILevels endp
;----------------------------------------------------------------------------;
; ComapareAXBXtoSIDI:							     ;
;									     ;
; Compare AX:BX (32 bits) to SI:DI (32 bits), the flags return the result of ;
; the comparision as would a CMP AX:BX,SI:DI would do.			     ;
;----------------------------------------------------------------------------;
CompareAXBXtoSIDI  proc near

	cmp	ax,si			;compare high words
	jne	CABTSD_Ret		;either greater or less, flags tell
	cmp	bx,di			;compare low words, flags have result

CABTSD_Ret:

	ret

CompareAXBXtoSIDI  endp
;----------------------------------------------------------------------------;
; SWAPICreateSession:							     ;
;									     ;
; Makes a CREATE_SESSION SWAPI call out.     				     ;
;----------------------------------------------------------------------------;
cProc	SWAPICreateSession,<NEAR,PUBLIC,PASCAL>

cBegin
	mov	ax,SWAPI_CREATE		;create session call
	mov	dx,0ffffh		;call expects a return code
	sti				;interrupts on for this call
	call	MakeSwitchAPICall	;make the Switch API call

; invalidate the call back address.

	mov	cs:[CallBackAddrValid],0;the address is invalid

cEnd
;----------------------------------------------------------------------------;
; SWAPIResumeSession:							     ;
;									     ;
; Makes a RESUME_SESSION SWAPI call out.					     ;
;----------------------------------------------------------------------------;
cProc	SWAPIResumeSession,<NEAR,PUBLIC,PASCAL>

cBegin
	mov	ax,SWAPI_RESUME		;code for ResumeSession
	xor	dx,dx			;call expects no return code
	mov	cx,1			;being run for the first time
	cli				;interrupts off for this call.
	call	MakeSwitchAPICall	;make the Switch API call

; invalidate the call back address.

	mov	cs:[CallBackAddrValid],0;the address is invalid

cEnd
;----------------------------------------------------------------------------;
; SWAPISessionActive:							     ;
;									     ;
; Makes a SESSION_ACTIVE SWAPI call out. 				     ;
;----------------------------------------------------------------------------;
cProc	SWAPISessionActive,<NEAR,PUBLIC,PASCAL>

cBegin
	mov	ax,SWAPI_SESSION_ACTIVE	;code for SessionActive
	xor	dx,dx			;call expects no return code
	mov	cx,1			;being run for the first time
	sti				;interrupts on for this call
	call	MakeSwitchAPICall	;make the Switch API call

; invalidate the call back address.

	mov	cs:[CallBackAddrValid],0;the address is invalid

cEnd
;----------------------------------------------------------------------------;
; SWAPIDestroySession:							     ;
;									     ;
; Makes a DESTROY_SESSION SWAPI call out. 				     ;
;----------------------------------------------------------------------------;
cProc	SWAPIDestroySession,<NEAR,PUBLIC,PASCAL>

cBegin
	mov	ax,SWAPI_DESTROY	;code for DestroySession
	xor	dx,dx			;call expects no return code
	sti				;interrupts on for this call
	call	MakeSwitchAPICall	;make the Switch API call

; invalidate the call back address.

	mov	cs:[CallBackAddrValid],0;the address is invalid


cEnd
;----------------------------------------------------------------------------;
sEnd	StubSeg
end





	

	



⌨️ 快捷键说明

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