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

📄 woautils.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1985-1991
; *                      All Rights Reserved.
; */


;----------------------------------------------------------------------------;
; This file has utility programs which are invoked mostly from WOAMGR.ASM    ;
;									     ;
; History:								     ;
;									     ;
;	 Fri June-15-1990.	-by-  Amit Chatterjee [amitc]		     ;
;	 Adapted for the Dos Task Switcher.				     ;
;									     ;
;        Mon June-26-1989.  	-by-  Amit Chatterjee [amitc]		     ;
;        Created for Windows. (Added the History legend)       		     ;
;----------------------------------------------------------------------------;

	?win = 0

	?DF = 1
	.xlist
	include cmacros.inc
	include woasegs.inc
	include macros.mac
	include	njmp.mac
	include dosx.inc
	include	woapif.inc
	include woaerr.inc
	include	woaarena.inc
	include woaswch.inc
	.list

	.286p

	public	SaveWinEmsContext
	public	RestoreWinEmsContext
	public	GetSizeInBytes
	public	ConvKToBytes

;----------------------------------------------------------------------------;
; define external FAR winoldap procedures.				     ;
;----------------------------------------------------------------------------;

sBegin	Data

;----------------------------------------------------------------------------;
; define the global variables defined elsewhere				     ;
;----------------------------------------------------------------------------;

externW	ArenaWalkSel			;temp selector for walkimg arena chain
externW	ArenaRWSel			;temp sel for reading/writing arenas
externW	XmsHeapWalkSel			;scratch selector for walking xms heap
externW WoaStubSel			;sel for current loaction of stub code
externB	EmsFlag				;EMS present or not.
externB fBreak				;state of CTRL+C flag.
externW	HighMemXmsHandle		;handle of the high heap XMS block
externB	DosAppSwapFileName		;name of the dos app swap file
externB ErrorType			;save area for error code
externW WoaCsSize			;size of protected mode code seg
externW WoaDsSize			;size of winoldap data segment
externW StubSegSize			;size of real mode stub segment
externB DiskSwap1Drive			;swap drive index for fast path
externB DiskSwap2Drive			;swap drive index for slow path
externW	Swap1MinK			;space to be left on 1st drive
externW Swap2MinK			;space to be left on second drive
externW Int15UsershApp			;hApp of INT 15 user
externW hApp				;windows handle for this instance
externD XmsBankSize			;size of apps XMS bank
externW LowMemParaSize			;para size of available memory
externW LowMemArenaSel			;pointer to the available memory arena
externW LowMemSel			;sel for the start of the vail block
externW	SizeReservedArea		;size of area reserved area at heap st.
externW CurrentDosSwapSeed		;swap file seed being used now
externW	AppUsesXMS			;app used it's allocated XMS or not

ifdef	JAPAN
externD KkcDataSize			; Data area size of KKC
endif

	;-------------------------------------------------------;
	; define any locally used constants			;
	;-------------------------------------------------------;


	;-------------------------------------------------------;
	; define any locally used constants			;
	;-------------------------------------------------------;

		ZERO_BLOCK_SIZE equ 128

	;-------------------------------------------------------;
	; define any external contants.				;
	;-------------------------------------------------------;

		externB	  WoaAppSwapErr		;(WOAERR.ASM)
		externA   IS_WINOLDAP_ACTIVE	;(WOAMGR.ASM)

;---------------------------------------------------------------------------;
; now define the other global variables that will be needed.		    ;
;---------------------------------------------------------------------------;
		

;---------------------------------------------------------------------------;
; now define the other variables that will be needed.			    ;
;---------------------------------------------------------------------------;

WinEmsSaveArea		db 256 dup (0)	;save windows EMS context here
globalW AppXmsBaseSel,0			;selector to base of apps XMS block


		;-------------------------------------------;
		; Debug messages used if DEBUGMODE is set.  ;
		;-------------------------------------------;

ifdef	DEBUGMODE

endif	;DEBUGMODE

sEnd Data

;----------------------------------------------------------------------------;
; now declare the existence of the realmode stub segment and the variables   ;
; that we want to reference here.					     ;
;----------------------------------------------------------------------------;

createSeg   _WOARLMSEG,StubSeg,word,public,code
sBegin	StubSeg

sEnd	StubSeg

;----------------------------------------------------------------------------;
; we define the switch_cs macro here.					     ;
;----------------------------------------------------------------------------;

switch_cs macro
	local	_x
	local	_y
_x	proc	far
	lea	ax,_y
	push	ax
	ret
_y:
_x	endp
	endm

;----------------------------------------------------------------------------;

sBegin	Code

	assumes	cs,Code
	assumes	ds,Data
	assumes	es,nothing

	;-------------------------------------------------------;
	; external OLDAPP procedures.			        ;
	;-------------------------------------------------------;

	externNP	DeleteFile		;(WOAFILE.ASM)
	externNP	ErrorManager		;(WOAERR.ASM)
	externNP	CreateFile		;(WOAFILE.ASM)
	externNP	LseekFile		;(WOAFILE.ASM)
	externNP	OpnFile			;(WOAFILE.ASM)
	externNP	ReadFile		;(WOAFILE.ASM)
	externNP	WriteFile		;(WOAFILE.ASM)
	externNP	CloseFile		;(WOAFILE.ASM)
	externNP	DeleteFile		;(WOAFILE.ASM)
	externNP	SetNormalAttributes	;(WOAFILE.ASM)
	externNP	SetHiddenAttributes	;(WOAFILE.ASM)
	externNP	GetSelectorBase		;(WOAPMRM.ASM)
	externNP	SetSelectorBaseLim64	;(WOAPMRM.ASM)
	externNP	GetDosAppSwap1FileName	;(WOAMGR.ASM)
	externNP	GetDosAppSwap2FileName	;(WOAMGR.ASM)
	externNP	SaveFirstDosBlock	;(WOAPMRM.ASM)
	externNP	RestoreFirstDosBlock	;(WOAPMRM.ASM)
	externNP	RestoreAppXmsContext	;(WOAPMRM.ASM)
	externNP	AppendUniqueNumber	;(WOAMGR.ASM)
	externNP	ZeroOutMemory		;(WOAPMRM.ASM)
	externNP	GetSwitcherEntry	;(WOAPMRM.ASM)

;----------------------------------------------------------------------------;
; SaveDosMemory:							     ;
;									     ;
; This routine takes the name of the dos swap file as the input. It writes   ;
; the first DOS block (or a part of it in real mode) to the swap file and    ;
; then traverses memory looking for non zero values and then swaps them      ;
; out in groups.						             ;
;									     ;
; This routine also takes an OpCode, SDMOpCode which if 0 returns just the   ;
; size needed to save the memory and if non zero actually saves the memory.  ;
; If the OpCode is 0, the first parameter is insignificant.		     ;
;----------------------------------------------------------------------------;

cProc	SaveDosMemory,<NEAR,PUBLIC,PASCAL>

	parmD	lpFileName		;name of the swap file
	parmB	SDMOpCode		;save or get size 

	localW	FileHandle		;handle of the swap file
	localV	NodeHeader,8		;DWORDs of base and lock size
	localD	CurrentSize		;size of the node being prepared
	localD	CurrentBase		;base of the node being prepared
	localD	SizeLeft		;amount of memory left
	localD	SDMSize			;size of save area

cBegin

	cld				;do not take chances with this

; Initialize the SDMSize field

	mov	seg_SDMSize,0
	mov	off_SDMSize,4		;4 bytes for XMS link

; create the swap file, at this point the file should not be existing, but
; we do not care to check.  Ifthe OpCode is for get size only, we will not
; try to create any file.

	cmp	SDMOpCode,0		;get size only
	jz	SDMByPassIO1		;yes
	xor	ax,ax			;want to create a normal file
	cCall	CreateFile,<lpFileName,ax>
	jc	SaveDosMemoryRet	;cannot proceed with error.
	mov	FileHandle,ax		;save the handle of the swap file

; we need to leave 4 bytes at the start of the file for storing the offset 
; of the start of the XMS swap out area. This is actually needed only in 
; real mode winoldap where the XMS memory has to be swapped in first.

	xor	ax,ax			;need zeros for hiword of offset/org.

ifdef	JAPAN
	mov	cx,8			;offset for seek
else
	mov	cx,4			;offset for seek
endif

	cCall	LseekFile,<FileHandle,ax,cx,ax>

SDMByPassIO1:

; we will save the first block arena selector separately and then skip over
; the _DATA and _TEXT segments. The following routine will do that, it will
; return the size of the block skipped over (top PDB, _DATA & _TEXT) in AX
; and the size wriiten to file (actuall 16) in CX:DX.

	cCall	SaveFirstDosBlock,<FileHandle,SDMOpCode>;saves the block containing woa stub
	jc	SaveDosMemoryRet	;cannot proceed with error.

; AX has the para size of the first block. CX:DX has the size wriiten out.
; Calculate the amount of memory left to be swapped.

	add	off_SDMSize,dx		;add in size wriitent out
	adc	seg_SDMSize,cx		;update hiword

	sub	ax,LowMemParaSize	;get difference
	neg	ax			;convert to positive
	call	GetSizeInBytes		;AX:BX has the size
	mov	seg_SizeLeft,ax 	;save hiword
	mov	off_SizeLeft,bx 	;save loword

; SetArenaWalkSel to the start of the block from where we want to swap on 
; (_WOARLMSEG) 
	       
	mov	ax,_WOARLMSEG		;want to swap from here
	mov	ArenaWalkSel,ax		;save it

; call the generalized routine to swap out the non zero blocks

	cCall	SwapOutNonZeroBlocks,<FileHandle,ArenaWalkSel,SizeLeft,SDMOpCode>
	jc	SaveDosMemoryRet	;cannot proceed with error.

; update the size and add 8 for the following node too. The above routine 
; would have returned the size written out in DX:AX

	add	ax,8			;for the terminating header
	adc	dx,0			;update hiword
	add	off_SDMSize,ax		;update total size
	adc	seg_SDMSize,dx		;update hiword

	cmp	SDMOpCode,0		;get size only ?
	jz	SaveDosMemoryRet	;yes.

; need to write out a dummy header to mark the end of the memory image area

	smov	es,ss			;need to access header structure
	lea	di,NodeHeader		;es:di points to the node header area
	push	di			;save the offset
	xor	ax,ax			;need to zero it out
	mov	cx,4			;size of header	in words
	rep	stosw			;initialize it
	pop	di			;es:di points to the NodeHeader
	mov	cx,8			;8 bytes of header to write
	xor	dx,dx			;hiword of number of bytes to write
	cCall	WriteFile,<FileHandle,es,di,dx,cx>

SaveDosMemoryRet:

	mov	ax,FileHandle		;need to return the handle of the file

; if the SDMOpCode is zero, return with the size in DX:AX.

	pushf				;save state of carry flag
	cmp	SDMOpCode,0		;get size only ?
	jnz	@f			;no.
	mov	dx,seg_SDMSize		;get hiword of size
	mov	ax,off_SDMSize		;get low eord of size
@@:
	popf				;restore carry flag (success or failure code)

cEnd
;----------------------------------------------------------------------------;
; SwapOutNonZeroBlocks:							     ;
; 									     ;
; This routine takes the following parameters:				     ;
;	 								     ;
;	FileHandle	---	Data will be written into this file	     ;
;	Start sel	---	Swap out area starts here (offset 0)	     ;
;	Size		---	Total size of the area in bytes (dword)	     ;
;       SONZBOpCode	---     If 0 will just get the swap area size.
;									     ;
; It scans the range specified for non zero blocks of zeros and writes out   ;
; swap groups (block preeceded by 8 byte header) to the file. It returns     ;
; with carry set if the writes failed.					     ;
;----------------------------------------------------------------------------;

cProc	SwapOutNonZeroBlocks,<NEAR,PUBLIC,PASCAL>,<es>

	parmW	FHandle			;handle for the file
	parmW	StartSel		;start selector
	parmD	SLeft			;size for the block
	parmB	SONZBOpCode		;get size only or not.

	localV	NHeader,8		;DWORDs of base and lock size
	localD	CSize			;current swap group size
	localD  CBase			;current swap group base
	localW	LoopSize		;size being tested in the loop
	localW	RestartOffset		;restart point
	localD	SONZBSize		;size of the swap area.

cBegin

; initialize the swap area size variable.

	mov	seg_SONZBSize,0
	mov	off_SONZBSize,0

; initialize the base and size for the next swap group

	mov	bx,StartSel		;get the selector
	mov	ArenaWalkSel,bx		;save it
	call	GetSelectorBase		;get the base in cx:dx

	mov	seg_CSize,0		;initialize current size of swap node
	mov	off_CSize,0		;initialize 32 bits
	mov	seg_CBase,cx		;save high word of current base
	mov	off_CBase,dx		;save low word of current base

ScanForZerosLoop:

	mov	es,ArenaWalkSel		;get the selector into es
	mov	ax,seg_SLeft		;are we all done ?
	or	ax,off_SLeft		
	njz	WriteSwapGroup		;write the group and end

; need to scan the segment for zeros.

	mov	cx,8000h		;assume complete segment (in words)
	cmp	seg_SLeft,0		;are we in the last 64k seg ?
	jnz	start_check_for_0	;no.
	mov	cx,off_SLeft		;get the size left to look.
	shr	cx,1			;convert to words

start_check_for_0:

	mov	LoopSize,cx		;save the size in words that we test

; scan for zeros in this segment.

	xor	ax,ax			;looking for zeros.
	xor	di,di			;start at top of segment.

continue_check_for_zero:

	repne	scasw			;look for zero.
	jcxz	go_to_next_seg		;no zeros found.

; the zero stretch should atleast be ZERO_STRETCH_SIZE long.

	inc	cx			;ignore the match.
	sub	di,2			;start of the zeros.
	mov	bx,di			;save

; look ahead ZERO_STRTECH_SIZE  or to the end of segment which ever is smaller

	pushem	ax,bx
	mov	ax,cx			;words left in the segment
	shl	ax,1			;convert to bytes
	mov	bx,ZERO_BLOCK_SIZE	;min zero block size
	jc	enough_in_segment	;complete segment is left
	cmp	ax,bx			;which is smaller ?
	jbe	look_ahead_size_obt	;ax has look ahead size

enough_in_segment:

	mov	ax,bx			;bx is min

look_ahead_size_obt:

	mov	dx,ax			;have it in dx
	popem	ax,bx

; from di onwards we want to have a block of DX size as 0s

	add	di,dx			;look ahead
	jc	scan_block_for_all_0s	;goes into next seg, see if its all 0
	cmp	byte ptr es:[di],0	;is it still 0 ?
	jz	scan_block_for_all_0s	;possibly 0 stretch obtained.
	sub	di,dx			;take it back to start of block

⌨️ 快捷键说明

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