home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / GDEMO / REAL.ASM < prev   
Encoding:
Assembly Source File  |  1992-12-23  |  6.9 KB  |  245 lines

  1.     .386r
  2.     .387
  3. ;
  4. ;    real.asm - Real mode assembler code for gserver
  5. ;
  6. ;************************************************************************/
  7. ;*    Copyright (C) 1986-1993 Phar Lap Software, Inc.            */
  8. ;*    Unpublished - rights reserved under the Copyright Laws of the    */
  9. ;*    United States.  Use, duplication, or disclosure by the         */
  10. ;*    Government is subject to restrictions as set forth in         */
  11. ;*    subparagraph (c)(1)(ii) of the Rights in Technical Data and     */
  12. ;*    Computer Software clause at 252.227-7013.            */
  13. ;*    Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138    */
  14. ;************************************************************************/
  15.  
  16.  
  17.     extrn    _gserver:far,_exit:far
  18.  
  19.     assume    cs:codeseg,ds:nothing
  20.  
  21. codeseg    segment public byte 'code'
  22.  
  23.  
  24. ;
  25. ;    Variables used by this assembly language code, kept in code segment
  26. ;
  27.  
  28. dssave    dw    ?        ; Real mode DS register
  29. sssave    dw    ?        ; Real mode SS register
  30. essave    dw    ?        ; Real mode ES register
  31. spsave    dw    ?        ; Real mode SP register
  32. bpsave    dw    ?        ; Real mode BP register
  33.  
  34. realpsp    dw    ?        ; Real mode program's PSP pointer
  35. protpsp    dw    ?        ; Protected mode program's PSP pointer
  36.  
  37. spsave2 dw    ?        ; SP register provided by DOS-Extender
  38. sssave2    dw    ?        ; SS register provided by DOS-Extender
  39.  
  40. TRUE    equ    1
  41. FALSE    equ    0
  42. fp387f    dw    ?        ; T ==> 387 present, F ==> not present
  43. real_387state db 94 dup (?)    ; real mode program's floating point state
  44. prot_387state db 94 dup (?)    ; protected mode program's floating point state
  45.  
  46. reptr    dd    _reenter    ; Far pointer to _reenter
  47.  
  48. ;
  49. ;    protret - Return from real mode back to protected mode
  50. ;
  51. ;    This routine is called by the real mode server when
  52. ;    initialization of the server has been completed.  It returns
  53. ;    to the protected mode code which loaded the real mode server.
  54. ;    It returns by calling the 386|DOS-Extender protected mode
  55. ;    call function.  The address of this function as well as the
  56. ;    protected mode return address are taken from the parameter
  57. ;    block that is passed into the real mode server as the command
  58. ;    tail by the protected mode code.
  59. ;
  60.  
  61.     public    _protret
  62.  
  63. _protret proc    far
  64.  
  65. ;    First, the real mode PSP segment pointer, the real mode segment
  66. ;    registers, and the real mode stack are saved for future calls
  67. ;    to the real mode server.
  68.  
  69.     mov    ah,51h        ; Get the address of the PSP into ES.
  70.     int    21h        ;
  71.     mov    es,bx        ;
  72.  
  73.     mov    realpsp,bx    ; Save the real mode PSP pointer.
  74.  
  75.     mov    dssave,ds    ; Save the current real mode registers.
  76.     mov    sssave,ss    ;
  77.     mov    essave,es    ;
  78.     mov    bpsave,bp    ;
  79.     mov    ax,sp        ;
  80.     sub    ax,20h        ;
  81.     mov    spsave,ax    ;
  82.  
  83. ;
  84. ; If we have a 387 present, save the floating point state so we can restore
  85. ; it again each time the real mode program is called.  (It's not necessary
  86. ; to save the state if there's no coprocessor and we're emulating, since
  87. ; the real mode and prot mode emulators won't interfere with each other.
  88. ; Since we don't unconditionally do an FSAVE/FRSTOR, someone could pick up
  89. ; this glue code and use it with a non-floating-point program without
  90. ; having it break on a machine without a coprocessor).
  91. ;
  92.     mov    fp387f,FALSE    ; assume no coprocessor
  93.     int    11h        ; branch if no coprocessor
  94.     test    ax,2            ;
  95.     jz    short #no_87        ;
  96.     mov    fp387f,TRUE    ; flag coprocessor present
  97.     fsave    real_387state    ; save current coprocessor state
  98. #no_87:
  99.  
  100. ;     The following sanity check is done to make sure that the
  101. ;    we were called by a protected mode program
  102.  
  103.     mov    al,es:80h    ; Branch if the length of the command
  104.     cmp    al,12        ;    tail is not 12.
  105.     jne    #err        ;
  106.  
  107. ;    Save the segment address of the protected mode PSP for future
  108. ;    calls into the real mode code.
  109.  
  110.     mov    ax,es:8bh    ; Save the protected mode PSP.
  111.     mov    protpsp,ax    ;
  112.  
  113. ;    Return to protected mode by calling the 386|DOS-Extender service
  114. ;    that calls through to protected mode
  115.  
  116.     xor    ax,ax        ; Zero the parameter block pointer on
  117.     push    ax        ;    the stack.
  118.     push    ax        ;
  119.  
  120.     mov    ax,es:89h    ; Push the prot mode CS onto
  121.     push    ax        ;    the stack.
  122.  
  123.     mov    ax,es:87h    ; Push the protected mode return address
  124.     push    ax        ;    onto the stack.
  125.     mov    ax,es:85h    ;
  126.     push    ax        ;
  127.  
  128.     mov    eax,reptr    ; Load a far pointer to the real mode re-enter 
  129.                 ;    routine into EAX.
  130.  
  131.     call    es:(dword ptr 81h) ; Call 386|DOS-X service to call back into 
  132.                    ;      protected mode.
  133.  
  134. ;    When the protected mode code returns to this point, it wants us
  135. ;    to exit.
  136.  
  137. ;    Switch to the real mode PSP so that MS-DOS is all happy.
  138.  
  139.     mov    ah,50h        ; Restore the real mode PSP.
  140.     mov    bx,realpsp    ;
  141.     int    21h        ;
  142.  
  143. ;    Call the C exit routine to terminate and go back to protected mode
  144. ;    forever.
  145.  
  146.     push    0        ; Call the C exit routine.
  147.     call    _exit        ;
  148.  
  149.  
  150. ;    Fatal error handler.
  151.  
  152. #err:    mov    dx,offset #errmsg; Output a fatal error message.
  153.     push    cs        ;
  154.     pop    ds        ;
  155.     mov    ah,9h        ;
  156.     int    21h        ;
  157.  
  158.     mov    ax,4c01h    ; Abort.
  159.     int    21h        ;
  160.  
  161. #errmsg    db    'Fatal error: Bad call to real mode server.',0dh,0ah,'$'
  162.  
  163. _protret endp
  164.  
  165.  
  166. ;
  167. ;    _reenter - Re-enter point for real mode
  168. ;
  169. ;    This routine is called from protected mode.  Its job is
  170. ;    to restore the real mode segment registers, stack, and PSP
  171. ;    and then to call the server.
  172. ;
  173.  
  174.     public    _reenter
  175.  
  176. _reenter proc    far
  177.  
  178. ;
  179. ; Switch to the real mode program's floating point state
  180. ;
  181.     cmp    fp387f,FALSE    ; branch if no 387
  182.     je    short #no_87    ;
  183.     fsave    prot_387state    ; save prot mode coprocessor state
  184.     frstor    real_387state    ; restore real mode coprocessor state
  185. #no_87:
  186.  
  187. ;    First load the segment:offset address of the graphics commands buffer
  188. ;    into EDX.  We do this now because the address is on the stack and
  189. ;    we are about to switch stacks.
  190.  
  191.     mov    bp,sp        ; Load from the stack, the far pointer to 
  192.     mov    edx,4[bp]    ;    graphics commands buffer into EDX.
  193.  
  194. ;    Now switch stacks and restore the real mode segment registers.
  195.  
  196.     mov    spsave2,sp    ; Save the stack pointer (SS:SP) given to us 
  197.     mov    sssave2,ss    ;    by 386|DOS-Extender.
  198.  
  199.     mov    ds,dssave    ; Restore the real mode registers and switch
  200.     mov    es,essave    ;    stacks.
  201.     mov    ss,sssave    ;
  202.     mov    sp,spsave    ;
  203.     mov    bp,bpsave    ;
  204.  
  205. ;    Switch to the real mode PSP so that MS-DOS is all happy.
  206.  
  207.     mov    ah,50h        ; Restore the real mode PSP.
  208.     mov    bx,realpsp    ;
  209.     int    21h        ;
  210.  
  211. ;    Call the server with the address of the graphics commands buffer
  212. ;    pushed onto the stack as an argument
  213.  
  214.     push    edx        ; Call the graphics server.
  215.     call    _gserver    ;
  216.  
  217. ;    Switch back to the protected mode PSP so that MS-DOS stays happy
  218.  
  219.     mov    ah,50h        ; Switch back to the protected mode PSP.
  220.     mov    bx,protpsp    ;
  221.     int    21h        ;
  222.  
  223. ;    Switch back to the stack provided by 386|DOS-Extender and then
  224. ;    return back to the caller that is running in protected mode.
  225.  
  226.     mov    ss,sssave2    ; Switch back to the stack provided by
  227.     mov    sp,spsave2    ;    386|DOS-Extender.
  228.  
  229. ;
  230. ; Switch back to the protected mode program's floating point state.
  231. ;
  232.     cmp    fp387f,FALSE    ; branch if no 387
  233.     je    short #no_87_rst ;
  234.     fsave    real_387state    ; save real mode coprocessor state
  235.     frstor    prot_387state    ; restore prot mode coprocessor state
  236. #no_87_rst:
  237.  
  238.     ret            ; Return back to protected mode caller.
  239.  
  240. _reenter endp
  241.  
  242. codeseg    ends
  243.  
  244.     end
  245.