📄 woautils.asm
字号:
xor ax,ax ;hiword of count is 0
pushem es,di ;save the pointer
cCall ReadFile,<FileHandle,es,di,ax,cx>
popem es,di ;restore the pointer
jc RestoreSwappedGroupsRet ;cannot proceed with error.
; if the base of the block is 0, we are done
mov ax,es:[di] ;get the low word of base
or ax,es:[di+2] ;the high word of base
jz ReadBlockDone ;we have read back the complate image
; prepare a word selector for reading back the block and read it back.
mov cx,es:[di+2] ;get the hiword of the base
mov dx,es:[di] ;get the low word of the base
mov bx,ArenaRWSel ;load the temp selector
cCall SetSelectorBaseLim64 ;set up with the proper base
mov ArenaRWSel,bx ;save the modified value
mov cx,es:[di+6] ;get the high word of count
mov dx,es:[di+4] ;get the low word of count
xor ax,ax ;need zero for the start offset
cCall ReadFile,<FileHandle,ArenaRWSel,ax,cx,dx>
jc RestoreSwappedGroupsRet ;cannot proceed with error.
; now read back the other blocks.
jmp short ReadBlockLoop ;read in the resto of the blocks
ReadBlockDone:
clc ;successful read back done
RestoreSwappedGroupsRet:
cEnd
;----------------------------------------------------------------------------;
; GetSizeInBytes: ;
; ;
; On entry AX has the size of an object in paragraphs, this routine returns ;
; the size in bytes in AX:BX ;
;----------------------------------------------------------------------------;
GetSizeInBytes proc near
xor bh,bh ;hibyte of hiword will be zero
mov bl,ah ;need the high nibble
shiftr bl,4 ;move it to bit positions 16-19
shiftl ax,4 ;effective mul by 16
xchg ax,bx ;ax:bx has the size in bytes
ret
GetSizeInBytes endp
;----------------------------------------------------------------------------;
; ConvKToBytes: ;
; ;
; On entry AX has the size of an object in KBytes and this routine returns ;
; the size in bytes in AX:BX. ;
;----------------------------------------------------------------------------;
ConvKToBytes proc near
push dx ;save
xor dx,dx ;for the mul
mov bx,1024 ;mult fctor
mul bx ;dx:ax has the result
xchg ax,dx ;ax:dx has the result
mov bx,dx ;ax:bx has the result
pop dx ;restore
ret
ConvKToBytes endp
;----------------------------------------------------------------------------;
; This routine save the state of the EMS page mapping registers if EMS driver;
; is present. ;
;----------------------------------------------------------------------------;
SaveWinEmsContext proc near
cmp EmsFlag,0ffh ;is the EMS driver present ?
jnz @f ;no, nothing to save
mov di,DataOFFSET WinEmsSaveArea
mov ax,4e00h ;want to get the page mapping resgisters
smov es,ds ;ES:DI points to the save area
int 67h ;page map resgisters obtained
@@:
ret
SaveWinEmsContext endp
;----------------------------------------------------------------------------;
; This routine restores the previously saved state of the Ems page mapping ;
; registers, if the EMS drivers is present. ;
;----------------------------------------------------------------------------;
RestoreWinEmsContext proc near
cmp EmsFlag,0ffh ;is the EMS driver present ?
jnz @f ;no, nothing to restore
mov si,DataOFFSET WinEmsSaveArea
mov ax,4e01h ;set map resgister code
int 67h ;the mapper resgisters reprogrammed
@@:
ret
RestoreWinEmsContext endp
;----------------------------------------------------------------------------;
; WhichSwapPathToUse: ;
; ;
; This routine finds out the amount of space that will be needed for swapping;
; out the dos app's context and decides which swap path it should use. ;
; ;
; It will will up the 'DosAppSwapFileName' buffer appropriately, but will ;
; return with carry if no space is available in either places. It wil also ;
; update the global structure for the top entry to reflect what path it is ;
; using. ;
;----------------------------------------------------------------------------;
cProc WhichSwapPathToUse,<NEAR,PUBLIC,PASCAL>
localD WSPSize ;size of swap area
cBegin
; initialize the variable to hold the size of the swap area.
mov off_WSPSize,1024 ;size of IDT area
mov seg_WSPSize,0 ;reset high word
; find out the size of the conventional memory context.
xor ax,ax ;get size only
cCall SaveDosMemory,<ax,ax,ax>;1st two parameters insignificant
add off_WSPSize,ax ;add low word of size
adc seg_WSPSize,dx ;update high word
; Add in the size of the XMS Context. We will have to consider the complete
; XMS size as we have no way of knowing what the actual size will be, at this
; point. However if 'AppUsesXMS' is 0, we will not swap the XMS out and thus
; we will not consider it's size
cmp AppUsesXMS,0 ;did it use XMS ?
jz @f ;no.
mov ax,wptr [XmsBankSize] ;get low word of size
mov dx,wptr [XmsBankSize+2] ;get high word of size
add off_WSPSize,ax ;add low word of size
adc seg_WSPSize,dx ;update high word
@@:
ifdef JAPAN
mov ax,wptr [KkcDataSize] ; get data size of KKC
mov dx,wptr [KkcDataSize+2] ;
add off_WSPSize,ax ;add low word of size
adc seg_WSPSize,dx ;update high word
endif
; find out if there is enough disk space on the first drive.
mov cx,seg_WSPSize ;get low word of size
mov dx,off_WSPSize ;cx:dx has swap area size
mov ax,Swap1MinK ;min area to be left
call ConvKToBytes ;ax:bx has size of space to leave
add dx,bx ;add in low word
adc cx,ax ;cx:ax = desired space
cCall IsEnoughDiskSpace,<DiskSwap1Drive,cx,dx>
jc TryDisk2 ;not enough on disk 1
call GetDosAppSwap1FileName ;fill up file name
mov bl,1 ;1st path to be used
jmp short UpdatePathInfo ;update global block
TryDisk2:
mov cx,seg_WSPSize ;get low word of size
mov dx,off_WSPSize ;cx:dx has swap area size
mov ax,Swap2MinK ;min area to be left
call ConvKToBytes ;ax:bx has size of space to leave
add dx,bx ;add in low word
adc cx,ax ;cx:ax = desired space
cCall IsEnoughDiskSpace,<DiskSwap2Drive,cx,dx>
jc WhichSwapPathToUseRet ;no space on any drive
call GetDosAppSwap2FileName ;fill up file name
mov bl,2 ;second path to be used
UpdatePathInfo:
pushem es,si ;save
push bx ;save
cCall GetSwitcherEntry,<CurrentDosSwapSeed>
jc WhichSwapPathToUseRet ;error, can't find node:can't swapout
mov es,dx ;ignore logical node num in bx
mov si,ax ;es:si points to the desired entry
pop bx ;get back path id
mov es:[si].Path_Id,bl ;save path code
popem es,si ;restore
clc ;no error
WhichSwapPathToUseRet:
cEnd
;----------------------------------------------------------------------------;
; IsEnoughDiskSpace: ;
; ;
; This routine checks to see if the amount of bytes of disk space left is ;
; enough to swap out the dword of bytes that is passed in as a parameter. ;
; Carry is set if there is not enough free space else it is set. ;
;----------------------------------------------------------------------------;
cProc IsEnoughDiskSpace,<NEAR,PASCAL,PUBLIC>
parmB IEDDriveId ;drive ID
parmD SpaceNeeded ;amount of space needed
cBegin
; get the amount of disk space left.
mov ah,36h ;get free space call
mov dl,IEDDriveId ;get the swap drive number
sub dl,40h ;A=1,B=2 etc
int 21h ;get various parameters
xor dx,dx ;need for multiplication
; AX*BX*CX is the no of bytes of free space.
mul bx ;DX:AX has AX*BX
or dx,dx ;is dx already 1 ?
jnz IsEnoughDiskSpaceRet ;will be enough space
mul cx ;DX:AX has amount of free space
; check to see if this is enough
cmp dx,seg_SpaceNeeded ;compare hiwords
jne IsEnoughDiskSpaceRet ;carry set or unset for result
cmp ax,off_SpaceNeeded ;compare low words
; carry set if not enough space or cleared if enough space
IsEnoughDiskSpaceRet:
cEnd
;----------------------------------------------------------------------------;
; AppSwapOutErrHandler: ;
; ;
; This routine is called when an application swap out attempt fails. The ;
; screen had been put into a text mode by a previous grabber call. This ;
; routine displays an error msg across the top of the screen and waits ;
; for a key to be hit. ;
;----------------------------------------------------------------------------;
cProc AppSwapOutErrHandler,<NEAR,PUBLIC,PASCAL>
cBegin
; if a partial swap file had been created for the application, delete it.
mov si,DataOFFSET DosAppSwapFileName;ds:si points to the name
mov dx,si ;ds:dx has the pointer now.
mov ah,41h ;delete file code
int 21h ;delete the file
; print the error message. First home the cursor.
mov ah,0Fh ;get & set the current mode
int 10h ; so that the screen is clear
xor ah,ah ; and the cursor is homed
int 10h ; (works for mode 3 & 7)
mov dx,DataOFFSET WoaAppSwapErr;the error message
mov ah,09h ;display string code
int 21h
; now remove the cursor from the screen.
mov ah,2 ;position cursor
xor bh,bh ;page 0
mov dx,1900h ;position to 25th line
int 10h ;cursor removed.
; now wait for a key to be hit.
mov ax,0C07h ;flush kbd buffer & do a raw read
int 21h
cEnd
;----------------------------------------------------------------------------;
; ResetClassInt15Word: ;
; ;
; This takes an app ID as the parameter and if the INT 15 word in the global;
; structure is the same as the handle then it resets the word. ;
; ;
; This routine must also reset the 'Int15UsershApp' variable if the handle ;
; is the same. ;
;----------------------------------------------------------------------------;
cProc ResetClassInt15Word,<NEAR,PUBLIC,PASCAL>
parmW hAppId ;hApp passed in
cBegin
; get the current word.
cCall GetInt15Word ;get the current ID
cmp ax,hAppId ;does it compare ?
jnz @f ;no.
xor ax,ax ;need to set it to 0
mov Int15UsershApp,ax ;reset the ID
cCall SetInt15Word,<ax> ;reset the word
@@:
cEnd
;----------------------------------------------------------------------------;
; GetInt15Word: ;
; ;
; This routine gets the current value of the INT 15 Users ID saved in the ;
; global switch structure. ;
;----------------------------------------------------------------------------;
cProc GetInt15Word,<NEAR,PUBLIC,PASCAL>,<es,di>
cBegin
mov ax,4a05h ;opcode
mov si,CGET_GLOBAL_SWITCH_DATA
int 2fh ;dx:ax has the long pointer
mov es,dx ;load it into es
mov di,ax ;es:di -> info structure
mov ax,es:[di].Int_15_Users_Id;get the ID
cEnd
;----------------------------------------------------------------------------;
; SetInt15Word: ;
; ;
; This routine sets the current value of the INT 15 Users ID saved in the ;
; global switch structure to the passed in parameter value. ;
;----------------------------------------------------------------------------;
cProc SetInt15Word,<NEAR,PUBLIC,PASCAL>,<es,di>
parmW Value ;value of the word
cBegin
mov ax,4a05h ;opcode
mov si,CGET_GLOBAL_SWITCH_DATA
int 2fh ;dx:ax has the long pointer
mov es,dx ;load it into es
mov di,ax ;es:di -> info structure
mov ax,Value ;get the new value
mov es:[di].Int_15_Users_Id,ax ;set it
cEnd
;----------------------------------------------------------------------------;
; GetNSetCtrlCFlag: ;
; ;
; This routine gets the current state of the CTRL+C flag and sets it off ;
; after saving the state. The state would be restored in the stub segment ;
; and also before the next EnableDos call. ;
; ;
; Entry: ;
; DS - Winoldap's Data segment. ;
; No other registers relevant. ;
;----------------------------------------------------------------------------;
cProc GetNSetCtrlCFlag,<NEAR,PUBLIC,PASCAL>
cBegin
; flush the keyboard buffer
mov ax,0c00h ;flush buffer code
int 21h
; get the current state of the CtrlC flag.
mov ax,3300h ;get CTRL+C flag
int 21h ;state in DL.
mov fBreak,dl ;save it
; now set the state off.
mov ax,3301h ;set the blag
xor dl,dl ;to off
int 21h ;flag set off
cEnd
;----------------------------------------------------------------------------;
; RestoreCtrlCFlag: ;
; ;
; Restores the state of the CTRL+C flag that had been saved before. ;
; ;
; Entry: ;
; DS - Winoldap's Data segment. ;
; No other registers relevant. ;
;----------------------------------------------------------------------------;
cProc RestoreCtrlCFlag,<NEAR,PUBLIC,PASCAL>
cBegin
; restore the saved state
mov ax,3301h ;set the blag
mov dl,fBreak ;get the saved state.
int 21h ;flag restored
cEnd
;----------------------------------------------------------------------------;
; This routine invokes the error manager. ;
;----------------------------------------------------------------------------;
ErrorHandler:
call ErrorManager ;this never returns
;----------------------------------------------------------------------------;
sEnd Code
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -