📄 cwswapr.asm
字号:
;
mov swap_prep.handle,dx
mov ax,USE_XMS
mov swap_prep.swapmethod,al
ret
;
; No XMS allowed, or XMS not present/full. Try File swap.
;
prep_no_xms:
test pmethod,XMS_FIRST
jz check_file
jmp check_ems
;
check_file:
test pmethod,USE_FILE
jnz prep_do_file
jmp prep_no_file
;
prep_do_file:
push ds
; IF ptrsize
; lds dx,swapfname
; ELSE
mov dx,OFFSET SwapFileName
; ENDIF
mov cx,2 ; hidden attribute
test pmethod,HIDE_FILE
jnz prep_hide
xor cx,cx ; normal attribute
;
prep_hide:
mov ah,3ch ; create file
test pmethod,CREAT_TEMP
jz prep_no_temp
mov ah,5ah
;
prep_no_temp:
int 21h ; create/create temp
jnc prep_got_file
cmp ax,3 ; see if path not found (bad TEMP setting)
jne prep_no_file
mov ah,19h ; get current disk
int 21h
add al,'A' ; convert to ASCII drive
mov bx,dx
mov BYTE PTR ds:[bx],al ; default to current drive root
mov BYTE PTR ds:[bx+1],':'
mov BYTE PTR ds:[bx+2],'\'
mov BYTE PTR ds:[bx+3],0 ; zero out path name and retry
; mov BYTE PTR ds:[bx],0 ; zero out path name and retry
jmp SHORT prep_hide
;
prep_got_file:
mov bx,ax ; handle
;
; save the file name
;
pop es
push es
mov di,offset swap_prep.sp_swapfilename
mov cx,81
mov si,dx
rep movsb
;
pop ds
mov swap_prep.handle,bx
;
; preallocate the file
;
test pmethod,NO_PREALLOC
jnz prep_noprealloc
test pmethod,CHECK_NET
jz prep_nonetcheck
;
; check whether file is on a network drive, and don't preallocate
; if so. preallocation can slow down swapping significantly when
; running on certain networks (Novell)
;
mov ax,440ah ; check if handle is remote
int 21h
jc prep_nonetcheck ; assume not remote if function fails
test dh,80h ; DX bit 15 set ?
jnz prep_noprealloc ; remote if yes
;
prep_nonetcheck:
mov dx,totparas
mov cl,4
rol dx,cl
mov cx,dx
and dx,0fff0h
and cx,0000fh
sub dx,1
sbb cx,0
mov si,dx ; save
mov ax,4200h ; move file pointer, absolute
int 21h
jc prep_file_err
cmp dx,cx
jne prep_file_err
cmp ax,si
jne prep_file_err
mov cx,1 ; write 1 byte
mov ah,40h
int 21h
jc prep_file_err
cmp ax,cx
jne prep_file_err
;
mov ax,4200h ; move file pointer, absolute
xor dx,dx
xor cx,cx ; rewind to beginning
int 21h
jc prep_file_err
;
prep_noprealloc:
mov ax,USE_FILE
mov swap_prep.swapmethod,al
ret
;
prep_file_err:
mov ah,3eh ; close file
int 21h
mov dx,offset swap_prep.sp_swapfilename
mov ah,41h ; delete file
int 21h
;
prep_no_file:
mov ax,-1
mov swap_prep.swapmethod,al
ret
;
prep_swap endp
;
COMMENT !
O_RUNX:
pusha
push ds
push es
mov bx,SWAP_TEXT
mov ax,0ff06h
int 31h
jc SwapErr
push ax ; save -> swap routine data
mov es,ax
mov BYTE PTR es:[params],0 ; kill leftovers
; get length of first passed parameter
push 1
call __parclen
add sp,2
or ax,ax
je med3 ; zero length
; get first parameter string in dx:ax
push 1
call __parc
add sp,2
pop es
push es
mov di,OFFSET params ; es:di -> parameter storage
push ds ; save ds -> DGROUP
mov ds,dx
mov si,ax ; ds:si -> character string
mov ax,'/'+256*'C' ; put in /C for command.com, transient command
stosw
mov al,' '
stosb
xparamloop1:
movsb
cmp BYTE PTR ds:[si-1],0 ; see if hit null terminator
jne xparamloop1
pop ds ; restore ds -> DGROUP
dec di ; make di -> null terminator in case of second parameter
; get length of second passed parameter
push 2
call __parclen
add sp,2
or ax,ax
je med3 ; zero length
; get second parameter string in dx:ax
push 2
call __parc
add sp,2
mov ds,dx
mov si,ax ; ds:si -> character string
pop es
push es ; es:di -> current position of stored string
mov al,' '
stosb ; put in space
xparamloop2:
movsb
cmp BYTE PTR ds:[si-1],0 ; see if stored null terminator
jne xparamloop2
jmp SHORT med3
END COMMENT !
;SWPRUNCMD:
;OverLay:
CWSwap_:
pushad
push ds
push es
cld
;**JW**
;works upto here...
; pop es
; pop ds
; popa
; db 66h
; retf
push eax ; save -> command
mov bx,SWAP_TEXT
mov ax,0ff06h
int 31h
; jc SwapErr
push ax ; save -> swap routine data
mov es,ax
mov BYTE PTR es:[params],0 ; kill leftovers
; get length of passed parameter
; push 1
; call __parclen
; add sp,2
; or ax,ax
; je med3 ; zero length
; get parameter string in dx:ax
; push 1
; call __parc
; add sp,2
; mov ds,dx
; mov si,ax ; ds:si -> character string
pop es
pop esi ; ds:esi -> command
push es
mov di,OFFSET params ; es:di -> parameter storage
mov al,'/'
mov ax,'/'+256*'C' ; put in /C for command.com, transient command
stosw
mov al,' '
stosb
paramloop:
mov al,ds:[esi]
mov es:[di],al
inc esi
inc di
cmp BYTE PTR ds:[esi-1],0 ; see if stored null terminator
jne paramloop
med3:
pop ds ; ds -> swap routine data
ASSUME ds:SWAP_TEXT,es:SWAP_TEXT
mov AliasSelector,ds
mov IntVectorSelector,0
mov LowMemSelector,0
mov WedgeMemSelector,0
xor bh,bh
mov ah,3
int 10h ; ready cursor size, position, and shape
mov CursorSize,cx
mov CursorRowCol,dx
; get selector for interrupt vector table
mov ax,0ff03h ; GetSel
int 31h
jc SwapErr
xor cx,cx ; point selector at 0:0 for interrupt vectors
mov dx,cx
mov di,400h
mov si,cx
mov ax,0ff09h ; SetSelDet
int 31h
mov INTVectorSelector,bx ; save selector
; get protected mode PSP of program
mov ah,62h ; get PSP
int 21h
mov PMPSP,bx ; save protected mode PSP
mov ds,bx ; ds -> protected mode psp
mov ax,ds:[EPSP_RealENV] ; real mode environment block pointer
mov es:EnvironmentPointer,ax
mov edx,ds:[EPSP_INTMem] ; interrupt/exception vectors linear address
mov ax,0ff03h ; GetSel
int 31h
jc SwapErr
mov ecx,(256*6)+(32*6)+400h ; selector limit
mov ax,0ff0ah ; SetSelDet32
int 31h
mov ds,bx ; ds -> selector
mov si,(256*6)+(32*6) ; si -> past protected mode interrupt and exception vectors
mov di,OFFSET INTVectorTable ; es:di -> real mode vector table storage
mov cx,256
rep movsd ; save real mode vector table
; release interrupt/exception vectors selector
mov ax,0ff04h ; RelSel
int 31h
push es
pop ds
; get/save memory allocation strategy
mov ax,5800h ; get allocation strategy
int 21h
mov AllocStrat,ax ; save original strategy
; change memory allocation strategy to last fit
mov ax,5801h ; set allocation strategy
mov bx,2 ; use highest available block that fits
int 21h
; get wedge memory for EXEC'ing
mov bx,(WedgeSpace+15)/16
mov ax,0ff21h
int 31h
jnc savewedge
pushf ; setup stack so restore strategy still works properly
push ax
jmp NEAR PTR restalloc ; error in dos allocation
; save the wedge memory segment and selector
savewedge:
; mov RealRegs.Real_FS,ax ; save real mode segment of wedge memory
; alternate save real mode segment of wedge memory into bx since NT doesn't restore FS properly
mov WORD PTR RealRegs.Real_EBX,ax
mov WedgeMemSelector,dx
; copy wedge code to wedge segment
mov es,dx
xor di,di
mov si,OFFSET WedgeStart
mov cx,WedgeSpace
push cx
shr cx,2
rep movsd
pop cx
and cx,3
rep movsb
push ds
pop es
; track if DPMI or non-, to determine where MCB is in relation to allocation
mov ax,0ff00h
int 31h
and di,8 ; mask to DPMI bit
mov WORD PTR RealRegs.Real_EDX,di ; save real mode flag
; get DOS memory for moving code down for real mode execution
mov bx,(((OFFSET CodeEnd-OFFSET CodeStart)+15))/16 ; amount of low memory needed
mov ax,0ff21h
int 31h
pushf ; save allocation error code
push ax ; save segment
; restore memory allocation strategy to original
restalloc:
mov ax,5801h ; set allocation strategy
mov bx,AllocStrat ; use highest available block that fits
int 21h
pop ax ; restore segment
popf ; restore allocation error code
jnc GotMemory
; error using swapper
SwapErr:
mov ax,SWAPPERERROR
mov WORD PTR es:RealRegs.Real_EAX,ax ; get return value
jmp NEAR PTR Done
; got low DOS memory for code/data transfer, ax == segment, dx == selector
; transfer code down to it
GotMemory:
mov WORD PTR RealRegs.Real_EAX,SWAPPERERROR ; init return value
mov RealRegs.Real_CS,ax ; save real mode segment
mov RealRegs.Real_IP,OFFSET NowInReal ; transfer address in low memory
mov es,dx ; es -> low memory selector
mov LowMemSelector,dx
xor di,di
mov si,OFFSET CodeStart
mov ax,(OFFSET CodeEnd-OFFSET CodeStart)
mov cx,ax
shr cx,2
rep movsd
mov cx,ax
and cx,3
rep movsb
push ds
pop es ; es -> swap data
;**JW**
;
;INC exec counter.
;
; int 3
mov ah,62h ; get PSP
int 21h
push ds
mov ds,bx ; ds -> protected mode psp
lds bx,ds:[EPSP_ExecCount]
inc byte ptr[bx]
pop ds
; transfer to low DOS memory real mode operation
mov edi,OFFSET RealRegs ; es:[e]di -> real mode register structure
; mov ax,0ff02h ; FarCallReal
; int 31h
;**JW**
;
;Have to use DPMI far call function now because we've shut off CauseWay specific
;functions.
;
mov ax,301h
xor cx,cx
xor bx,bx
mov es:word ptr[di+Real_SP],0
mov es:word ptr[di+Real_SS],0
int 31h
;**JW**
;
;DEC exec counter.
;
RestoreExecCount:
mov ah,62h ; get PSP
int 21h
push ds
mov ds,bx ; ds -> protected mode psp
lds bx,ds:[EPSP_ExecCount]
dec byte ptr[bx]
pop ds
; real mode code will return here
; stack holds return value
Done:
xor bh,bh
mov dx,cs:CursorRowCol
mov ah,2 ; set cursor position
int 10h
mov cx,cs:CursorSize
mov ah,1 ; set cursor size and shape
int 10h
mov di,WORD PTR cs:RealRegs.Real_EAX ; get return value
mov bx,cs:AliasSelector ; release aliased selector
or bx,bx
je Adios
mov ax,0ff04h ; RelSel
int 31h
mov bx,cs:INTVectorSelector ; release interrupt vector selector
or bx,bx
je Adios
mov ax,0ff04h ; RelSel
int 31h
mov dx,cs:WedgeMemSelector ; release wedge memory
or dx,dx
je Adios
mov ax,0ff23h ; RelMemDOS
int 31h
mov dx,cs:LowMemSelector ; release low memory
or dx,dx
je Adios
mov ax,0ff23h ; RelMemDOS
int 31h
Adios:
pop es
pop ds
; push di
; xor ah,ah
; or di,di
; sete al
; push ax
; call __retni ; return value as integer to clipper
; add sp,2 ; get return value off of stack
popad
;**JW**
;Need to do a 32-bit far return to match the call.
db 66h
retf
; this part is executing in low DOS memory real mode
; fs -> wedge memory segment
; dl is nonzero if DPMI environment
NowInReal = $
; DB 66h
; retf
; nop
; nop
; int 3
mov fs,bx ; wedge memory segment to fs (NT bug workaround)
; swap original interrupt vector table with current
cli
mov cx,256
push cs
pop ds
xor di,di
mov es,di ; es:di -> interrupt vector table
mov si,OFFSET IntVectorTable
vectloop:
mov eax,ds:[si]
xchg eax,es:[di]
add di,4
mov ds:[si],eax
add si,4
loop vectloop
sti
push cs
pop es
; reset mouse driver
xor ax,ax
int 33h
; int 3
; save DPMI flag status
mov DPMIFlag,dl
; get real mode PSP of program
mov ah,62h ; get PSP
int 21h
mov PSP,bx
; seek out EXE pathspec from environment block
mov ds,bx ; ds -> PSP
mov ax,ds:[2ch] ; get original PSP environment pointer
mov es:PSPEnvironPtr,ax ; save original PSP environment pointer
mov ax,es:EnvironmentPointer
mov ds:[2ch],ax ; update PSP environment pointer
mov ds,ax ; ds -> real mode PSP environment block
xor si,si ; ds:si -> start of environment
endloop:
lodsb ; get environment char
or al,ds:[si] ; merge in next char
jne endloop ; not at end of environment block
add si,3 ; si -> start of EXE file path
mov di,si ; save -> start
xor bx,bx ; init end of char pointer
pathloop:
lodsb ; get char of file path
or al,al ; see if at end
je calcpath ; yes
cmp al,'\' ; see if directory indicator
jne pathloop ; no
mov bx,si ; save -> char past directory
jmp SHORT pathloop
calcpath:
mov si,di ; ds:si -> start of file path
mov di,OFFSET SwapFileName ; es:di -> swap file name slot
or bx,bx ; see if any path
je calcdone ; no
calcloop:
movs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -