;# SCCSID = @(#)viopopup.asm    6.6 92/02/24
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        SUBTTL  VIOPOPUP, VIOENDPOPUP
        TITLE   VIOPOPUP.ASM
;******************************************************************************
;*******   C H A N G E       H I S T O R Y   **********************************
;******************************************************************************
;$A0= Preserve AVS return code when VIOENDPOPUP returns nonzero and non -1
;     8-25-86 (7.49)
;$A1= call VIOGETMODE inside VIOPOPUP to ensure that VIOPOPUP is not first
;     VIO call from any process
;     9-11-86 (7.??)
;$A2= turn off SGDATA[popee].POP_MODE flag before calling DOSSMSGENDPOPUP
;     9-18-86 (7.58)
;$A3= move POP_MODE flag to instance data segment
;     9-19-86 (7.58)
;$A4= make call to KBDGETSTATUS so as to use proper KBDxxx semaphore
;     9-22-86 (7.58)
;$A5= Ensure that KBDCALLS.EXE INSTANCE data segment is loaded.
;     10-3-86 (7.62)
;$Y9= change for DOSEXITLIST (see \\design1\desup gateway \dcr111\dcr0018)
;     07-10-87
;$Z1= VIOENDPOPUP: for HETPID, do NOT clear pu_sem (VIOPOPUP didn't request it)
;     06-19-87
;$Z2= clear pu_sem if AVS returns non 0,-1
;     06-12-87
;$Z3= new System Trace parameters support
;     06-04-87
;$Z4= Don't call GETMODE during POPUP/ENDPOPUP
;     05-11-87
;$Z5= turn on POP_MODE flag only when POPUP succeeds (PTM P4536)
;     05-04-87
;$Z6= pass VIOPOPUP flags to DOSSMSGDOPOPUP (for transparent popups, DCR 67)
;     04-24-87
;$Z7= SHELLPID is in COMMON, not INSTANCE
;     03-16-87
;$Z8= return ERROR_VIO_SHELL_INIT from VIOPOPUP until VIOSHELLINIT completes
;     03-12-87
;$Z9= Set detach popup flag so VIOGETMODE will be allowed. @@11
;     11-3-86
;%A0= Use FS RAM sems instead of system sems
;     07-30-87
;%A1= Add origSG INSTANCE data field to record/restore popup PID's original SG
;     07-30-87
;%A2= When waitflags = 0, immediately return to user if error
;     03-14-88
;P2964= Call vioattach from VioEndPopUp if caller's first VIO call
;       06-14-88
;P3093= clear fsRAMsem in VIOENDPOPUP multi-times if caller is exiting
;       07-13-88
;P3610= use CX to check for correct number of DOSFSRAMSEMCLEAR's until 0
;       09-13-88
;P3707= call bvs_getmode so that BVS can reset caller's state after endpopup
;       09-18-88
;P3825= disable signal processing during VioPopUp function
;       11-13-88 (1.2 PTM 2472)
;P2859= (1.2 PTM) Fix Trap D on popup & endpopup
;       11-28-88
;p3096= (1.2 PTM) Popup with nowait should not wait if a popup already exists
;       12-08-88
;@T2  = 04/03/89 TPL, Sizzle work, PTR B701685
;@T5  = 05/10/89 TPL, PTR B701685 fix
;@T7  = 07/07/89 TPL, PTR AR03752 fix
;@T8  = 07/08/89 TPL, Removal of 3xbox code
;@tb16 = 08/03/89 TLB, PTR B784986 fix
;@tb17 = 08/08/89 TLB, PTR AR04329 fix
;DTBB1= 08/21/89 WKB, Dynamic Trace
;@T10  = 08/28/89 TPL, Allow VIOPOPUP during exitlist, PTR B707404
;@T11  = 09/05/89 TPL, Register early and late exitlist routine, B785577
;@S35  = 10/06/89 STJ, Loop thru semaphores only if they exist, B786097
;@tb38 = 01/25/89 TLB, On VIOPOPUP, continue processing if -1 return code
;                      from AVS or if pop_mode is set, B711111
;D549  = 11/07/89 WKB, D549 Changes
;@T52 = 01/15/90 TPL, DCR 704 work
;@B50 = 03/21/90 WKB, Transparent popup over diff cp disallowed, B711349
;@C42  03/26/90  CJJ, SL85039 Don't allow VioPopups until Shell has done a
;                VioSavRedrawWait.
;@T14 = 03/28/90 TPL, Remove duplication of functions
;@T18 = 04/30/90 TPL, B712103 - Optimize popup and screen switch processing
;@C39 = 01/11/91 CJJ, MVDM transparent popup changes, PTR SM84577
;@T14f= 05/08/91 TPL, Allow Detached to issue multiple popups, B790735
;@T80 = 02/06/92 TPL, Don't use the reserved register FS, B732479
;@T85 = 02/23/92 TPL, Reduce usage of DosLoadModule, B733000

INCL_DEF             equ   1            ;needed for basemaca.inc         @C39
INCL_TYPES           equ   1            ;needed for basedef.inc          @C39
INCL_WINPROGRAMLIST  equ   1            ;needed for pmshl.inc defines    @C39
SESMGR               equ   1            ;needed for pmshl.inc defines    @C39

.xlist
include error.inc
include error2.inc
include struc.inc
include infoseg.inc
include vioextrn.inc
include vioequ.inc
include viomac.inc
include vioidata.inc
include viocdata.inc
include basemaca.inc            ;macros for basedef.inc                  @C39
include basedef.inc             ;typedefs for vvd.inc                    @C39
include vvd.inc                 ;MVDM Virtual Video Equates              @C39
include pmshl.inc               ;PM Shell equates for prog type          @C39
.list
.386p                                                                   ;D549

IFDEF MMIOPH                                                         ;DTBB1
EXTRN   viopretrace:NEAR        ;internal call external definitions
EXTRN   vioposttrace:NEAR       ;
ENDIF                                                                ;DTBB1
EXTRN   vioattach:NEAR          ;
EXTRN   VIOGETMODE:FAR          ;
EXTRN   DOSFSRAMSEMREQUEST:FAR
EXTRN   DOSFSRAMSEMCLEAR:FAR
;EXTRN  Thunker:NEAR                                                    ;MDLL
;EXTRN  ThunkerFarRet:FAR                                               ;MDLL
EXTRN   DOSSMSGDOPOPUP:FAR                                              ;MDLL
EXTRN   DOSSMSGENDPOPUP:FAR                                             ;MDLL
EXTRN   KBDLOADINSTANCE:FAR                                         ;@T2,@T85
EXTRN   KBDFLUSHBUFFER:FAR                                          ;@T2,@T85
EXTRN   suicide:NEAR                                                    ;D549
EXTRN   OS2BASEINIT:FAR                                                 ;@T14
EXTRN   DOSOPENVDD:FAR          ;Open MVDM Video VDD                    ;@C39
EXTRN   DOSCLOSEVDD:FAR         ;Close MVDM Video VDD                   ;@C39
EXTRN   DOSREQUESTVDD:FAR       ;Request MVDM Video info                ;@C39

public  VIOPOPUP
public  VIOPOPUP_POSTDT                                                 ;DTBB1
public  VIOENDPOPUP
public  VIOENDPOPUP_POSTDT                                              ;DTBB1
public  VIOENDPOPEXIT
public  VIOENDPOPEXIT1                                                  ;@T11

instance segment byte public 'data'     USE16                           ;D549
instance ends

common segment byte public 'far_data'   USE16                       ;D549;@T52
common ends

cseg    segment byte public 'code'      USE16                           ;D549
        assume  cs:cseg,ds:instance,es:common,ss:nothing
        page


        SUBTTL VIOPOPUP - REQUEST FOR POPUP
        page
;/*********************** START OF SPECIFICATIONS ****************************/
;/* SUBROUTINE NAME: VIOPOPUP                                                */
;/*                                                                          */
;/* DESCRIPTIVE NAME: foreground POPUP request                               */
;/*                                                                          */
;/* FUNCTION:                                                                */
;/*                                                                          */
;/* NOTES:                                                                   */
;/*                                                                          */
;/* ENTRY POINT: VIOPOPUP                                                    */
;/*     LINKAGE: FAR CALL                                                    */
;/*                                                                          */
;/* INPUT: "WAIT" - wait flags (DWORD ptr on stack)                          */
;/*                 (xxxxxxxxxxxxxxx1H = wait, where x = don't care)         */
;/*        "DEV_HANDLE" - device handle (reserved WORD of 0000H on stack)    */
;/*                                                                          */
;/* EXIT-NORMAL: AX = NO_ERROR                                               */
;/*                                                                          */
;/* EXIT-ERROR: AX = ERROR_VIO_EXISTING_POPUP - POPUP on screen (no wait)    */
;/*             AX = ERROR_VIO_NO_POPUP - POPUP not allocated                */
;/*             AX = ERROR_VIO_SHELL_INIT - shell not initialized yet        */
;/*             AX = error code from AVS                                     */
;/*                                                                          */
;/* EFFECTS: The contents of AX are destroyed.                               */
;/*                                                                          */
;/* INTERNAL                                                                 */
;/* REFERENCES: currSG - current process's screen group (local info)         */
;/*             fgSG - current foreground screen group (global info)         */
;/*             SGDATA[currSG].POP_MODE - set from VIOPOPUP to VIOENDPOPUP   */
;/*             POPSYNC - handle for POPUP synch. system semaphore           */
;/*             SGSYNC - handle for currSG's per SG synch. system semaphore  */
;/*             SWITCHOFF - handle for sess. mgr.'s screen switch sem.       */
;/*   ROUTINES: None.                                                        */
;/*                                                                          */
;/* EXTERNAL                                                                 */
;/* REFERENCES: None.                                                        */
;/*   ROUTINES: DOSSEMREQUEST - request a semaphore                          */
;/*             DOSSEMCLEAR - clear a semaphore                              */
;/*             KBDFLUSHBUFFER - flush the keystroke buffer                  */
;/*             DOSSMSGDOPOPUP - sess. mgr. popup screen switch              */
;/*********************** END OF SPECIFICATIONS ******************************/
;VIOPOPUP psuedo code:
;  call viopretrace
;
;  if SHELLPID = 0  or
;  if "shell has not done a VioSavRedrawWait"  and
;  if "this is not the harderror pid"
;    AX <-- ERROR_VIO_SHELL_INIT
;  else
;
;    if "need to call vioattach"
;      call vioattach
;
;    if AX = NO_ERROR
;
;      if (currSG) != (hard_error SG)
;        request POPUP system sem
;
;      if AX = NO_ERROR  or
;      if AX = ERROR_SEM_OWNER_DIED
;        disable signals
;        origSG <-- currSG
;        call KBDLOADINSTANCE
;        request currSG's FS RAM sem
;
;        if VIOPOPUP replaced and
;        if currSG = fgSG
;          call AVS
;
;        clear currSG's FS RAM sem
;
;        if AVS desires default system action
;          call DOSSMSGDOPOPUP
;
;          if AX = NO_ERROR
;            pop_mode <-- 1
;            fsRAMoff <-- SGDATA[newSG].fsRAMsem offset
;            call KBDFLUSHBUFFER
;          else
;            clear POPUP system sem
;
;        elseif AX != NO_ERROR
;          clear POPUP system sem
;        elseif AX = NO_ERROR
;          pop_mode <-- 1
;
;        enable signals
;      else
;        AX <-- ERROR_VIO_EXISTING_POPUP
;
;  request currSG's FS RAM sem
;
;  if at least one GVS exists
;
;     for each GVS registered
;
;        if GVS has repleced VioPopUp
;           call GVS
;
;  clear currSG's FS RAM sem
;  call vioposttrace
;  return

VIOPOPUP proc far
   xor   ax,ax          ;preset AX = NO_ERROR
   push  fc_popup       ;VIOPOPUP function code
   push  ax             ;dummy nearIP                                   ;@T2
   push  ds             ;save registers
   enter 10,0           ;make stack look like viorout's (use BP)        ;1.2
   push  es             ;save registers
   push  gs                                                        ;D549,@T80
   pusha

   mov   bx,instance    ;DS <-- instance data selector                  ;P2859
   mov   ds,bx          ;                                               ;P2859

   IFDEF MMIOPH                                                         ;DTBB1
   mov   es,ds:gdtinfo                   ;ES <-- global info sel.
   mov   al,es:[SIS_MEC_TABLE].SIS_VIOMEC;AL <-- byte w/VIO MEC
   test  al,traceonoffmask               ;0=OFF, non-0=ON

   .if <nz>                                                             ;@T2
     call  viopretrace
   .endif
   ENDIF                                                                ;DTBB1

   mov   ax,common               ;ES <-- common data selector
   mov   es,ax                   ;

   .if <es:SHELLPID eq 0>  or     ;disallowed if shell not initialized or ;@CJ42;@T14
   .if <es:shellVSRW_done eq 0> and ;shell has not done VioSavRedrawWait  ;@CJ42
   mov ax,es:hetpid                                                       ;@CJ42
   .if <ax ne ds:currPID>           ;and this is not Harderror calling    ;@CJ42
     mov   [bp].rout_savAX,ERROR_VIO_SHELL_INIT
   .elseif <<word ptr[bp].puviohndl> ne 0>
     mov   [bp].rout_savAX,ERROR_VIO_INVALID_HANDLE
   .else near
     mov   es,ds:ldtinfo         ;currSG <-- current screen group
     mov   ax,es:[LIS_CurScrnGrp];
     mov   ds:currSG,ax          ;
     mov   al,es:[LIS_ProcType]  ;procTYPE <-- current process type     ;P2859
     cbw                         ;                                      ;P2859
     mov   ds:procTYPE,ax        ;

     les   di,dword ptr [bp].puwaitoff  ;POPUP options                  ;@B50
     mov   cx,es:[di]                   ;Put popup type flag in CX ;@B50,@T14

     .if <ax ne LIS_PT_DETACHED> near ;Not a detached process?       ;@T14;@C39

       lgs   bx,ds:SGCB         ;load gs:[bx] with SGCB ptr          ;D549,@T80

;/****************************************************************************/
;/* Add check for tranparent popup over different codepage                   */
;/****************************************************************************/
       mov   ax,cx                      ;Strip off all but         ;@B50,@T14
       and   ax,poptypemask             ; transparent type bit          ;@B50

       .if <nonzero ax> near            ;if transparent popup        ;@B50;@C39
         mov   es,ds:gdtinfo            ;get ForeGround Session info    ;@B50
         sub   dx,dx                    ;zero out DH               ;@B50,@T14
         mov   dl,es:[SIS_CurScrnGrp]   ;ForeGround Session        ;@B50,@T14
         .if  <ds:currSG ne dx>         ;current SG not in foreground   ;@T18
           push  ds                     ;sel:off to SGCB address        ;@B50
           push  offset SGCB_temp       ;  (returned)                   ;@B50
           push  dx                     ;DX has session ID         ;@B50,@T14
           push  Look_up_SGID                                           ;@B50
           call  DOSSMGETSGCB           ;get SGCB ptr                   ;@B50

           les   di,ds:SGCB_temp                                        ;@B50
        .else                                                           ;@T18
           les   di,ds:SGCB             ;already have access            ;@T18
        .endif                                                          ;@T18

        ;*********************************************************************
        ; if MVDM, need to call MVDM to get the codepage                ;@C39
        ;*********************************************************************
        .if <es:[di].SGCB_Type eq PROG_VDM>      ;if MVDM Session       ;@C39
          mov   ax,common                        ;ES <-- common data    ;@C39
          mov   es,ax                                                   ;@C39
          xor   ax,ax                                                   ;@C39

          .if <ds:vddhandle eq 0>        ;don't have VDD handle yet     ;@C39
            push    es                   ;push ptr to primary VDD name  ;@C39
            push    offset vdd1                                         ;@C39
            push    ds                   ;push ptr to MVDM VDD handle   ;@C39
            push    offset vddhandle                                    ;@C39
            call    DosOpenVDD           ;open Video VDD primary display;@C39
            mov     [bp].rout_savAX,ax   ;save return code              ;@C39
          .endif                                                        ;@C39

          .if <zero ax>                                                 ;@C39
            sub     sp,size vvm_s        ;get temp data on stack        ;@C39
            mov     si,sp                ;size of MVDM mode data struc  ;@C39
            push    ebx                  ;save EBX                      ;@C39

            mov     ebx,ds:vddhandle     ;MVDM VDD handle               ;@C39
            push    ebx                                                 ;@C39
            push    dx                   ;MVDM screen group number      ;@C39
            push    VVDSYSREQ_QUERYMODE  ;get MVDM mode data            ;@C39
            push    ebx                  ;ignored long parm - cbinput   ;@C39
            push    ebx                  ;ignored ptr parm -  pinput    ;@C39
            mov     ebx,size vvm_s       ;length of output data         ;@C39
            push    ebx                                                 ;@C39
            push    ss                   ;push ptr for MVDM mode data   ;@C39
            push    si                                                  ;@C39
            call    DosRequestVDD        ;get video mode info           ;@C39
            mov     [bp].rout_savAX,ax   ;save return code              ;@C39

            mov     si,word ptr ss:[si].vvm_cpID ;get current codepage  ;@C39

            mov     ebx,ds:vddhandle            ;MVDM VDD handle        ;@C39
            push    ebx                                                 ;@C39
            call    DosCloseVDD                 ;close Video VDD handle ;@C39

            pop     ebx                         ;restore EBX            ;@C39
            add     sp,size vvm_s               ;remove temp data       ;@C39
          .endif                                                        ;@C39
                                                                        ;@C39
        .else                            ;else get codepage from SGCB   ;@C39
           mov   si,es:[di].VIO_CodePageID ;get foreground Codepage ID ;@B50,@T14
        .endif                                                          ;@C39

         .if <zero ax> and                                    ;no errors ;@C39
         .if <dx ne 1> and              ;don't check if harderror  ;@B50,@T14
         .if <si ne gs:[bx].VIO_CodePageID> ;if codepages don't match ;@B50,@T80
           mov   [bp].rout_savAX,ERROR_VIO_BAD_CP ;ret codepage err     ;@B50
         .endif                                                         ;@B50
       .endif                                                           ;@B50

       .if <<word ptr[bp].rout_savAX> eq NO_ERROR>            ;no errors  ;@C39
         mov   ax,common          ;ES <-- common data selector            ;@T2
         mov   es,ax              ;                                       ;@T2

         mov   ax,ds:oldtimes     ;AX <-- number of VIOREGISTERs for this SG

         .if <ax ne gs:[bx].VIO_times>                               ;D549,@T80
           call  vioattach
         .endif
       .endif                                                             ;@C39

     .endif                     ;End of detached process check          ;@T14

     .if <<word ptr[bp].rout_savAX> eq NO_ERROR> near
       push  0C081H             ;add early exitlist routine             ;@T10
       mov   ax,cs              ;sel:off to VIOENDPOPUP routine
       or    ax,3
       push  ax
       push  offset VIOENDPOPEXIT
       call  DOSEXITLIST        ;

       push  0C001H             ;add late exitlist routine              ;@T11
       mov   ax,cs              ;sel:off to VIOENDPOPUP routine         ;@T11
       or    ax,3
       push  ax
       push  offset VIOENDPOPEXIT1                                      ;@T11
       call  DOSEXITLIST        ;                                       ;@T11

       xor   ax,ax                                                      ;@T14
       .if <cx a 3>             ;Invalid popup type flag?               ;@T14
         mov  [bp].rout_savAX,ERROR_VIO_INVALID_PARMS
       .else                                                        ;@T2,@T14

         mov   dx,common        ;ES <-- common data selector            ;@T14
         mov   es,dx            ;                                       ;@T14
         mov   dx,es:hetpid

         .if <ds:currPID ne dx> ;Do not get popup sem if harderr task   ;@T14
           and  cx,popwaitmask                                          ;@T14
           .if  <nz>            ;Wait flag set?                         ;@T14
             mov  cx,-1         ;Indicate wait until sem. is cleared    ;@T14
           .endif               ;                                       ;@T14
           .repeat
             push  dword ptr ds:pu_sem_lo                               ;@T14
             push  cx                                                   ;@T14
             push  cx                                                   ;@T14
             call  DOSSEMREQUEST        ;Request popup RAMsem           ;@T14
           .until <ax ne ERROR_INTERRUPT>
         .endif

         .if <nonzero ax> AND                                     ;P2859,@T14
         .if <ax ne ERROR_SEM_OWNER_DIED>                               ;@T14
           mov  [bp].rout_savAX,ERROR_VIO_EXISTING_POPUP
         .endif

       .endif

       .if <<word ptr [bp].rout_savAX> eq NO_ERROR> near
         push  1                ;disable signals                        ;P3825
         call  DOSHOLDSIGNAL    ;                                       ;P3825

         mov   ax,ds:currSG     ;record caller's original SG
         mov   ds:origSG,ax     ;

         mov   ax,ds:procTYPE   ;Save caller's original procTYPE        ;@T14
         mov   ds:origTYPE,ax

         mov   [bp].rout_savAX,avstonorm;preset AX <-- avstonorm        ;@T14

         .if <ds:procTYPE ne LIS_PT_DETACHED> near ;Not detached?  ;@T14;@C39

           call KBDLOADINSTANCE   ;load KBD INSTANCE data segment   ;@T2,@T85

           mov   ax,es:hetpid     ;don't request FS RAM sem if caller
           .if <ds:currPID ne ax> ;  is harderr

             .repeat
               push  dword ptr ds:fsRAMoff ;Request FS RAM sem ;@T2,D549,@T14
;@T18          push  wait_hi            ;no timeout
               push  dword ptr -1       ;                               ;@T18
               call  DOSFSRAMSEMREQUEST ;request SGPIDSYNC semaphore
             .until <ax ne ERROR_INTERRUPT>

             mov   eax,dword ptr ds:fsRAMoff    ;Save fsRAMsem address  ;@T14
             mov   dword ptr ds:rqdSEMoff,eax                           ;@T14

           .endif

           mov   cl,equpopup
           mov   dx,0001H
           rol   dx,cl

           and   dx,gs:[bx].VIO_masklo  ;always VIO_masklo for popup ;D549,@T80

           mov   es,ds:gdtinfo          ;
           mov   al,es:[SIS_CurScrnGrp] ;Get foreground session ID      ;@T14
           cbw                          ;                               ;@T14

           .if <nonzero dx>  and        ;VIOPOPUP replaced and current  ;P2859
           .if <ax eq ds:currSG>        ;screen group is in FG      ;@T2,@T14
             popa
             pop   gs                                              ;D549,@T80
             pop   es
             leave
             call dword ptr ds:avs_off ;call subsystem
             enter 10,0                                                 ;1.2
             push  es
             push  gs                                              ;D549,@T80
             pusha
           .endif

           mov  ax,common       ;need to setup es again                 ;@T14
           mov  es,ax                                                   ;@T14

           xor  ax,ax                                                   ;P2859
           push es              ;data area for mode data struc.         ;@T14
           push offset PUgetmode                                        ;@T52
           push ax              ;VIOhandle                              ;P2859
           push ax              ;dummy CS                               ;P2859
           push ax              ;dummy IP                               ;P2859
           push fc_getmode
           push ax              ;dummy IP                               ;P2859
           push ax                                                      ;P2859
           call dword ptr ds:bvs_off
           add  sp,16           ;remove dummy parameters

           mov  ax,es:hetpid            ;don't clear FS RAM sem         ;@T14
           .if <ds:currPID ne ax>       ;  if caller is harderr         ;@T14
             push dword ptr ds:rqdSEMoff                                ;@T14
             call DOSFSRAMSEMCLEAR
           .endif

         .endif                 ;End of detached process check          ;@T14

         .if <<word ptr [bp].rout_savAX> eq avstonorm> near
           push ds
           lds  si,dword ptr [bp].puwaitoff ; (stack parameter)
           mov  ax,[si]
           and  ax,0000000000000010B
           shr  ax,1
           pop  ds

           push ds:procTYPE             ;tell sess. mgr. to switch
           push ax                      ;
           push ds:currPID              ;
           push ds:currSG               ;
           CALL DOSSMSGDOPOPUP          ;                               ;MDLL

           mov  [bp].rout_savAX,ax      ;return code

           .if <zero ax>        near                                    ;P2859

             inc  ds:pop_mode           ;place this PID in POPUP MODE   ;@T2

             sub  dx,dx                 ;Assume VIO_times is zero       ;@T14
             mov  si,es:SHELLPID        ;Don't grab FSRAMsem if detached ;@T14

             .if <ds:procTYPE ne LIS_PT_DETACHED> ;Not detached?        ;@T14
               lgs  bx,dword ptr ds:SGCB ;GS:BX --> SGCB           ;@T14,@T80
               mov  dx,gs:[bx].VIO_times                           ;@T14,@T80
               lgs  di,dword ptr ds:fsRAMoff ;Setup FSRAMsem address ;@T14,@T80
               mov  si,gs:[di].fs_PID   ;See if someone has FSRAMsem ;@T14,@T80
             .endif

             mov  ax,es:hetpid          ;Get harderr PID

             .if <ds:currPID ne ax> and ;if popper was FG, don't request
             .if <si ne es:SHELLPID>    ;sem because DOSSMSGDOPOPUP ;D549,@T14
                                        ;kept it
               .repeat                  ;request FS RAM sem
                 push gs                ;                     ;D549,@T14,@T80
                 push di                ;                               ;@T14
;@T18            push wait_hi           ;
                 push dword ptr -1      ;                               ;@T18
                 call DOSFSRAMSEMREQUEST
               .until <ax ne ERROR_INTERRUPT>

               push gs                  ;Keep current fsRAMsem on the ;@T14,@T80
               push di                  ;  stack to be clear later      ;@T14

               .if <ds:procTYPE ae LIS_PT_PRESMGR> and                  ;@T18
               .if <ds:detachpop e 0>   ;Initialization necessary?      ;@T18
                 call OS2BASEINIT       ;Tell everyone to sync up       ;@T14

                 .if <zero ax>          ;error returned            ;D549,@T14
                   call suicide                                         ;D549
                 .endif                                                 ;D549
                 mov  ds:detachpop,1                                    ;@T18
               .else                    ;                               ;@T18
                 push ds:SGCB_pop       ;Swap popup SGCB with           ;@T18
                 mov  eax,ds:SGCB       ;  caller's SGCB                ;@T18
                 mov  ds:SGCB_pop,eax   ;                               ;@T18
                 pop  ds:SGCB           ;                               ;@T18
               .endif                                                   ;@T18

               lgs  bx,ds:SGCB          ;Setup popup SGCB pointer  ;D549,@T80

               lea  ax,gs:[bx].VIO_fsRAMsem                        ;D549,@T80
               mov  ds:fsRAMsel,gs      ;Save popup fsRAMsem address ;D549,@T80
               mov  ds:fsRAMoff,ax      ;

               call DOSFSRAMSEMCLEAR    ;Release the previous fsRAMsem  ;@T14
             .else

               .if <ds:procTYPE ae LIS_PT_PRESMGR> and                  ;@T18
               .if <ds:detachpop e 0>   ;Initialization necessary?      ;@T18
                 call OS2BASEINIT                                       ;@T14

                 .if <zero ax>          ;error returned            ;D549,@T14
                   call suicide                                         ;D549
                 .endif                                                 ;D549
                 mov  ds:detachpop,1                                    ;@T18
               .elseif <ds:currPID ne ax> ;Caller is not Harderr?       ;@T18
                 push ds:SGCB_pop       ;Swap popup SGCB with           ;@T18
                 mov  eax,ds:SGCB       ;  caller's SGCB                ;@T18
                 mov  ds:SGCB_pop,eax   ;                               ;@T18
                 pop  ds:SGCB           ;                               ;@T18
               .endif                                                   ;@T18

               lgs  bx,ds:SGCB          ;Setup popup SGCB pointer  ;D549,@T80

               lea  ax,gs:[bx].VIO_fsRAMsem                        ;D549,@T80

               mov  ds:fsRAMsel,gs      ;Save popup fsRAMsem address ;D549,@T80
               mov  ds:fsRAMoff,ax      ;
             .endif

;@T18        mov  eax,ds:SGCB           ;Tucked away the old SGCB       ;@T14
;@T18        mov  ds:SGCB_pop,eax       ;  for EndPopup                 ;@T14

             mov  gs:[bx].VIO_times,dx  ;Record               ;D549,@T14,@T80

             push 0000H                 ;flush keystroke buffer
             call KBDFLUSHBUFFER        ;                           ;@T2,@T85
           .else
             push dword ptr ds:pu_sem_lo                                ;@T14
             call DOSSEMCLEAR           ;clear POPUP semaphore
           .endif

         .else
           push dword ptr ds:pu_sem_lo                                  ;@T14
           call DOSSEMCLEAR             ;clear POPUP semaphore
         .endif

         push  0                ;enable signals                         ;P3825
         call  DOSHOLDSIGNAL    ;                                       ;P3825
       .endif

     .endif

   .endif

   .if <ds:Igvs_count ne 0> NEAR AND    ;if at least one GVS exists     ;1.2
   .if <ds:currSG ne 0> NEAR AND        ;AND caller is from             ;1.2
   .if <ds:currSG b 16> NEAR            ;                               ;1.2

     lgs  bx,dword ptr ds:fsRAMoff                       ;P3096;1.2;@T52,@T80

     mov  ax,common                                                     ;@T2
     mov  es,ax                                                         ;@T2

     .repeat                                                    ;P3096  ;1.2
       push gs                                  ;@T2 ;P3096  ;1.2  ;D549,@T80
       push bx                                                  ;P3096  ;1.2
;@T18  push wait_hi                                             ;P3096  ;1.2
       push dword ptr -1                                    ;P3096  ;1.2,@T18
       call DOSFSRAMSEMREQUEST                                  ;P3096  ;1.2
     .until <ax ne ERROR_INTERRUPT>                             ;P3096  ;1.2

     mov  ds:rqdSEMsel,gs                                          ;D549,@T80
     mov  ds:rqdSEMoff,bx                                       ;P3096

     mov  di,[bp].rout_fc         ;DI <-- off. into GVS record   ;P2859 ;1.2
     shl  di,2                    ;                              ;P2859 ;1.2
     add  di,common2_beg          ;                              ;P2859 ;1.2

     mov  ax,es:[di]+2            ;                              ;P2859 ;1.2
     mov  [bp].funcmask,ax        ;setup [bp].funcmask for compare      ;1.2

     mov  di,es:[di]              ;DI <-- proper offset into     ;P2859 ;1.2
     add  di,Igvs_loest           ;Igvs record for the current          ;1.2
                                  ;function                             ;1.2
     mov  bx,idata_sz             ;BX --> first Igvs_record             ;1.2

     .repeat                      ;mark all .replaced fields            ;1.2
       mov  ax,ds:[bx][di]        ;if VioPopUp has been          ;P2859 ;1.2
       and  ax,[bp].funcmask      ;registered by a GVS                  ;1.2
       mov  ds:[bx].Ireplaced,ax  ;                              ;P2859 ;1.2
       add  bx,Igvs_rec_sz        ;                                     ;1.2
     .until <bx a ds:Igvs_last>   ;                                     ;1.2

     mov   ds:Igvs_quit,0                                               ;1.2
     popa                                                               ;1.2
     pop  gs                                                       ;D549,@T80
     pop  es                                                            ;1.2
     leave                                                              ;1.2

     mov  ds:gvs_cntr,0           ;reset gvs counter             ;P2859 ;1.2

     .repeat                                                            ;1.2
       push  ax                   ;save registers                       ;1.2
       push  bx                   ;                                     ;1.2

       mov   ax,ds:gvs_cntr       ;BX <-- first GVS record              ;@T2
       imul  bx,ax,Igvs_rec_sz    ;                                     ;@T2
       add   bx,idata_sz          ;                                     ;@T2

       inc   ds:gvs_cntr          ;set up for next repetition           ;1.2

       .if <ds:[bx].Ireplaced ne 0>                                     ;1.2
         mov   ax,ds:[bx].Igvs_off;setup GVS address to call            ;1.2
         mov   ds:gvsCURoff,ax    ;                                     ;1.2
         mov   ax,ds:[bx].Igvs_sel;                                     ;1.2
         mov   ds:gvsCURsel,ax    ;                                     ;1.2
         pop   bx                 ;                                     ;1.2
         pop   ax                 ;                                     ;1.2
         call  dword ptr ds:gvsCURoff                                   ;1.2
         push  ax                 ;save registers                       ;1.2
         push  bx                 ;                                     ;1.2
       .endif                                                           ;1.2

       mov  ax,ds:gvs_cntr                                              ;1.2

       .if <ax eq ds:Igvs_count>                                        ;1.2
         mov  ds:Igvs_quit,1                                            ;1.2
       .endif                                                           ;1.2

       pop  bx                    ;                                     ;1.2
       pop  ax                    ;                                     ;1.2
     .until <ds:Igvs_quit eq 1>                                         ;1.2

     enter 10,0                                                         ;1.2
     push  es                                                           ;1.2
     push  gs                                                      ;D549,@T80
     pusha                                                              ;1.2

     .repeat                                                    ;P3096  ;1.2

       push dword ptr ds:rqdSEMoff                            ;P3096;1.2,@T14
       call DOSFSRAMSEMCLEAR                                    ;P3096  ;1.2
     .until <ax ne ERROR_INTERRUPT>                             ;P3096  ;1.2
   .endif                                                       ;P3096  ;1.2

   .if <<word ptr [bp].rout_savAX> ne NO_ERROR>
     push ax                    ;save return code
     push 2                     ;remove routine from DOSEXITLIST
     mov  ax,cs                 ;sel:off to VIOENDPOPEXIT routine
     or   ax,3
     push ax
     push offset VIOENDPOPEXIT  ;
     call DOSEXITLIST           ;

     push 2                     ;remove late exitlist routine           ;@T11
     mov  ax,cs                 ;sel:off to VIOENDPOPEXIT1 routine      ;@T11
     or   ax,3
     push ax
     push offset VIOENDPOPEXIT1 ;                                       ;@T11
     call DOSEXITLIST           ;                                       ;@T11
     pop  ax                    ;restore retuen code
   .endif

   IFDEF MMIOPH                                                         ;DTBB1
   mov   es,ds:gdtinfo                          ;@tb17 ES <-- global info sel.
   mov   al,es:[SIS_MEC_TABLE].SIS_VIOMEC       ;@tb17 AL <-- byte w/VIO MEC
   test  al,traceonoffmask                      ;@tb17 0=OFF, non-0=ON

   .if <nz>                                     ;@tb17
     call  vioposttrace ;post-invocation system trace
   .endif                                       ;@tb17
   ENDIF                                                                ;DTBB1

   popa
   pop   gs                                                         ;D549,@T80
   pop   es
   leave
   cwde
   pop  ds              ;restore caller's DS
   add  sp,4            ;remove dummy IP and function code
VIOPOPUP_POSTDT label far                                               ;DTBB1
   ret  6               ;return and pop parameters
VIOPOPUP endp

        SUBTTL VIOENDPOPUP - TERMINATE A POPUP
        page
;/*********************** START OF SPECIFICATIONS ****************************/
;/* SUBROUTINE NAME: VIOENDPOPUP                                             */
;/*                                                                          */
;/* DESCRIPTIVE NAME: foreground POPUP termination                           */
;/*                                                                          */
;/* FUNCTION:                                                                */
;/*                                                                          */
;/* NOTES:                                                                   */
;/*                                                                          */
;/* ENTRY POINT: VIOENDPOPUP                                                 */
;/*     LINKAGE: FAR CALL                                                    */
;/*                                                                          */
;/* INPUT: "WAIT" - wait flags (DWORD ptr on stack)                          */
;/*        "DEV_HANDLE" - device handle (reserved WORD of 0000H on stack)    */
;/*                                                                          */
;/* EXIT-NORMAL: AX = NO_ERROR                                               */
;/*                                                                          */
;/* EXIT-ERROR: AX = ERROR_VIO_NO_POPUP - POPUP not allocated                */
;/*             AX = error code from AVS                                     */
;/*                                                                          */
;/* EFFECTS: The contents of AX are destroyed.                               */
;/*                                                                          */
;/* INTERNAL                                                                 */
;/* REFERENCES: currSG - current process's screen group (local info)         */
;/*             SGDATA[currSG].POP_MODE - set from VIOPOPUP to VIOENDPOPUP   */
;/*             POPSYNC - handle for POPUP synch. system semaphore           */
;/*             SGSYNC - handle for currSG's per SG synch. system semaphore  */
;/*   ROUTINES: None.                                                        */
;/*                                                                          */
;/* EXTERNAL                                                                 */
;/* REFERENCES: None.                                                        */
;/*   ROUTINES: DOSSEMREQUEST - request a semaphore                          */
;/*             DOSSEMCLEAR - clear a semaphore                              */
;/*             KBDFLUSHBUFFER - flush the keystroke buffer                  */
;/*             DOSSMSGENDPOPUP - sess. mgr. endpopup screen switch          */
;/*********************** END OF SPECIFICATIONS ******************************/
;VIOENDPOPUP psuedo code:
;  if PID's first VIO call
;    call getinfosegs
;
;  call viopretrace
;  currSG <-- current screen group
;  BX <-- SGDATA[currSG] offset
;
;  if (never attached) OR (no attach since last VIOREGISTER/VIODEREGISTER)
;    AX <-- ERROR_VIO_NO_POPUP
;  else
;
;    if currPID != hetPID
;      request currSG's FS RAM sem
;
;    if VIOENDPOPUP replaced
;      call AVS
;
;    if currPID != hetPID
;      clear currSG's FS RAM sem
;
;    if AVS desires default system action
;
;      if pop_mode == 0
;        AX <-- ERROR_VIO_NO_POPUP
;      else
;        pop_mode <-- 0
;        disable signals
;        call DOSSMSGENDPOPUP
;        ES:[BX].paused <-- 0
;        call KBDFLUSHBUFFER
;
;        if currPID != hetPID
;          request oldSG's FS RAM sem
;
;        sysSEMhdlPTR <-- currSG's FS RAM sem offset
;
;        if currPID != hetPID
;          clear oldSG's FS RAM sem
;
;        enable signals
;
;  request currSG's FS RAM sem
;
;  if at least one GVS exists
;
;     for each GVS registered
;
;        if GVS has repleced VioPopUp
;           call GVS
;
;  clear currSG's FS RAM sem
;  call vioposttrace
;  return

VIOENDPOPEXIT1 proc far                 ;Late exit line routine         ;@T11
   push ds                                                              ;@T11
   mov  ax,instance                                                     ;@T11
   mov  ds,ax                                                           ;@T11
   mov  ds:popexit,2                                                    ;@T11
   pop  ds                                                              ;@T11
   jmp  short VIOENDPOPUP                                               ;@T11
VIOENDPOPEXIT1 endp                                                     ;@T11

VIOENDPOPEXIT proc far
   push ds
   mov  ax,instance
   mov  ds,ax
   mov  ds:popexit,1
   pop  ds
VIOENDPOPEXIT endp
VIOENDPOPUP proc far
   xor   ax,ax          ;preset AX = NO_ERROR
   push  fc_endpopup    ;VIOENDPOPUP function code
   push  ax             ;dummy nearIP                                   ;@T2
   push  ds             ;save registers
   enter 10,0           ;make stack look like viorout's (use BP)        ;1.2
   push  es             ;save registers
   push  gs                                                        ;D549,@T80
   pusha

   mov  bx,instance     ;DS <-- INSTANCE data selector                  ;P2859
   mov  ds,bx           ;                                               ;P2859

   IFDEF MMIOPH                                                         ;DTBB1
   mov  es,ds:gdtinfo                   ;ES <-- global info sel.
   mov  al,es:[SIS_MEC_TABLE].SIS_VIOMEC;AL <-- byte w/VIO MEC
   test al,traceonoffmask               ;0=OFF, non-0=ON

   .if <nz>                                                             ;@T2
     call viopretrace
   .endif
   ENDIF                                                                ;DTBB1

   mov  ax,common               ;ES <-- COMMON data selector
   mov  es,ax                   ;

   lgs  bx,ds:SGCB              ;load gs:[bx] with SGCB ptr        ;D549,@T80

   mov  ax,ds:oldtimes          ;AX <-- number of REGISTERs for this SG ;P2964

   .if <ds:bvs_sel eq 0> or                                             ;@T14f
   .if <ax ne gs:[bx].VIO_times>                                   ;D549,@T80
     mov   [bp].rout_savAX,ERROR_VIO_NO_POPUP
   .elseif <<word ptr[bp].puviohndl> ne 0> and
   .if <ds:popexit e 0>                                                 ;@T11
     mov   [bp].rout_savAX,ERROR_VIO_INVALID_HANDLE
   .else near                                                           ;@T11
     .if <ds:popexit e 2> and   ;Already cleanup?                       ;@T11
     .if <ds:pop_mode e 0>                                              ;@T11
       sub   ax,ax              ;Nothing to do!!                        ;@T11
     .else near                                                         ;@T11

       .if <ax ne gs:[bx].VIO_times>                     ;@T7,P2964,D549,@T80
         call  vioattach                                            ;@T7,P2964
       .endif                                                       ;@T7,P2964
       mov  ax,es:hetPID

       .if <ds:currPID ne ax>

         .repeat
           push dword ptr ds:fsRAMoff   ;Request popup fsRAMsem    ;D549,@T14
;@T18      push wait_hi
           push dword ptr -1                                            ;@T18
           call DOSFSRAMSEMREQUEST
         .until <ax ne ERROR_INTERRUPT>

         mov  eax,dword ptr ds:FSRAMoff ;Save popup fsRAMsem address    ;@T14
         mov  dword ptr ds:rqdSEMoff,eax                           ;D549,@T14
       .endif

       mov   [bp].rout_savAX,avstonorm        ;Besure endpopup is called;@T14

       .if <ds:origTYPE ne LIS_PT_DETACHED>   ;Not a detached process   ;@T14

         .if  <ds:pop_mode a 0> ;Popup in progress                      ;@T14
           les  di,ds:SGCB_pop  ;Setup pointer to previous SGCB    ;D549,@T14
         .else                  ;                                       ;@T14
           les  di,ds:SGCB      ;Setup pointer to the current SGCB      ;@T14
         .endif                 ;                                       ;@T14

         mov  cl,equendpopup    ;
         mov  ax,0001H          ;AX <-- 0 :  if VIOENDPOPUP not replaced
         rol  ax,cl             ;
                                ;
         and  ax,es:[di].VIO_masklo     ;always VIO_masklo for endpopup ;D549

         .if <nonzero ax>       ;VIOENDPOPUP replaced?            ;P2859,@T14
           popa
           pop   gs                                                ;D549,@T80
           pop   es
           leave
           call dword ptr ds:avs_off    ;call subsystem
           enter 10,0                                                   ;1.2
           mov   [bp].rout_savAX,ax     ;Save AVS return code           ;@T14
           push  es
           push  gs                                                ;D549,@T80
           pusha
           lgs   bx,ds:SGCB     ;Setup pointer to popup SGCB       ;@T14,@T80
         .endif

         mov  ax,common         ;ES <-- COMMON data selector            ;@T14
         mov  es,ax             ;                                       ;@T14

       .endif                   ;End of detached process check          ;@T14

       mov  ax,es:hetPID        ;AX <-- Hard Error Task PID

       .if <ds:currPID ne ax>   ;if not Hard Error Task

         .if <ds:popexit a 1>   ;if currPID is terminating              ;@T11

           .repeat
             push dword ptr ds:rqdSEMoff        ;force ownership   ;D549,@T14
;@T18        push nowait_hi                     ;  of fsRAMsem
             push dword ptr 0                                           ;@T18
             call DOSFSRAMSEMREQUEST
           .until <ax ne ERROR_INTERRUPT>

           .if <zero ax> OR                                       ;P2859,P3093
           .if <ax eq ERROR_SEM_OWNER_DIED>                             ;P3093
             mov  cx,gs:[bx].VIO_FSRAMsem.fs_count ;number ;P3610;D549,@T14,@T80
                                        ; of times to clear semaphore
             .if  <ncxz>                ;Any semaphores to clear?       ;@S35
               .repeat                  ;clear currSG's FS RAM sem      ;P3093
                 push dword ptr ds:rqdSEMoff    ;until use         ;D549,@T14
                 call DOSFSRAMSEMCLEAR          ;  count = 0

                 .if <ax eq ERROR_INTERRUPT>    ;if interrupted, try    ;P3610
                   inc  cx                      ;  again                ;P3610
                 .endif                                                 ;P3610

               .loop                                                    ;P3610
             .endif                     ;@S35

           .endif                                                       ;P3093

         .else                                                          ;P3093
           push dword ptr ds:rqdSEMoff                                  ;@T14
           call DOSFSRAMSEMCLEAR
         .endif

       .endif

       .if <<word ptr [bp].rout_savAX> eq avstonorm> near or            ;@tb38
       .if <ds:pop_mode eq 1> near                                      ;@tb38

         .if <ds:pop_mode eq 0>
           mov   [bp].rout_savAX,ERROR_VIO_NO_POPUP
         .else near
           push  1              ;disable signals
           call  DOSHOLDSIGNAL

           mov   ds:pop_mode,0                                          ;P3825

           push  ds:currSG      ;tell sess. mgr. to switch
           CALL  DOSSMSGENDPOPUP                                        ;MDLL

           mov   [bp].rout_savAX,ax     ;return code
           .if   <zero ax>                                              ;@T7
             push  ds                                                   ;@T7
             mov   ds,ds:ldtinfo                                        ;@T7
             mov   al,ds:[LIS_ProcType]                                 ;@T7
             mov   cx,ds:[LIS_CurScrnGrp]                               ;@T14
             pop   ds                                                   ;@T7
             mov   ds:procTYPE,ax                                       ;@T7
             mov   ds:currSG,cx                                         ;@T14
           .endif                                                       ;@T7
           mov   gs:[bx].VIO_paused,0   ;reset popup scrn grp      ;D549,@T80
                                        ;  NumLock bit
           mov   ax,es:hetPID

           .if <ds:currPID ne ax>

             .repeat
               push  dword ptr ds:fsRAMoff      ;request currSG's  ;D549,@T14
;@T18          push  wait_hi                    ;  fsRAMsem
               push  dword ptr -1                                       ;@T18
               call  DOSFSRAMSEMREQUEST
             .until <ax ne ERROR_INTERRUPT>

             mov  eax,dword ptr ds:fsRAMoff                             ;@T14
             mov  dword ptr ds:rqdPOPoff,eax                       ;D549,@T14
           .endif

;@T14f     .if <ds:procTYPE ne LIS_PT_DETACHED>                         ;P3707

             mov  ax,es:hetPID                                          ;@T18
             .if  <ds:currPID ne ax>    ;Caller is not Harderr?         ;@T18
               push ds:SGCB                                             ;@T18
               mov  eax,ds:SGCB_pop     ;Restore to previous SGCB       ;@T14
               mov  ds:SGCB,eax         ;                               ;@T14
               pop  ds:SGCB_pop                                         ;@T18

               add  ax,VIO_fsRAMsem                                ;D549,@T14
               mov  dword ptr ds:fsRAMoff,eax   ;Save fsRAMsem address  ;@T14
             .endif                                                     ;@T18

             xor  ax,ax                                           ;P2859,P3707
             push es            ;data area for mode data struc.     ;@T2,P3707
             push offset PUgetmode                                ;P3707,@T52
             push ax            ;VIOhandle                        ;P2859,P3707
             push ax            ;dummy CS                         ;P2859,P3707
             push ax            ;dummy IP                         ;P2859,P3707
             push fc_getmode                                            ;P3707
             push ax            ;dummy IP                         ;P2859,P3707
             push ax                                              ;P2859,P3707
             call dword ptr ds:bvs_off                            ;P2859,P3707
             add  sp,16         ;remove dummy parameters                ;P3707
;@T14f     .endif                                                       ;P3707

           mov  ax,es:hetPID

           .if <ds:currPID ne ax>

             .if <ds:popexit a 1>       ;if currPID is terminating      ;@T11
               push  dword ptr ds:rqdPOPoff                             ;@T14
;@T18          push  nowait_hi          ;(sets COUNT = 1)
               push  dword ptr 0        ;                               ;@T18
               call  DOSFSRAMSEMREQUEST
             .endif

             mov   di,ds:rqdPOPoff      ;@S35;D549
             mov   cx,gs:[di].fs_count  ;@S35                 ;@T10,D549,@T80
             .if  <ncxz>                ;Any semaphores to clear?       ;@S35
               .repeat                  ;                               ;@T10
                 push  dword ptr ds:rqdPOPoff                           ;@T14
                 call  DOSFSRAMSEMCLEAR
                 .if <ax eq ERROR_INTERRUPT>    ;if interrupted, try    ;@S35
                   inc  cx                      ;  again                ;@S35
                 .endif                         ;@S35
               .loop                            ; @tb16 (endif moved)   ;@T10
             .endif                             ;@S35
             push  dword ptr ds:pu_sem_lo       ;clear POPUP SYSSEM     ;@T14
             call  DOSSEMCLEAR                  ;
           .endif                               ;@tb16

           push  0              ;enable signals
           call  DOSHOLDSIGNAL
         .endif

       .endif

     .endif                     ;Already cleanup!!!!                    ;@T11

   .endif

   .if <ds:Igvs_count ne 0> NEAR AND    ;if at least one GVS exists     ;1.2
   .if <ds:currSG ne 0> NEAR AND        ;AND caller is from             ;1.2
   .if <ds:currSG b 16> NEAR            ;                               ;1.2

     push dword ptr ds:fsRAMoff                          ;P3096;1.2;@T52,@T14

     mov  ax,common                                                     ;@T2
     mov  es,ax                                                         ;@T2

     .repeat                                                      ;P3096,1.2
       push dword ptr ds:fsRAMoff                             ;P3096,1.2,@T14
;@T18  push wait_hi                                               ;P3096,1.2
       push dword ptr -1                                      ;P3096,1.2,@T18
       call DOSFSRAMSEMREQUEST                                    ;P3096,1.2
     .until <ax ne ERROR_INTERRUPT>                               ;P3096,1.2

     pop  dword ptr ds:rqdSEMoff                                        ;@T14

     mov  di,[bp].rout_fc       ;DI <-- off. into GVS record      ;P2859,1.2
     shl  di,2                  ;                                 ;P2859,1.2
     add  di,common2_beg        ;                                 ;P2859,1.2

     mov  ax,es:[di]+2          ;                                 ;P2859,1.2
     mov  [bp].funcmask,ax      ;setup [bp].funcmask for compare        ;1.2

     mov  di,es:[di]            ;DI <-- proper offset into        ;P2859,1.2
     add  di,Igvs_loest         ;Igvs record for the current      ;P2859,1.2
                                ;function
     mov  bx,idata_sz           ;BX --> first Igvs_record               ;1.2

     .repeat                    ;mark all .replaced fields              ;1.2
       mov  ax,ds:[bx][di]      ;if VioPopUp has been             ;P2859,1.2
       and  ax,[bp].funcmask    ;registered by a GVS                    ;1.2
       mov  ds:[bx].Ireplaced,ax                                  ;P2859,1.2
       add  bx,Igvs_rec_sz      ;                                       ;1.2
     .until <bx a ds:Igvs_last>                                         ;1.2

     mov   ds:Igvs_quit,0                                               ;1.2
     popa                                                               ;1.2
     pop  gs                                                       ;D549,@T80
     pop  es                                                            ;1.2
     leave                                                              ;1.2

     mov  ds:gvs_cntr,0         ;reset gvs counter                ;P2859,1.2

     .repeat                                                            ;1.2
       push  ax                 ;save registers                         ;1.2
       push  bx                 ;                                       ;1.2

       mov   ax,ds:gvs_cntr     ;BX <-- first GVS record                ;@T2
       imul  bx,ax,Igvs_rec_sz                                          ;@T2
       add   bx,idata_sz        ;                                       ;@T2

       inc   ds:gvs_cntr        ;set up for next repetition             ;1.2

       .if <ds:[bx].Ireplaced ne 0>                                     ;1.2
         mov   ax,ds:[bx].Igvs_off  ;setup GVS address to call          ;1.2
         mov   ds:gvsCURoff,ax                                          ;1.2
         mov   ax,ds:[bx].Igvs_sel                                      ;1.2
         mov   ds:gvsCURsel,ax                                          ;1.2
         pop   bx               ;                                       ;1.2
         pop   ax               ;                                       ;1.2
         call  dword ptr ds:gvsCURoff                                   ;1.2
         push  ax               ;save registers                         ;1.2
         push  bx               ;                                       ;1.2
       .endif                                                           ;1.2

       mov  ax,ds:gvs_cntr                                              ;1.2

       .if <ax eq ds:Igvs_count>                                        ;1.2
         mov  ds:Igvs_quit,1                                            ;1.2
       .endif                                                           ;1.2

       pop  bx                  ;                                       ;1.2
       pop  ax                  ;                                       ;1.2
     .until <ds:Igvs_quit eq 1>                                         ;1.2

     enter 10,0                                                         ;1.2
     push  es                                                           ;1.2
     push  gs                                                      ;D549,@T80
     pusha                                                              ;1.2

     .repeat                                                      ;P3096,1.2
       push dword ptr ds:rqdSEMoff                            ;P3096,1.2,@T14
       call DOSFSRAMSEMCLEAR                                      ;P3096,1.2
     .until <ax ne ERROR_INTERRUPT>                               ;P3096,1.2
   .endif                                                               ;1.2

   IFDEF MMIOPH                                                         ;DTBB1
   mov   es,ds:gdtinfo                          ;@tb17 ES <-- global info sel.
   mov   al,es:[SIS_MEC_TABLE].SIS_VIOMEC       ;@tb17 AL <-- byte w/VIO MEC
   test  al,traceonoffmask                      ;@tb17 0=OFF, non-0=ON

   .if <nz>                                     ;@tb17
     call  vioposttrace ;post-invocation system trace
   .endif                                       ;@tb17
   ENDIF                                                                ;DTBB1

   mov  ax,instance
   mov  ds,ax

   mov  ax,cs
   or   ax,3
   cmp  ds:popexit,1                                                    ;@T11
   .if  <ae>                                                            ;@T11
     push 3                     ;transfer control to next routine
     push ax                    ;sel:off to VIOENDPOPUP routine
     .if  <e>                                                           ;@T11
       push offset VIOENDPOPEXIT
     .else                                                              ;@T11
       push offset VIOENDPOPEXIT1                                       ;@T11
     .endif                                                             ;@T11
     mov  ds:popexit,0          ;done exitlist cleanup                  ;@T11
     call DOSEXITLIST           ;
   .endif

   popa
   pop   gs                                                        ;D549,@T80
   pop   es
   leave
   cwde                 ;convert AX to EAX                              ;@T14
   pop  ds              ;restore DS
   add  sp,4            ;remove dummy IP and function code
VIOENDPOPUP_POSTDT label far                                            ;DTBB1
   ret  2
VIOENDPOPUP endp

cseg ends
     end
