home *** CD-ROM | disk | FTP | other *** search
- .386r
- .387
- ;
- ; real.asm - Real mode assembler code for gserver
- ;
- ;************************************************************************/
- ;* Copyright (C) 1986-1993 Phar Lap Software, Inc. */
- ;* Unpublished - rights reserved under the Copyright Laws of the */
- ;* United States. Use, duplication, or disclosure by the */
- ;* Government is subject to restrictions as set forth in */
- ;* subparagraph (c)(1)(ii) of the Rights in Technical Data and */
- ;* Computer Software clause at 252.227-7013. */
- ;* Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138 */
- ;************************************************************************/
-
-
- extrn _gserver:far,_exit:far
-
- assume cs:codeseg,ds:nothing
-
- codeseg segment public byte 'code'
-
-
- ;
- ; Variables used by this assembly language code, kept in code segment
- ;
-
- dssave dw ? ; Real mode DS register
- sssave dw ? ; Real mode SS register
- essave dw ? ; Real mode ES register
- spsave dw ? ; Real mode SP register
- bpsave dw ? ; Real mode BP register
-
- realpsp dw ? ; Real mode program's PSP pointer
- protpsp dw ? ; Protected mode program's PSP pointer
-
- spsave2 dw ? ; SP register provided by DOS-Extender
- sssave2 dw ? ; SS register provided by DOS-Extender
-
- TRUE equ 1
- FALSE equ 0
- fp387f dw ? ; T ==> 387 present, F ==> not present
- real_387state db 94 dup (?) ; real mode program's floating point state
- prot_387state db 94 dup (?) ; protected mode program's floating point state
-
- reptr dd _reenter ; Far pointer to _reenter
-
- ;
- ; protret - Return from real mode back to protected mode
- ;
- ; This routine is called by the real mode server when
- ; initialization of the server has been completed. It returns
- ; to the protected mode code which loaded the real mode server.
- ; It returns by calling the 386|DOS-Extender protected mode
- ; call function. The address of this function as well as the
- ; protected mode return address are taken from the parameter
- ; block that is passed into the real mode server as the command
- ; tail by the protected mode code.
- ;
-
- public _protret
-
- _protret proc far
-
- ; First, the real mode PSP segment pointer, the real mode segment
- ; registers, and the real mode stack are saved for future calls
- ; to the real mode server.
-
- mov ah,51h ; Get the address of the PSP into ES.
- int 21h ;
- mov es,bx ;
-
- mov realpsp,bx ; Save the real mode PSP pointer.
-
- mov dssave,ds ; Save the current real mode registers.
- mov sssave,ss ;
- mov essave,es ;
- mov bpsave,bp ;
- mov ax,sp ;
- sub ax,20h ;
- mov spsave,ax ;
-
- ;
- ; If we have a 387 present, save the floating point state so we can restore
- ; it again each time the real mode program is called. (It's not necessary
- ; to save the state if there's no coprocessor and we're emulating, since
- ; the real mode and prot mode emulators won't interfere with each other.
- ; Since we don't unconditionally do an FSAVE/FRSTOR, someone could pick up
- ; this glue code and use it with a non-floating-point program without
- ; having it break on a machine without a coprocessor).
- ;
- mov fp387f,FALSE ; assume no coprocessor
- int 11h ; branch if no coprocessor
- test ax,2 ;
- jz short #no_87 ;
- mov fp387f,TRUE ; flag coprocessor present
- fsave real_387state ; save current coprocessor state
- #no_87:
-
- ; The following sanity check is done to make sure that the
- ; we were called by a protected mode program
-
- mov al,es:80h ; Branch if the length of the command
- cmp al,12 ; tail is not 12.
- jne #err ;
-
- ; Save the segment address of the protected mode PSP for future
- ; calls into the real mode code.
-
- mov ax,es:8bh ; Save the protected mode PSP.
- mov protpsp,ax ;
-
- ; Return to protected mode by calling the 386|DOS-Extender service
- ; that calls through to protected mode
-
- xor ax,ax ; Zero the parameter block pointer on
- push ax ; the stack.
- push ax ;
-
- mov ax,es:89h ; Push the prot mode CS onto
- push ax ; the stack.
-
- mov ax,es:87h ; Push the protected mode return address
- push ax ; onto the stack.
- mov ax,es:85h ;
- push ax ;
-
- mov eax,reptr ; Load a far pointer to the real mode re-enter
- ; routine into EAX.
-
- call es:(dword ptr 81h) ; Call 386|DOS-X service to call back into
- ; protected mode.
-
- ; When the protected mode code returns to this point, it wants us
- ; to exit.
-
- ; Switch to the real mode PSP so that MS-DOS is all happy.
-
- mov ah,50h ; Restore the real mode PSP.
- mov bx,realpsp ;
- int 21h ;
-
- ; Call the C exit routine to terminate and go back to protected mode
- ; forever.
-
- push 0 ; Call the C exit routine.
- call _exit ;
-
-
- ; Fatal error handler.
-
- #err: mov dx,offset #errmsg; Output a fatal error message.
- push cs ;
- pop ds ;
- mov ah,9h ;
- int 21h ;
-
- mov ax,4c01h ; Abort.
- int 21h ;
-
- #errmsg db 'Fatal error: Bad call to real mode server.',0dh,0ah,'$'
-
- _protret endp
-
-
- ;
- ; _reenter - Re-enter point for real mode
- ;
- ; This routine is called from protected mode. Its job is
- ; to restore the real mode segment registers, stack, and PSP
- ; and then to call the server.
- ;
-
- public _reenter
-
- _reenter proc far
-
- ;
- ; Switch to the real mode program's floating point state
- ;
- cmp fp387f,FALSE ; branch if no 387
- je short #no_87 ;
- fsave prot_387state ; save prot mode coprocessor state
- frstor real_387state ; restore real mode coprocessor state
- #no_87:
-
- ; First load the segment:offset address of the graphics commands buffer
- ; into EDX. We do this now because the address is on the stack and
- ; we are about to switch stacks.
-
- mov bp,sp ; Load from the stack, the far pointer to
- mov edx,4[bp] ; graphics commands buffer into EDX.
-
- ; Now switch stacks and restore the real mode segment registers.
-
- mov spsave2,sp ; Save the stack pointer (SS:SP) given to us
- mov sssave2,ss ; by 386|DOS-Extender.
-
- mov ds,dssave ; Restore the real mode registers and switch
- mov es,essave ; stacks.
- mov ss,sssave ;
- mov sp,spsave ;
- mov bp,bpsave ;
-
- ; Switch to the real mode PSP so that MS-DOS is all happy.
-
- mov ah,50h ; Restore the real mode PSP.
- mov bx,realpsp ;
- int 21h ;
-
- ; Call the server with the address of the graphics commands buffer
- ; pushed onto the stack as an argument
-
- push edx ; Call the graphics server.
- call _gserver ;
-
- ; Switch back to the protected mode PSP so that MS-DOS stays happy
-
- mov ah,50h ; Switch back to the protected mode PSP.
- mov bx,protpsp ;
- int 21h ;
-
- ; Switch back to the stack provided by 386|DOS-Extender and then
- ; return back to the caller that is running in protected mode.
-
- mov ss,sssave2 ; Switch back to the stack provided by
- mov sp,spsave2 ; 386|DOS-Extender.
-
- ;
- ; Switch back to the protected mode program's floating point state.
- ;
- cmp fp387f,FALSE ; branch if no 387
- je short #no_87_rst ;
- fsave real_387state ; save real mode coprocessor state
- frstor prot_387state ; restore prot mode coprocessor state
- #no_87_rst:
-
- ret ; Return back to protected mode caller.
-
- _reenter endp
-
- codeseg ends
-
- end
-