;       SCCSID = @(#)vioblock.asm       6.2 91/06/14
;# SCCSID = @(#)vioblock.asm    6.2 91/06/14
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        SUBTTL  VIOSRFBLOCK, VIOSRFUNBLOCK
        TITLE   VIOBLOCK.ASM
;******************************************************************************
;*******   C H A N G E       H I S T O R Y   **********************************
;******************************************************************************
;@A0= Add support for VIOREDRAWSIZE (DCR 85)
;     02-03-88
;$A0= Clear OLDFGSGID flag after VIOUNBLOCK from VIOENDPOPUP
;     8-25-86 (7.49)
;$A1= check for CTRL-NUMLOCK/CTRL-S pause requests
;     9-12-86 (?.??)
;$Z9= request/clear PRTSCSEM in BLOCK/UNBLOCK (I don't know how this ever
;     got taken out!)
;%A0= Use FS RAM sems instead of system sems
;     07-30-87
;%A1= Request/Clear only current FG and new FG screen groups' semaphores
;     08-17-87
;P2778 = Change VioSrfUnBlock so tha VioRedrawSize is unaffected by VioRegister
;        06-07-88
;@T2  = 04/03/89 TPL, Sizzle work, PTR B701685
;@T7  = 07/06/89 TPL, Removal of 3xbox code
;D549 = 11/07/89 WKB, DCR549 Changes
;@T52 = 01/15/90 TPL, DCR 704 work
;@T18 = 05/07/90 TPL, B712103 - Optimize popup and screen switch processing
;@B722219 = 06/14/91 WKB, B722219 - Give up timeslice as appropriate
;MDLL = 01/10/94 BJN, Page Tune segments for Merged DLL.

.xlist
include error.inc
include struc.inc
include vioextrn.inc
include vioequ.inc
include viomac.inc
include vioidata.inc
include viocdata.inc
.list
.386p                                                                   ;D549

public  VIOSRFBLOCK
public  VIOSRFUNBLOCK

EXTRN   DOSSLEEP:FAR                                                    ;B722219
EXTRN   DOSFSRAMSEMREQUEST:FAR                                          ;%A0I
EXTRN   DOSFSRAMSEMCLEAR:FAR                                            ;%A0I
EXTRN   suicide:NEAR                                                    ;D549

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

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

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

        SUBTTL VIOSRFBLOCK - SAVE/RESTORE/FREE BLOCKER
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: VIOSRFBLOCK                                        */
;/*                                                                     */
;/* DESCRIPTIVE NAME: Save/Restore Block (from sess. mgr.)              */
;/*                                                                     */
;/* FUNCTION: The purpose of this function is to block all VIO calls    */
;/*           during a screen switch.                                   */
;/*                                                                     */
;/* NOTES: This function accomplishes its task by REQUESTing the        */
;/*        semaphores of the two screen groups involved in the a        */
;/*        screen group switch. The session manager controls which      */
;/*        screen group semaphores to request. A screen group number    */
;/*        of -1 indicates to skip this request.                        */
;/*                                                                     */
;/* ENTRY POINT: VIOSRFBLOCK                                            */
;/*     LINKAGE: FAR CALL (from session manager)                        */
;/*                                                                     */
;/*              PUSH    OldForeSG                                      */
;/*              PUSH    NewForeSG                                      */
;/*              Call    VIOSRFBLOCK                                    */
;/*                                                                     */
;/* INPUT: OldForeSG - Current foreground screen group number           */
;/*        NewForeSG - Screen group being switched to foreground        */
;/*        ES:SI    -> Out going FG SGCB pointer                @T18    */
;/*        FS:DI    -> In comming SGCB pointer                  @T18    */
;/*                                                                     */
;/* EXIT-NORMAL: AX = NO_ERROR                                          */
;/*                                                                     */
;/* EXIT-ERROR: AX <> NO_ERROR                                          */
;/*                                                                     */
;/* EFFECTS: The contents of AX are destroyed.                          */
;/*                                                                     */
;/* INTERNAL                                                            */
;/* REFERENCES: ?                                                       */
;/*   ROUTINES: ?                                                       */
;/*                                                                     */
;/* EXTERNAL                                                            */
;/* REFERENCES: ?                                                       */
;/*   ROUTINES: ?                                                       */
;/*********************** END OF SPECIFICATIONS *************************/

VIOSRFBLOCK proc far
   push bp              ;BP <-- stack frame pointer
   mov  bp,sp           ;
   push ds              ;save registers
;  push es              ;                                               ;@T18
;  push fs                                                         ;D549,@T18
   push di              ;                                               ;@T18
   push si              ;                                               ;@T18

   mov  ax,instance     ;address data segments
   mov  ds,ax           ;
;  mov  ax,common       ;                                               ;@T18
;  mov  es,ax           ;                                               ;@T18

   .repeat
;    push ds:prtscsemhi         ;wait until no VIOPRTSC                 ;@T18
     push dword ptr ds:prtscsemlo                                       ;@T18
;    push wait_hi               ;                                       ;@T18
     push dword ptr -1          ;                                       ;@T18
     call DOSSEMREQUEST         ;
   .until <ax ne ERROR_INTERRUPT>

;  mov  ax,ss:[bp+8]            ;Current foreground screen group        ;@T18

   .if  <<word ptr ss:[bp]+8> ne -1>    ;Valid out going SGid?          ;@T18
;    xor  ah,ah                 ;ignore session type of SGid       ;D549,@T18

;    push    ds                 ;sel:off to SGCB address           ;D549,@T18
;    push    offset SGCB_temp   ;  (returned)                 ;D549;@T52,@T18
;    push    ax                 ;                                  ;D549,@T18
;    push    Look_up_SGID       ;                                  ;D549,@T18
;    call    DOSSMGETSGCB       ;                                  ;D549,@T18

;    .if  <nonzero ax>          ;error returned                    ;D549,@T18
;      call suicide                                                ;D549,@T18
;    .endif                                                        ;D549,@T18

;    lfs   bx,ds:SGCB_temp      ;load with SGCB ptr                ;D549,@T18
     add   si,VIO_fsRAMsem      ;D549                                   ;@T18

; Keep track of screen group requesting ram semaphore

     push es                                                            ;B722219
     mov ax,common                                                      ;B722219
     mov es,ax                                                          ;B722219
     mov ax,ss:[bp]+8                                                   ;B722219
     xor ah,ah                                                          ;B722219
     mov es:RamSem_SGID, ax                                             ;B722219
     pop es                                                             ;B722219

     .repeat
       push es                  ;request curFG SG's fsRAMsem            ;D549
       push si                  ;
;@T18  push wait_hi             ;
       push dword ptr -1        ;                                       ;@T18
       call DOSFSRAMSEMREQUEST  ;
     .until <ax ne ERROR_INTERRUPT>

; Reset ram semaphore tracking word                                     ;B722219

     push es                                                            ;B722219
     mov ax,common                                                      ;B722219
     mov es,ax                                                          ;B722219
     mov es:RamSem_SGID, -1                                             ;B722219
     pop es                                                             ;B722219

     mov  ax,ds:currSG
     mov  es:[si].fs_client,ax                                     ;D549,@T18
   .endif

;  mov  ax,ss:[bp+6]            ;New foreground screen group            ;@T18

   .if  <<word ptr ss:[bp]+6> ne -1>    ;Valid in comming SGid?         ;@T18
;    xor  ah,ah                 ;ignore session type of SGid       ;D549,@T18

;    push    ds                 ;sel:off to SGCB address                ;D549
;    push    offset SGCB_temp   ;  (returned)                      ;D549;@T52
;    push    ax                 ;                                       ;D549
;    push    Look_up_SGID       ;                                       ;D549
;    call    DOSSMGETSGCB       ;                                       ;D549

;    .if  <nonzero ax>          ;error returned                         ;D549
;      call suicide                                                     ;D549
;    .endif                                                             ;D549

;    lfs   bx,ds:SGCB_temp      ;load with SGCB ptr                     ;D549
     add   di,VIO_FSRAMSem                                         ;D549,@T18

     push es                                                            ;B722219
     mov ax,common                                                      ;B722219
     mov es,ax                                                          ;B722219
     mov ax,ss:[bp]+6                                                   ;B722219
     xor ah,ah                                                          ;B722219
     mov es:RamSem_SGID, ax                                             ;B722219
     pop es                                                             ;B722219

     .repeat
       push fs                  ;newFG SG's fsRAMsem D549
       push di                  ;                                       ;@T18
;@T18  push wait_hi             ;
       push dword ptr -1        ;                                       ;@T18
       call DOSFSRAMSEMREQUEST  ;
     .until <ax ne ERROR_INTERRUPT>

     push es                                                            ;B722219
     mov ax,common                                                      ;B722219
     mov es,ax                                                          ;B722219
     mov es:RamSem_SGID, -1                                             ;B722219
     pop es                                                             ;B722219

     mov  ax,ds:currSG
     mov  fs:[di].fs_client,ax                                     ;D549,@T18
   .endif

   pop  si              ;restore registers                              ;@T18
   pop  di                                                              ;@T18
;  pop  fs                                                         ;D549,@T18
;  pop  es              ;                                               ;@T18
   pop  ds              ;
   pop  bp              ;restore BP
   ret  4               ;return and pop parameters
VIOSRFBLOCK endp

        SUBTTL VIOSRFUNBLOCK - SAVE/RESTORE/FREE UNBLOCKER
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: VIOSRFUNBLOCK                                      */
;/*                                                                     */
;/* DESCRIPTIVE NAME: Save/Restore UNBlock (from sess. mgr.)            */
;/*                                                                     */
;/* FUNCTION: The purpose of this function is to unblock all VIO calls  */
;/*           after a screen switch.                                    */
;/*                                                                     */
;/* NOTES: This function clears the screen group semaphores             */
;/*        requested during VIOSRFBLOCK. The session manager controls   */
;/*        which screen group semaphores are cleared. A screen group    */
;/*        number of -1 indicates to skip that clear.                   */
;/*                                                                     */
;/* ENTRY POINT: VIOSRFUNBLOCK                                          */
;/*     LINKAGE: FAR CALL (from session manager)                        */
;/*                                                                     */
;/*              PUSH    NewForeSG                                      */
;/*              PUSH    OldForeSG                                      */
;/*              Call    VIOSRFBLOCK                                    */
;/*                                                                     */
;/* INPUT: OldForeSG - Previous foreground screen group number          */
;/*        NewForeSG - Current foreground screen group                  */
;/*        ES:SI    -> Out going FG SGCB pointer                @T18    */
;/*        FS:DI    -> In comming SGCB pointer                  @T18    */
;/*                                                                     */
;/* EXIT-NORMAL: AX = NO_ERROR                                          */
;/*                                                                     */
;/* EXIT-ERROR: AX <> NO_ERROR                                          */
;/*                                                                     */
;/* EFFECTS: The contents of AX are destroyed.                          */
;/*          Also, if the screen group being brought to the foreground  */
;/*          is not the shell (1), then the following checks are made.  */
;/*          The dirty flag in the COMMON data segment is set under     */
;/*          the following conditions:                                  */
;/*             1. the new FG session has an AVS registered             */
;/*             2. the new FG session has a SAVREDRAWWAIT thread        */
;/*             3. the new FG session has a MODEWAIT thread             */
;/*             4. the new FG session is the REAL MODE box (SG=2)       */
;/*          This information is used by VIOREDRAWSIZE (for DCR 85).    */
;/*                                                                     */
;/* INTERNAL                                                            */
;/* REFERENCES: ?                                                       */
;/*   ROUTINES: ?                                                       */
;/*                                                                     */
;/* EXTERNAL                                                            */
;/* REFERENCES: ?                                                       */
;/*   ROUTINES: ?                                                       */
;/*********************** END OF SPECIFICATIONS *************************/

VIOSRFUNBLOCK proc far
   push bp              ;BP <-- stack frame
   mov  bp,sp           ;
   push ds              ;save registers
;  push es              ;                                               ;@T18
;  push fs                                                         ;D549,@T18
   push di              ;                                               ;@T18
   push si              ;                                               ;@T18

   mov  ax,instance     ;address data segments
   mov  ds,ax           ;
;  mov  ax,common       ;                                               ;@T18
;  mov  es,ax           ;                                               ;@T18

;  mov  ax,ss:[bp+6]            ;AX <-- Old foreground screen group     ;@T18

   .if <<word ptr ss:[bp]+6> ne -1>     ;Valid out going SGid?          ;@T18
;    xor  ah,ah                 ;ignore session type of SGid       ;D549,@T18

;    push    ds                 ;sel:off to SGCB address                ;D549
;    push    offset SGCB_temp   ;  (returned)                      ;D549;@T52
;    push    ax                 ;                                       ;D549
;    push    Look_up_SGID       ;                                       ;D549
;    call    DOSSMGETSGCB       ;                                       ;D549

;    .if  <nonzero ax>          ;error returned                         ;D549
;      call suicide                                                     ;D549
;    .endif                                                             ;D549

;    lfs  bx,ds:SGCB_temp       ;load with SGCB ptr                ;D549,@T18
;    push bx                    ;D549                                   ;@T18
     add  si,VIO_fsRAMsem       ;D549                                   ;@T18

     push es                    ;clear oldFG's fsRAMsem D549            ;@T18
     push si                    ;                                       ;@T18
     call DOSFSRAMSEMCLEAR      ;

     push es                                                            ;B722219
     mov ax, common                                                     ;B722219
     mov es, ax                                                         ;B722219
     mov ax, es:RamSem_SGID                                             ;B722219
     .if <ax eq ds:currSG>                                              ;B722219
        sub  eax,eax                                                    ;B722219
        push eax                                                        ;B722219
        call DOSSLEEP           ;give up the timeslice                  ;B722219
     .endif                                                             ;B722219
     pop es                                                             ;B722219

;    pop  bx                    ;D549                                   ;@T18
   .endif

   mov  ax,ss:[bp+8]            ;AX <-- New foreground screen group;D549,@T18

   .if <ax ne -1>                                                  ;D549,@T18
     cbw                        ;ignore session type of SGid       ;D549,@T18

;    push    ds                 ;sel:off to SGCB address           ;D549,@T18
;    push    offset SGCB_temp   ;  (returned)                 ;D549;@T52,@T18
;    push    cx                 ;                                  ;D549,@T18
;    push    Look_up_SGID       ;                                  ;D549,@T18
;    call    DOSSMGETSGCB       ;                                  ;D549,@T18

;    .if  <nonzero ax>          ;error returned                    ;D549,@T18
;      call suicide                                                ;D549,@T18
;    .endif                                                        ;D549,@T18

;    lfs  bx,ds:SGCB_temp       ;load with SGCB ptr                ;D549,@T18
     .if <ax ne 1>                                             ;@T2;D549,@T18

;@T18  .if <fs:[bx].VIO_SrwPID ne 0> or                             ;@A0;D549
       .if <<dword ptr fs:[di].VIO_SrwtID> ne 0> or            ;@A0;D549,@T18
;@T18  .if <fs:[bx].VIO_SmwPID ne 0> or                             ;@A0;D549
       .if <<dword ptr fs:[di].VIO_SmwtID> ne 0>            @T2;@A0;D549,@T18
         push  es                                                       ;@T18
         mov   ax,common                                                ;@T18
         mov   es,ax                                                    ;@T18
         inc   es:dirty         ;Mark PVB dirty                     ;@T2;@A0
         pop   es                                                       ;@T18
       .endif                                                           ;@T2
     .endif                                                             ;@A0

     add  di,VIO_fsRAMsem       ;BX <-- SGDATA[newFG].fsRAMsem offset   ;@T18

     push fs                    ;clear newFG's fsRAMsem D549
     push di                    ;                                       ;@T18
     call DOSFSRAMSEMCLEAR      ;

     push es                                                            ;B722219
     mov ax, common                                                     ;B722219
     mov es, ax                                                         ;B722219
     mov ax, es:RamSem_SGID                                             ;B722219
     .if <ax eq ds:currSG>                                              ;B722219
        sub  eax,eax                                                    ;B722219
        push eax                                                        ;B722219
        call DOSSLEEP           ;give up the timeslice                  ;B722219
     .endif                                                             ;B722219
     pop es                                                             ;B722219

   .endif

;  push ds:prtscsemhi   ;allow screen switching                         ;@T18
   push dword ptr ds:prtscsemlo                                         ;@T18
   call DOSSEMCLEAR     ;

   pop  si              ;restore registers and return                   ;@T18
   pop  di                                                              ;@T18
;  pop  fs                                                         ;D549,@T18
;  pop  es              ;                                               ;@T18
   pop  ds              ;
   pop  bp              ;
   ret  4               ;
VIOSRFUNBLOCK endp

CTEXT_TUNE4 ends                                                        ;MDLL
     end
