Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

336 lines
6.5 KiB

page ,132
subttl emfixfly.asm - Fixup-on-the-fly routines
;***
;emfixfly.asm - Fixup-on-the-fly routines
;
; Copyright (c) 1987-89, Microsoft Corporation
;
;Purpose:
; Fixup-on-the-fly routines
;
; This Module contains Proprietary Information of Microsoft
; Corporation and should be treated as Confidential.
;
;Revision History:
; See emulator.hst
;
;*******************************************************************************
;*******************************************************************************
; 03/29/85 - added 286 optimizations to change FWAITs to NOPs
; 09/10/87 - added FWAIT's for BASIC error handling
; 11/02/87 - changed FWFixUpOnFly to check for errors
;*******************************************************************************
ProfBegin FIXFLY
ifdef DOS3
pub SOFixUpOnFly
sti ; turn on interrupts
fwait ; For BASIC error handling
push ax
push bp
push ds
push si
mov bp,sp ; Point to stack
lds si,dword ptr 8[bp] ; Fetch ret address,(points to after instruction)
mov al,[si] ; get ESC byte
or byte ptr [si],0C0h ; turn back into ESC x byte
dec si ; Make SI point to start off instruction
dec si
mov 8[bp],si ; Change ret address to return to instruction
shr al,1 ; move 2 bits into correct position
shr al,1
shr al,1
not al ; negate them
and al,018h ; mask to middle 2 bits
or al,fES ; turn into correct segmented override
xchg al,ah ; into high half
mov al,fFWAIT ; low byte
mov [si],ax ; stuff it
push bx
mov bx,1 ; bx = 1 to skip segment override
ifdef WF
jmp fixupdone
else
jmp short fixupdone
endif
; new routine - don't back patch - check for error
; UNDONE - need to change this for Windows - can't edit code
; need to check errorcode
pub FWFixUpOnFly
sti ; turn on interrupts
fwait ; For BASIC error handling
ifdef WF
wfFaultHere = $-1
; int 3
push ds ; ds[18] retip[20] retcs[22] retfl[24]
push es ; es[16]
pusha ;
mov bp, sp ;
mov ax, EMULATOR_DATA
mov ds, ax
cmp [wfGoFast], 1
jnz WinSlow
push [bp+22] ; faulting CS - get data alias
push [wfSel]
call ChangeSelector
mov es, [wfSel]
sub word ptr [bp+20], 2
mov bx, [bp+20] ; point to faulting insn
xor ax, ax
xchg [wfInsn], ax
or ax, ax ; are we here due to fault?
je wfNoFault
mov es:[bx], ax ; yes - restore 'fake' INT 3d
xor ax,ax
xchg [errorcode],al ; get and reset errorcode
mov REMLSW, ax ; save error code
popa
pop es
pop ds
jmp WinFastContinue
; mov ax, 353eh
; int 21h
; mov ax, es ; does app have a handler?
; or ax, bx
; jz wfDone
;
; mov ax, [wfErr]
;
; push cs ; return to wfDone
; push offset wfDone
;
; push es ; call app handler
; push bx
;
; retf
FWAITNOP equ (iNOP + 256*fFWAIT)
wfNoFault: ; this was a 'real' INT 3d,
mov es:[bx], FWAITNOP ; so we'll patch it to inline code
wfDone:
popa
pop es
pop ds
iret
WinSlow: ; can't use fast method, fall through
popa
pop es
pop ds ; fall through into old code
endif
ifdef POLLING ; new exception handling under POLLING
ifdef USE_IRET
FWAITiret:
iret ; Edit to nop if error occurs
elseifdef WINDOWS
push ds
push ax
mov ax, EMULATOR_DATA
mov ds, ax
cmp [ExceptFlag], 0 ; if not zero, 80x87 exception occured.
pop ax
pop ds
jnz PolledException
iret
else ;DEFUALT
FWAITRetF db bRETF ; Edit to 3 byte nop if error occurs
FWAITRetF2 dw 2
endif ;DEFAULT
pub PolledException
push eax ; same frame as in emerror.asm
push ds ; get address from task DS
ifdef standalone
xor ax,ax
mov ds,ax
mov ds,ds:[4*TSKINT+2]
elseifdef _COM_
mov ds, [__EmDataSeg]
else ;not standalone or _COM_
mov ax,EMULATOR_DATA
mov ds,ax
endif ;not standalone or _COM_
;*
;* Reset fwait polling flag.
;*
ifdef USE_IRET
mov byte ptr cs:[FWAITiret], bIRET ; reset "iret"
elseifdef WINDOWS
mov [ExceptFlag], 0
else ;DEFAULT
mov [FWAITRetF], bRETF ; reset "retf 2"
mov [FWAITRetF2], 2
endif ;DEFAULT
xor ax,ax
xchg [errorcode],al ; get and reset errorcode
ifdef WINDOWS
mov REMLSW, ax ; save error code
pop ds
pop ax ; stack is now just an int stack frame
WinFastContinue:
inc bp
push bp
mov bp, sp
push ds
push ax ; save user's ax
push cs ; must set up another stack frame
mov ax, offset FF_DummyReturn
push ax
FF_DummyReturn:
mov word ptr [bp-2], EMULATOR_DATA ; emulator's ds goes on first frame
inc bp
push bp
mov bp, sp
push ds ; push user's ds onto dummy stack frame
mov ax, EMULATOR_DATA
mov ds, ax
push es ; if windows => setup SignalAddress for
push bx ; far call
mov ax, DOS_getvector*256 + TSKINT
IntDOS
mov word ptr [SignalAddress], bx
mov word ptr [SignalAddress+2], es
pop bx
pop es
mov ax, REMLSW ; al = error code
call [SignalAddress] ; execute signal routine
pop ds ; restore user's ds
add sp, 6 ; get rid of dummy stack frame
pop ax ; restore user's ax
add sp, 2 ; get rid of emulator ds on stack
pop bp
dec bp
iret ; return
else ;not WINDOWS
call [SignalAddress] ; execute signal routine
pop ds ; restore user DS
pop eax
iret
endif ;not WINDOWS
else ;not POLLING
push ax
mov ax,FIWRQQ ; isolated FWAIT fixup
jmp short FixUpOnFly
endif ;not POLLING
pub DSFixUpOnFly
sti ; turn on interrupts
fwait ; For BASIC error handling
push ax
mov ax,FIDRQQ ; DS segment fixup
pub FixUpOnFly
PUSH BP
PUSH DS
PUSH SI
MOV BP,SP ; Point to stack
LDS SI,dword ptr 8[BP] ; Fetch ret address,(points to after instruction)
DEC SI ; Make SI point to instruction
DEC SI
MOV 8[BP],SI ; Change ret address to return to instruction
SUB [SI],ax ; Remove Fixup to convert to 8087 instruction
push bx
xor bx,bx ; bx = 0 for no segment override
; For the 286 change FWAITs on numeric instructions to NOPs
;
; ds:si = FWAIT address
; ds:(si+bx+1) = 8087/287 instruction
pub fixupdone
push sp ; check for 286
pop ax
cmp ax,sp
jne fixupxit ; not 286
mov ax,[bx+si+1] ; get instruction
and ax,030FBh ; mask for FSTCW/FSTSW/FSTENV/FSAVE
cmp ax,030D9h ; underlying bits
jne fixcheck2 ; not one of the above
mov al,[bx+si+2] ; get 2nd byte of instruction again
cmp al,0F0h ; check if kernel functions
jb fixupxit ; no - exit
pub fixcheck2
mov ax,[bx+si+1] ; get instruction
and ax,0FEFFh ; mask for FCLEX/FINIT
cmp ax,0E2DBh ; underlying bits
je fixupxit ; can't remove FWAIT
mov ax,[bx+si+1] ; get instruction
cmp ax,0E0DFh ; check for FSTSW AX
je fixupxit ; can't remove FWAIT
mov byte ptr [si],iNOP ; NOP the FWAIT
pub fixupxit
pop bx
POP SI
POP DS
POP BP
pop ax
IRET
endif ;DOS3
ProfEnd FIXFLY