;       SCCSID = @(#)smghdepu.asm	6.3 91/11/19
;	SCCSID @(#)smghdepu.asm	6.3 91/11/19
PAGE 60,132    ;
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************

;***************************************************************************
;
; Source File Name:	SMGHDEPU.ASM
;
; Subroutine Name:	DOSSMHDEPOPUP
;
; Descriptive Name:	Session Manager Hard Error Popup Switch
;
; Function:	Process a switch request to do/end a hard error
;		popup from the hard error daemon process.
;
; Notes:
;	Dependencies:	This procedure only receives control when a
;			system or shared RAM semaphore is cleared.
;
;			This procedure is called via DOSCREATETHREAD.
;
;	Restrictions:	None
;
;     Change History:
;	@TL7 - 04/05/90 - PTR B712376 - Enable for MMIO
;	@MHW - 09/13/90 - PTR B715818 - Removed MMIO support
;
; Entry Point:
;	Linkage:  EXTRN DOSSMHDEPOPUP:FAR
;
; Inputs:
;	None
;
; Exit Normal:
;	None
;
; Exit Errors:
;	None
;
; Effects:	This is an infinite loop for the hard error popup
;		switch.
;
; Internal References:
;	   Data:
;
;	   Routines:	DOSSMSGSWITCH
;
; External References:
;	   Routines:	DOSMUXSEMWAIT
;			DOSSEMCLEAR
;			DOSSEMSET
;
;***************************************************************************
ifdef I1
;
;   REPEAT (Wait on a list of semaphores until one is cleared)
;      DOSMUXSEMWAIT
;      IF (Index of Muxwait sem cleared e 0 [popup switch])
;	  DOSSEMSET (Muxwait semaphore)
;
;	  IF (BX e 4 [Do popup])
;	     DOSSEMREQUEST (Halt normal switch)
;	     IF (Popup active)
;		CX = current foreground sg
;	     ELSE
;		CX = popup sg
;	     ENDIF
;
;	  ELSE (BX = 5 [End popup request])
;	     IF (Other popup active)
;		DX = Old foreground sg
;	     ELSE
;		DX = popup sg
;	     ENDIF
;	     RC = Error_SMG_Already_Top
;	  ENDIF
;
;	  DOSSMGSWITCH (Change foreground sg)
;
;	  IF (BL e 4 [No other popups]) AND
;	  IF (Old popup sgid ne -1)
;	     Restore old popup sgid
;
;	  ELSEIF (BL e 5 [End popup]) AND
;	  IF (Old popup sgid ne 0)
;	     Restore old popup sgid
;	  ENDIF
;
;	  IF (BX e 5 [End popup])
;	     DOSSEMCLEAR (Allow normal switching)
;	  ENDIF
;	  DOSSEMCLEAR (Indicate switch complete)
;      ENDIF
;   UNTIL
;***************************************************************************
else

.386C
    EXTRN HdeIndex		: WORD	; Index to semaphore cleared
    EXTRN HdeOldFgnd		: WORD	; Old fgnd SG prior to popup
    EXTRN HdePopFlags		: WORD	; Do or end popup request
    EXTRN HdePopRetCode		: WORD	; Popup switch return code
    EXTRN HdeSMGRamSem		: DWORD ; Popup ram semaphore for SMGR
    EXTRN HdeSem		: WORD	; Semaphore list array
    EXTRN HdeSemNum		: WORD	; Number of semaphores in list
    EXTRN HdeVioRamSem		: DWORD ; Popup ram semaphore for VIO
    EXTRN BottomMost		: DWORD
    EXTRN CurrentDebugger	: WORD
    EXTRN IncomingDebugger	: WORD
    EXTRN PopUpScrnGrp2		: WORD
    EXTRN SwitchRamSem		: DWORD
    EXTRN TopMost		: DWORD

    EXTRN DOSSMGSWITCH	   : NEAR	; Change foreground screen group
    EXTRN DOSMUXSEMWAIT	   : FAR	; Wait for a semaphore to clear
    EXTRN DOSSEMCLEAR	   : FAR	; Release semaphore ownership
    EXTRN DOSSEMREQUEST	   : FAR	; Obtain semaphore ownership
    EXTRN DOSSEMSET	   : FAR	; Reset semaphore for MuxWait
.xlist
    INCLUDE SMRSGCB.INC
    INCLUDE SMRRDATA.INC
.xcref
    INCLUDE ERROR2.INC
    INCLUDE STRUC.INC
.cref
.list

CODE SEGMENT WORD PUBLIC 'CODE' USE16
    ASSUME CS:CODE,DS:RDATA,SS:NOTHING,ES:NOTHING,FS:NOTHING

    PUBLIC DOSSMHDEPOPUP
DOSSMHDEPOPUP PROC FAR

    Local_Bytes	 EQU  0

    ENTER Local_Bytes,0
    MOV	 AX, RDATA			; Addressability to global data
    MOV	 DS, AX

;   *****************************************
;   *  Block on a list of semaphores until  *
;   *  one of the semaphores is cleared	    *
;   *****************************************
    .REPEAT
      PUSH DS				; Index number of semaphore cleared
      PUSH OFFSET HdeIndex
      PUSH DS				; List of semaphore handles
      PUSH OFFSET HdeSemNum
      PUSH DWORD PTR -1			; Wait until semaphore clears	;CJ10
;CJ10 PUSH -1
      CALL DOSMUXSEMWAIT

;     ********************************************
;     *	 Process do or end popup switch request	 *
;     ********************************************
      .IF  <<DS:HdeIndex> eq 0> near	; Popup switch?
	PUSH DS				; Reset MUXWAIT sem.
	PUSH OFFSET HdeVioRamSem
	CALL DOSSEMSET

	MOV  BX, Do_PopUp		; Assume popup switch request
;CJ10	MOV  AX, HdePopFlags
	ADD  BX, HdePopFlags		; BX=4(DO) or 5(END) popup

	.IF  < BX eq Do_PopUp >		; Popup starting
	  PUSH DS			; Halt normal switch
	  PUSH OFFSET SwitchRamSem
	  PUSH DWORD PTR -1						;CJ10
;CJ10	  PUSH -1
	  CALL DOSSEMREQUEST

	  LES  SI, TopMost		; TopMost SGCB
	  LFS  DI, BottomMost		; Bottom SGCB

	  PUSH PopUpScrnGrp2		 ; Popup screen group ID
	  .IF  <PopUpScrnGrp2 eq 0FFFFH> ; Popup acitve?
	    MOV	 CX, FS:[DI].SGCB_ID	 ; Current foregnd SG
	    XOR	 CH, CH			 ; True SGID only
	  .ELSE
	    MOV	 CX, PopUpScrnGrp2	; popup SGo popup
	  .ENDIF

	  XOR  DX, DX			; Switch to screen group 0
	  XOR  AX, AX
	  MOV  IncomingDebugger, AX	; No debugger on popup		;CJ10

	.ELSE				; End popup request
	  LFS  DI, TopMost		; TopMost SGCB
	  LES  SI, BottomMost		; Bottom SGCB

	  PUSH DS:PopUpScrnGrp2		; Popup screen group ID
	  .IF  < PopUpScrnGrp2 eq 0 >	; Other popup active
	    MOV	 DX, FS:[DI].SGCB_ID	; Switch old fore SG
	    XOR	 DH, DH			; True SGID only
	  .ELSE
	    MOV	 DX, PopUpScrnGrp2	; Switch to popup
	    MOV	 PopUpScrnGrp2, 0
	  .ENDIF

	  MOV  AX, CurrentDebugger	 ; Restore
	  MOV  IncomingDebugger, AX	 ; Debug SID
	  MOV  AX, Error_SMG_Already_Top
	.ENDIF

;	FS:DI	Sel:Off	   New foreground SGCB
;	ES:SI	Sel:Off	   Previous queue SGCB
	CALL DOSSMGSWITCH		; Change foregrnd SG
	POP  DX				; Restore old popup SGID

	.IF  < BL eq Do_PopUp > AND	; No other popups
	.IF  < DX ne 0FFFFH >
	  MOV  PopUpScrnGrp2, DX	; Restore old popup
	.ELSEIF < BL eq End_PopUp > AND
	.IF  < nonzero DX >						;CJ10
	  MOV  PopUpScrnGrp2, DX	; Restore old popup
	.ENDIF

	.IF  < BX eq End_PopUp >
	  PUSH AX			; Save meaningful return code
	  PUSH DS			; Allow normal switch
	  PUSH OFFSET SwitchRamSem
	  CALL DOSSEMCLEAR
	  POP  AX			; Restore meaningful return code
	.ENDIF

	MOV  HdeOldFgnd, CX		; Save old fgnd SG ID
	MOV  HdePopRetCode, AX		; Set return code for VIO

	PUSH DS				; Indicate switch complete
	PUSH OFFSET HdeSMGRamSem
	CALL DOSSEMCLEAR

      .ENDIF
    .UNTIL				; Infinite loop

DOSSMHDEPOPUP ENDP

CODE ENDS
endif
    END
