| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- (* Release 3.10 *)
- (*-------------------------------------------------------------------------*
- * *
- * P_EMUL.A - protected-mode emulator support *
- * *
- * COPYRIGHT (C) 1989..1992 Clarion Software Corporation. *
- * All Rights Reserved *
- * *
- *--------------------------------------------------------------------------*)
- module p_emul
- auto_select = 1 (* use 8087 if one is present at run time *)
- public FIDRQQ = 0
- public FIWRQQ = 0
- public FIERQQ = 0
- public FIARQQ = 0
- public FISRQQ = 0
- public FICRQQ = 0
- public FJERQQ = 0
- public FJARQQ = 0
- public FJSRQQ = 0
- public FJCRQQ = 0
- public FIXRQQ = 0
- segment EMU_TEXT (EMU_CODE,28H)
- foption 2
- extrn emulate8087
- oldFlags = 22
- oldCS = 20
- oldIP = 18
- oldAX = 16
- oldBX = 14
- oldBX = 12
- oldDX = 10
- oldSI = 8
- oldDI = 6
- oldDS = 4
- oldES = 2
- oldBP = 0
- e286_entry :
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
- push bp
- mov bp,sp
- cld (* forward string direction *)
- lds si, [bp][oldIP]
- sub dl, dl (* records whether there was a segment override *)
- lodsw
- sub al, 0D8H
- cmp al, 8
- jae override
- decoded:
- jmp emulate8087
- resume:
- (* ggfb: check for another float instruction *)
- lds si, [bp][oldIP]
- cld (* !! it may not be clear! *)
- search:
- lodsw
- cmp al, 90H
- je skip
- cmp al, 9BH
- je skip
- sub al, 0D8H
- cmp al, 8
- jae notanother (* seg-overrides cause not checked *)
- sub dl, dl
- jmp emulate8087 (* ax,bx,cx,dl,bp,ds,si,di must all be all valid ! *)
- notanother:
- mov sp, bp
- pop bp
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- iret
- override:
- cmp al, 3EH-0D8H (* ds: ? *)
- je DSfix
- cmp al, 26H-0D8H (* es: ? *)
- je ESfix
- cmp al, 2EH-0D8H (* cs: ? *)
- je CSfix
- (*jmp SSfix*)
- SSfix: mov di, ss; jmp segfix
- CSfix: mov di, ds; jmp segfix
- ESfix: mov di, [bp][oldES]; jmp segfix
- DSfix: mov di, [bp][oldDS]; (*jmp segfix*)
- segfix:
- mov es, di
- lodsb (* advance to pick up mod/r/m byte *)
- xchg ah, al
- and al, 7
- inc dl
- jmp emulate8087
- skip:
- dec si
- jmp search
- public __FloatInit:
- push bp
- mov bp,sp
- sub sp, 4
- extrn __fp_1
- call far __fp_1
- db 0FH, 01H, 66H, 0FEH; (* smsw ds:[bp][-2] *)
- test word [bp][-2],2
- (*%T auto_select*)
- jnz emulation_not_required (* disable jump for debugging *)
- (*%E*)
- mov ax, 7 ; push ax (* push 7 *)
- mov ax, EMU_TEXT ; push ax
- mov ax, e286_entry ; push ax (* push e286_entry *)
- push ss
- lea ax, [bp][-4]; push ax (* push address for result *)
- extrn DOSSETVEC
- call far DOSSETVEC
- emulation_not_required:
- mov sp, bp
- pop bp
- mov bx, ss
- (*call __FloatInitInstance*)
- (*ret far 0*)
- public __FloatInitInstance:
- mov ax, resume
- extrn __EmulInitInstance
- call __EmulInitInstance
- push bp
- mov bp,sp
- sub sp,2
- finit
- fstcw [bp][-2]
- fwait
- or word [bp][-2], 0C00H
- and word [bp][-2],~001DH (* enable invalid op/underflow/overflow/divide by zero exception *)
- fldcw [bp][-2]
- extrn __FloatInitStack
- call far __FloatInitStack
- mov sp,bp
- pop bp
- ret far 0
- public __FloatFinish:
- ret far 0
- public __FloatMathExcepOs2 :
- (* always far called from coresig *)
- (*
- stack contains far return address to signal handler, then status word,
- then far return address to error location, the iret flags.
- This is how __math_excep likes it, so just jump there.
- *)
- extrn __math_excep
- fclex
- jmp far __math_excep
- public __FloatEmulNMI:
- emws_status = 414 (* org 2, aligned. Result of comparisons *)
- push ss:[emws_status] (* as per OS/2, status word onto stack *)
- extrn sigHandlerFPE1
- jmp far sigHandlerFPE1
- public __FloatJmpSave :
- st1_reg = 20
- st2_reg = 30
- fld st(0), st(1)
- fstp tbyte es:[di][st1_reg], st(0)
- fld st(0), st(2)
- fstp tbyte es:[di][st2_reg], st(0)
- fwait
- ret far 0
- public __FloatJmpRestore :
- fld tbyte st(0), ds:[si][st1_reg]
- fstp st(2), st(0)
- fld tbyte st(0), ds:[si][st2_reg]
- fstp st(3), st(0)
- ret far 0
- ProcessFloat = 14
- public __FloatSave :
- fsave es:[ProcessFloat]
- ret far 0
- public __FloatRestore :
- frstor ds:[ProcessFloat]
- ret far 0
- public __FloatExecSave :
- public __FloatExecRestore :
- ret far 0
- segment EMU_STATE(DATA,68H)
- emuRecSize = 490
- select EMU_STATE
- public emuBuffer:
- db 0
- org emuRecSize-1
- end (*P_EMUL.A*)
|