📄 woarlm.asm
字号:
mov ax,WoaSegResizeBlock ;segment of block to resize
; first we must save the size.
dec ax ;point to DOS arena segment
mov es,ax
mov ax,wptr es:[3] ;get areana size in paras
mov OriginalDosBlockSize,ax ;save it
; at this point calculate the size of the swap area for the TestMemoryRegion
; switcher api call. The swapping starts at the current CS and the size in
; paras is:
;
; OriginalDosBlockSize - (CS - WoaSegResizeBlock)
mov bx,cs ;get our CS
sub ax,bx ;based on above formula
add ax,WoaSegResizeBlock ;total para size of swap area from CS:0
mov WoaSwapAreaParaSize,ax ;save it
; also retrive the arena type and mark it as the last one
mov al,es:[0] ;exchange with the current type
mov OriginalBlockType,al ;save the actual arena type
mov es,WoaSegResizeBlock ;want to resize the block
mov bx,WoaSizeReservedArea ;size of any reserved area
add bx,GrabberParaSize ;add in the size of the grabber context
;----------------------------------------------------------------------------;
; add WoaAppNumber to this value, so that the memory locked by the stub will ;
; be progressively more ensuring that none of the oldapps are given the same ;
; PSP by DOS ;
;----------------------------------------------------------------------------;
add bx,WoaAppNumber ;extra para, 2nd app onwards
ifdef JAPAN
push cx ;
mov cx,KkcBufferSize ;
or cx,cx ; not installed KKC ?
jz @f ; yes
mov ax,WoaSegResizeBlock ;
add ax,bx ;
mov KkcBufferSeg,ax ; save buffer segment
add bx,cx ; add buffer size using to save KKC state
@@:
pop cx
endif
;----------------------------------------------------------------------------;
mov ax,4a00h ;resize function
int 21h ;area released for WOA
; initialize our Switcher API handler module.
cCall InitSwitcherAPI
; get and save long pointers to the InDos and ErrorMode flags.
call GetDosFlags ;get the flag variables
; now let grabber hook INT 10 if it is loaded
cCall GrabberEnableSave ;grabber hooks int 10
; hook all the vectors that WOA wants to trap
call HookIntVectors ;hooks relevant vectors
; now set the mode to a known one and the requested no of lines per screen.
mov ax,WoaStartScreenLines ;start up no of lines
; if the no of lines is not 25,43 or 50 validate it.
call PruneNumLines ;get a valid value
mov WoaStartScreenLines,ax ;save the one num we will use
cCall GrabberInitScreen ;initialize the display
; if HIMEM is installed, then get the address of the XMS entry point. This
; will be needed to set the correct state of the A20 line.
call GetXmsHandler ;saves the call address
; if XMS handling is to be done, call the XMS initializer
call StartXms ;initialize if needed
; set up ES:BX to point to the parameter block
mov bx,StubSegOFFSET WoaParamBlock
smov es,ds ;ES:BX points to parameter block
; set the environment segment in the parm block from the one in the heap
; owners pdb.
push es ;save
mov es,WoaPSP ;get the owners PDB
mov ax,es:[2ch] ;get the environment segment
pop es ;es:bx points to param block
mov es:[bx],ax ;save the environment segment
; now we need to save various dos or bios related state befor we start the
; old app so that we can restore these states when we switch back to windows
call SaveWinDosBiosStates ;save various states
; initialize the 'TsrActive' flag, it will be set only if a TSR is activated
mov cs:[TsrActive],0 ;is there a tsr to handle ?
; before invoking the Old App, restore the state of the HP system
push es ;save
cCall SaveWindowsHPState ;must be restored before going back
popem es ;restore
; clear out pending CTRL+Cs, if any.
mov ax,0c00h ;flush keyboard
int 21h
; reset the CTRL+C flag state now.
mov ax,3301h ;set CTRL+C flag
mov dl,WoafBreak ;get the startup flag
int 21h ;set the start up state
;----------------------------------------------------------------------------;
; do the Create_Session switch API call.
cCall SWAPICreateSession
jz CreateSessionSucceeded ;ok to go ahead
; the create session call failed. Exit with an appropriate error code.
stc ;EXEC fails
mov ax,ER_SWAPI_CREATE_FAILS;error subcode
jmp short ExecReturns ;skip over the EXEC call
CreateSessionSucceeded:
; do a resume session call.
cCall SWAPIResumeSession
; do a sesssion active call.
cCall SWAPISessionActive
;----------------------------------------------------------------------------;
; point DS:DX to the file to execute
mov bx,StubSegOFFSET WoaParamBlock
mov dx,StubSegOFFSET WoaPath;DS:DX points to file to execute
; switch to a temporary stack before execing.
cli ;mask off interrupts
smov ss,cs ;stack is in our segment
mov sp,StubSegOFFSET WoaExecStackTop
sti ;restore interrupts.
mov ax,4b00h ;exec code
int 21h ;pass control to child.
ExecReturns:
; make sure DS is same as CS at this point
smov ds,cs ;ds has stub segment
; the stack might have changed, so reload it
mov ss,WoaRlmEntrySS ;get the entry point stack
mov sp,WoaRlmEntrySP ;get the entry point stack pointer
; a terminate and stay resident call might have been made, if so handle it
; (we basically wait in a loop till the user actually exits the TSR)
pushf ;push the flag before comparision
push ax ;save 4b return code
;----------------------------------------------------------------------------;
; make a DestroySession Switch API call.
cCall SWAPIDestroySession
;----------------------------------------------------------------------------;
; restore the state of the A20 line if the application had turned it off (done
; only if HIMEM is installed.
call SetCorrectA20State ;sets A20 back on if HIMEM installed
; turn the CTRL+C flag off, so that if we decide to put up the TSR pop-up &
; decide to stay on for a while longer no one will forcibly abort us.
mov ax,3301h ;set CTRL+C flag
xor dl,dl ;to off
int 21h ;break flag turned off
pop ax ;restor return code
cmp cs:[TsrActive],0ffh ;is there a tsr to handle ?
jnz NoTsrActive ;no.
popf ;donot need them now
; a TSR is active, allocate a fresh stack block and move the stack to it
mov ah,48h ;code to allocate memory block
mov bx,64 ;1K for temporary stack
int 21h ;do the allocation
mov cs:[TempStack],ax ;save segment
; get back exec return code and flag, they must be saved on the new stack
mov bx,1000 ;offset of start stack top
mov ss,ax ;switch stack
mov sp,bx ;ss:sp in temporary stack
; now put up the dialog box and wait
call ProcessTsr ;handle the tsr if any
smov ds,cs ;go back to own segment
; go back to the entry level stack
mov ss,WoaRlmEntrySS ;get the entry point stack
mov sp,WoaRlmEntrySP ;get the entry point stack pointer
; release the stack space.
mov ah,49h ;release memory code
mov es,cs:[TempStack] ;the allocated segment
int 21h ;block released
; now flags to say there is no exec failure
clc ;no failure
pushf ;save the flag
NoTsrActive:
push ax ;save exec return code
; if 'destroy pif window' pif setting is not set, display message that we
; are ready to exit and wait for user to type in a key, else this routine
; will be a NOP.
or SwitcherDisabled,SD_LOCAL_DISABLE;prevent a switch out.
call PressKeyToExit ;wait if necessary
; now initialize the display back to a know mode incase the old app leaves
; it in a graphics mode.Set back the start up no of lines
mov ax,WoaStartScreenLines ;no of lines per screen
cCall GrabberInitScreen ;initialize the display
; remove our XMS hook.
cmp WoafXmsInstalled,0 ;is there any xms handler
jz @f ;XMS code handler not installed.
call UnHookOurXMSCode ;XMS hook removed
@@:
; we should disable the INT 15 mouse if a local handler is active
call DisableInt15Mouse
;----------------------------------------------------------------------------;
; we are back from execing the child, now grow back the original DOS block ;
; allocated to windows to its original size. ;
;----------------------------------------------------------------------------;
; set back ds to cs
smov ds,cs ;restore stub ds
; restore various dos & bios states that we had saved before the app had
; started
call RestoreWinDosBiosStates ;restore dos and bios states
; if the machine is a vectra, restore the stae of the system for windows
cCall RestoreWindowsHPState ;restores vectra state on a vectra
; restore the saved instance data image which includes IDT
cCall SwapInstanceDataBlocks
; let grabber de-install it's INT 10 hooks.
cCall GrabberDisableSave ;grabber releases int 10 hooks
; restore the IRQ enable state in the PIC
mov al,MasterPICMask ;get the value
out 21h,al ;restored
; do the same for the slave PIC. We should restore the slave PIC mask only if
; the app used it else not. Also if the app used it, we should restore the
; PreExec state.
mov al,PreExecSlavePICMask ;get the value
call RestoreSlavePICMask ;restore the slave pic mask
; go back to heap owner pdb before resizing (same as WOA's PSP)
mov bx,WoaPSP
mov ax,5000h ;set PDB call
int 21h ;we are now in DOS extenders PSP
mov es,WoaSegResizeBlock ;this is the DOS block to resize
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -