;       SCCSID = @(#)smgpaude.asm	6.1 90/11/18
;	SCCSID @(#)smgpaude.asm	6.8 90/09/12
PAGE 60,132    ;
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************

;***************************************************************************
;									   *
; Source File Name:   SMGPAUDE						   *
;									   *
; Subroutine Name:    DOSSMPAUDAEMON					   *
;									   *
; Descriptive Name:   Ctrl-Numlock daemon thread			   *
;									   *
; Function:   Process a Ctrl-Numlock request on a per screen group basis.  *
;	      When a Ctrl-Numlock event is received the Session Manager	   *
;	      sets a flag and a ram semaphore. VIO detects that the flag   *
;	      is on and blocks any display I/O from occurring by blocking  *
;	      each process in the screen group using the ram semaphore.	   *
;									   *
; Notes:								   *
;     Dependencies:   This procedure is called via DOSCREATETHREAD.	   *
;									   *
;     Restrictions:   None						   *
;									   *
;   Change History:							   *
;	@@A5 - 02/16/90 - PTR B787589 - Use pause semaphore in SGCB	   *
;	@TL7 - 04/05/90 - PTR B712376 - Enable for MMIO			   *
;	@MHW - 09/13/90 - PTR B715818 - Removed MMIO support.		   *
;									   *
; Entry Point:								   *
;	  Linkage:    EXTRN  DOSSMPAUDAEMON:FAR				   *
;									   *
; Inputs:     None							   *
;									   *
; Exit Normal:	      None						   *
;									   *
; Exit Errors:	      None						   *
;									   *
; Effects:    This is an infinite loop for the Session Manager control	   *
;	      numlock daemon thread.					   *
;									   *
; Internal References:							   *
;	   Data:      The following data is in a shared data segment(SDATA)*
;									   *
;		      pauresppacket - pause screen response packet	   *
;		      globalselector - global info segment selector	   *
;		      pausedata	    - screen group pause data address	   *
;									   *
;	   Routines:							   *
;									   *
; External References:							   *
;	   Data:							   *
;	   Routines:  DOSSYSTEMSERVICE					   *
;		      DOSSEMREQUEST					   *
;		      DOSSEMCLEAR					   *
;		      DOSSEMSET						   *
;									   *
;***************************************************************************
ifdef I1
;
;   REPEAT
;      DOSSYSTEMSERVICE (Wait for Ctrl-Num notification)
;
;      Code from DOSSMPAUSE follows:
;      Get fg sg
;      IF (Sg# ne 1)
;	  Establish addressability to pause data
;
;	  IF (Release pause)
;	     DOSSEMSET (Block sg on ram sem)
;	     Toggle flag to resume VIO
;	  ELSE	(Pause SG)
;	     Toggle flag to pause VIO
;	     DOSSEMCLEAR (Unblock sg ram semaphore)
;	  ENDIF
;      ENDIF
;      ; End of code from DosSMPause
;   UNTIL (Wait for next event)
;
;***************************************************************************
else

.386C
   EXTRN PauseActionPacket   : WORD	; Pause action packet
   EXTRN PauseResponsePacket : WORD	; Pause screen response packet

   EXTRN DOSSYSTEMSERVICE : FAR		; Wait for shift/control prtsc
   EXTRN DOSSEMCLEAR	  : FAR		; Clear SG pause semaphore
   EXTRN DOSSEMSET	  : FAR		; Set SG pause semaphore
   EXTRN DOSSMGETSGCB	  : FAR		;				   @@A5

.xlist
   INCLUDE SMGPAUSE.INC
   INCLUDE SMRSGCB.INC
   INCLUDE SMRRDATA.INC
.xcref
   INCLUDE STRUC.INC
.cref
.list

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

   PUBLIC DOSSMPAUSE
   PUBLIC DOSSMPAUDAEMON

DOSSMPAUDAEMON PROC FAR

   Local_Bytes	EQU  4			;				   @@A5
   Local_Var	EQU  SS:[BP][-4]	;				   @@A5

   ENTER Local_Bytes,0
   MOV	AX, RDATA			; Addressability to shared data segment
   MOV	DS, AX
   MOV	SI, OFFSET PauseResponsePacket

;  *****************************************************
;  *  Wait for the kernel to notify the daemon thread  *
;  *  that a control numlock event has occurred.       *
;  *****************************************************
   .REPEAT
     PUSH 0				; Session Manager category
     PUSH DS				; Action packet for ctrl-numlock
     PUSH OFFSET PauseActionPacket
     PUSH DS				; Response packet address
     PUSH SI
     CALL DOSSYSTEMSERVICE

;    ********************************************
;    *	Capture foreground screen group and	*
;    *	establish addressability to pause data	*
;    ********************************************
     PUSH DS:[SI]			; Foreground screen group
     CALL FAR PTR DOSSMPAUSE
   .UNTIL				; Infinite loop, wait for next event

DOSSMPAUDAEMON ENDP



;***************************************************************************
;			    D O S S M P A U S E				   *
; This entire routine was re-written for @@A5				   *
;***************************************************************************
DOSSMPAUSE PROC FAR

   ENTER Local_Bytes,0			;
   PUSH DS
   PUSH DI
   PUSH DX

   MOV	DX, SS:[BP].Pause_SG		; Foreground screen group
   .IF	< DL ne Shell_SG >		; PM?

;    ******************************
;    *	Get the SGCB for this SG  *
;    ******************************
     LEA  DI, Local_Var			; @ return @ of SGCB
     PUSH SS
     PUSH DI
     PUSH DX				; SGID
     PUSH SGID_Lookup			; Look up SGID not PID
     CALL DOSSMGETSGCB

     .IF < zero AX >							;CJ10
       LDS  DI, Local_Var
       LEA  AX, [DI].VIO_Pause_Sem	; Offset from begining of SGCB	;CJ10
       PUSH DS				; Push address of VIO Semaphore
       PUSH AX								;CJ10
;CJ10  SUB  DI, VIO_Pause_Sem		; Point back to SGCB
;      *************************************************
;      *  If this SG is not paused, set the semaphore  *
;      *  and indicate that we are paused.  If it is   *
;      *  paused, then clear the semaphore and set     *
;      *  the indicator flag.			       *
;      *************************************************
       .IF  <<[DI].VIO_Paused> eq No >	  ; Are we paused?
	 CALL DOSSEMSET			  ; No, so block SG I/O
	 MOV  [DI].VIO_Paused, Yes	  ; Toggle flag

       .ELSE				  ; SG is paused
	 MOV  [DI].VIO_Paused, No	  ; Toggle flag
	 CALL DOSSEMCLEAR		  ; Unblock SG I/O
       .ENDIF
     .ENDIF				  ; DosSMGetSGCB Test
   .ENDIF				  ; If Shell not foreground test

   POP	DX				  ; Restore Registers
   POP	DI
   POP	DS

   XOR	AX, AX				  ; Always return no-failure
   LEAVE
   RET	2


DOSSMPAUSE ENDP

CODE ENDS
endif
   END
