;       SCCSID = @(#)viosrf.asm 6.3 92/02/13
;# SCCSID = @(#)viosrf.asm      6.3 92/02/13
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        SUBTTL  VIOSAVE, VIORESTORE, VIOFREE
        TITLE   VIOSRF.ASM
;******************************************************************************
;*******   C H A N G E       H I S T O R Y   **********************************
;******************************************************************************
;$Z8= reset Ctrl-NumLock status in VIOFREE (PTM P4555)
;     05-01-87
;$Z9= synchronize VIOFREE calls
;     04-27-87
;%A0= Use FS RAM sems instead of system sems
;     07-30-87
;P3374= VIOFREE: get SGID off of stack, not info seg
;       08-15-88
;P3425= VIOFREE: when pointing DI to fsRAMsem, use fsRAMsem instead of fsRAMoff
;       08-22-88
;P3528= VIOFREE: when clearing FSRAM sem, get SGID off stack, not ds:fsRAMoff
;       08-30-88
;P3839= initCP called on SG's first VIO call (set video CP to process CP)
;       11-14-88 (1.2 PTM 2502)
;@T2  = 04/03/89 TPL, Sizzle work, PTR B700???
;@T8  = 08/17/89 TPL, Compress registration mask for BVS, PTR B707524
;D549 = 11/07/89 WKB, DCR549 Changes
;@T52 = 01/15/90 TPL, DCR 704 work
;@T14 = 03/28/90 TPL, Remove duplication of functions
;@B722219 = 06/14/91 WKB, B722219 - Give up timeslice as appropriate
;@T80 = 02/06/92 TPL, Don't use the reserved register FS, B732479
;MDLL = 01/10/94 BJN, Page Tune segments for Merged DLL.

.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
.list
.386p                                                                   ;D549

EXTRN   vioattach:NEAR  ;
EXTRN   DOSSLEEP:FAR                                                    ;B722219
EXTRN   DOSFSRAMSEMREQUEST:FAR                                          ;%A0I
EXTRN   DOSFSRAMSEMCLEAR:FAR                                            ;%A0I

public  VIOSAVE
public  VIORESTORE
public  VIOFREE

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 VIOSAVE - SAVE CURRENT PHYSICAL SCREEN STATE
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: VIOSAVE (not replaceable)                          */
;/*                                                                     */
;/* DESCRIPTIVE NAME: save the current screen group state               */
;/*                                                                     */
;/* FUNCTION: Saves the current foreground screen group.                */
;/*                                                                     */
;/* NOTES: This call will be failed if it is not made by the Screen     */
;/*        Switcher/Session Manager (valid only from shell PID)         */
;/*                                                                     */
;/* ENTRY POINT: VIOSAVE                                                */
;/*     LINKAGE: FAR CALL (external, valid from Screen Switcher only)   */
;/* INPUT: "SGID" - screen group which terminated (word stack parameter)*/
;/*        "MODE" - popup/nopopup mode save requested                   */
;/*                                                                     */
;/* EXIT-NORMAL: AX = NO_ERROR                                          */
;/* EXIT-ERROR: AX = ERROR_VIO_SMG_ONLY - valid from session mgr only   */
;/* EFFECTS: The contents of AX are destroyed.                          */
;/* INTERNAL                                                            */
;/* REFERENCES: currSG - current process's screen group (LDTINFO:8)     */
;/*             LDTINFO - local info segment selector                   */
;/*             GDTINFO - global info segment selector                  */
;/*             SGDATA["SGID"].MASKI - AKS function mask                */
;/*             SGDATA["SGID"].MODULE - AKS module name                 */
;/*             SGDATA["SGID"].ENTRY_PT - AKS entry procedure name      */
;/*   ROUTINES: None.                                                   */
;/* EXTERNAL                                                            */
;/* REFERENCES: None.                                                   */
;/*   ROUTINES: DOSGETINFOSEG - get local/global info seg selectors     */
;/*********************** END OF SPECIFICATIONS *************************/

VIOSAVE proc far
   xor   ax,ax          ;preset AX = NO_ERROR
   push  fc_save        ;function code for BVS
   push  0              ;DummyVIO IP (added by Don T)
   push  ds             ;save DS
   enter 10,0           ;setup BP and allocate 4 words local storage
   push  es             ;save registers
   push  gs             ;save FS                                        ;@T80
   pusha                ;

   mov  ax,instance             ;DS <-- instance data selector
   mov  ds,ax                   ;
   mov  ax,common               ;ES <-- common data selector
   mov  es,ax                   ;

   mov  ax,ds:currpid

   .if <ax eq es:SHELLPID> or   ;valid from Sess. Mgr. or               ;@T14
   .if <ax eq es:HETPID>        ;valid from Hard Error Process     ;DRT HET

     .if <<word ptr [bp].rout_savAX> eq NO_ERROR>
       popa
       pop   gs                                                         ;@T80
       pop   es
       leave
       mov  ax,ds:avs_bvs_bits                                          ;@T8
       call dword ptr ds:bvs_off;call Base Video Subsystem
       enter 10,0           ;setup BP and allocate 4 words local storage
       push  es             ;save registers
       push  gs             ;                                           ;@T80
       pusha                ;
     .endif

   .else
     mov   [bp].rout_savAX,ERROR_VIO_SMG_ONLY
   .endif

   popa
   pop   gs                                                             ;@T80
   pop   es
   leave
   pop   ds
   add   sp,4           ;remove dummy IP and function code
   ret   4              ;return and pop parameters
VIOSAVE endp
cseg ends                                                               ;MDLL

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

        SUBTTL VIORESTORE - RESTORE SCREEN GROUP'S PHYSICAL SCREEN STATE
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: VIORESTORE (not replaceable)                       */
;/*                                                                     */
;/* DESCRIPTIVE NAME: restore the current screen group state            */
;/*                                                                     */
;/* FUNCTION: Restore the current foreground screen group.              */
;/*                                                                     */
;/* NOTES: This call will be failed if it is not made by the Screen     */
;/*        Switcher/Session Manager (valid only from shell PID)         */
;/*                                                                     */
;/* ENTRY POINT: VIORESTORE                                             */
;/*     LINKAGE: FAR CALL (external, valid from Screen Switcher only)   */
;/* INPUT: "SGID" - screen group which terminated (word stack parameter)*/
;/*        "MODE" - popup/nopopup mode restore requested                */
;/*                                                                     */
;/* EXIT-NORMAL: AX = NO_ERROR                                          */
;/* EXIT-ERROR: AX = ERROR_VIO_SMG_ONLY - valid from session mgr only   */
;/* EFFECTS: The contents of AX are destroyed.                          */
;/* INTERNAL                                                            */
;/* REFERENCES: currSG - current process's screen group (LDTINFO:8)     */
;/*             LDTINFO - local info segment selector                   */
;/*   ROUTINES: None.                                                   */
;/* EXTERNAL                                                            */
;/* REFERENCES: None.                                                   */
;/*   ROUTINES: DOSGETINFOSEG - get local/global info seg selectors     */
;/*********************** END OF SPECIFICATIONS *************************/

VIORESTORE proc far
   xor   ax,ax          ;preset AX = NO_ERROR
   push  fc_restore     ;function code for BVS
   push  0              ;DummyVIO IP (added by Don T)
   push  ds             ;save DS
   enter 10,0           ;setup BP and allocate 4 words local storage
   push  es             ;save registers
   push  gs             ;save FS                                        ;@T80
   pusha                ;

   mov   ax,instance    ;DS <-- instance data selector
   mov   ds,ax          ;
   mov   ax,common      ;ES <-- common data selector
   mov   es,ax          ;

   mov   ax,ds:currpid

   .if <ax eq es:SHELLPID> or   ;valid from Sess. Mgr. or               ;@T14
   .if <ax eq es:HETPID>        ;valid from Hard Error Process     ;DRT HET

     .if <<word ptr [bp].rout_savAX> eq NO_ERROR>
       popa
       pop   gs                                                         ;@T80
       pop   es
       leave
       mov   ax,ds:avs_bvs_bits                                         ;@T8
       call  dword ptr ds:bvs_off
       enter 10,0
       push  es
       push  gs                                                         ;@T80
       pusha
     .endif

   .else
     mov   [bp].rout_savAX,ERROR_VIO_SMG_ONLY
   .endif

   popa
   pop   gs                                                             ;@T80
   pop   es
   leave
   pop   ds
   add   sp,4
   ret   4              ;return and pop parameters
VIORESTORE endp

CTEXT_TUNE5 ends                                                        ;MDLL


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

        SUBTTL VIOFREE - FREE SCREEN GROUP DATA
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: VIOFREE (not replaceable)                          */
;/*                                                                     */
;/* DESCRIPTIVE NAME: free screen group data                            */
;/*                                                                     */
;/* FUNCTION: Resets the SGDATA entry specified by the screen group     */
;/*           passed on the stack and frees all data associated with    */
;/*           that SGDATA entry.                                        */
;/*                                                                     */
;/* NOTES: This call will be failed if it is not made by the Screen     */
;/*        Switcher/Session Manager (valid only from screen group 1)    */
;/*                                                                     */
;/* ENTRY POINT: VIOFREE                                                */
;/*     LINKAGE: FAR CALL (external, valid from Screen Switcher only)   */
;/* INPUT: "SGID" - screen group which terminated (word stack parameter)*/
;/*                                                                     */
;/* EXIT-NORMAL: AX = NO_ERROR                                          */
;/* EXIT-ERROR: AX = ERROR_VIO_SMG_ONLY - valid from session mgr only   */
;/* EFFECTS: The contents of AX are destroyed.                          */
;/* INTERNAL                                                            */
;/* REFERENCES: currSG - current process's screen group (LDTINFO:8)     */
;/*             LDTINFO - local info segment selector                   */
;/*             GDTINFO - global info segment selector                  */
;/*             SGDATA["SGID"].MASKI - AKS function mask                */
;/*             SGDATA["SGID"].MODULE - AKS module name                 */
;/*             SGDATA["SGID"].ENTRY_PT - AKS entry procedure name      */
;/*   ROUTINES: None.                                                   */
;/* EXTERNAL                                                            */
;/* REFERENCES: None.                                                   */
;/*   ROUTINES: DOSGETINFOSEG - get local/global info seg selectors     */
;/*********************** END OF SPECIFICATIONS *************************/

VIOFREE proc far
   xor   ax,ax          ;preset AX = NO_ERROR
   push  fc_free        ;function code for BVS
   push  0              ;DummyVIO IP (added by Don T)
   push  ds             ;save DS
   enter 10,0           ;setup BP and allocate 4 words local storage
   push  es             ;save registers
   push  gs                                                             ;@T80
   pusha                ;

   mov   ax,instance    ;DS <-- instance data selector
   mov   ds,ax          ;
   mov   ax,common      ;ES <-- common data selector
   mov   es,ax          ;

   lgs   bx,ds:SGCB                                                     ;@T80
   mov  ax,word ptr ds:SGCB         ;save original SGCB                 ;D549
   mov  word ptr ds:SGCB_temp,ax    ;save original SGCB                 ;D549
   mov  ax,word ptr ds:SGCB+2                                           ;D549
   mov  word ptr ds:SGCB_temp+2,ax                                      ;D549
   mov   ax,ds:currpid

   .if <ax eq es:SHELLPID> or   ;valid from Sess. Mgr. or               ;@T14
   .if <ax eq es:HETPID> NEAR   ;valid from Hard Error Process
     mov  ax,[bp].free_SG       ;parm specifying SG to be freed
     xor  ah,ah                 ;zero out proc type                     ;D549

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

     lgs  bx,ds:SGCB                                                    ;@T80

     add  bx,VIO_fsRAMsem       ;BX <- passed SG's fsRAMsem ;P3425;P3374;D549

     .repeat
       push  gs                 ;request [bp].free_SG's FS RAM sem      ;@T80
       push  bx                 ;                                       ;P3374
       push  wait_hi            ;
       push  wait_lo            ;
       call  DOSFSRAMSEMREQUEST ;
     .until <ax ne ERROR_INTERRUPT>

     mov  bx,word ptr ds:SGCB   ;BX <- SGCB offset refresh              ;D549

     .if <gs:[bx].VIO_shieldPID eq 0> ; Full screen session             ;@T80
       popa
       pop   gs                                                         ;@T80
       pop   es
       leave
       mov   ax,ds:avs_bvs_bits                                         ;@T8
       call  dword ptr ds:bvs_off ;call subsystem
       enter 10,0
       push  es
       push  gs                                                         ;@T80
       pusha
     .else
       mov   gs:[bx].VIO_shieldPID,0;clear current SHIELDINIT owner     ;@T80
     .endif                     ;                                       CDB

     mov  ax,common                                                     ;P3528
     mov  es,ax                                                         ;P3528

     mov  ax,[bp].free_SG       ;parm specifying SG to be freed         ;P3528

     lgs  bx,ds:SGCB                                                    ;@T80

     add  bx,VIO_fsRAMsem       ;BX <- [bp].free_SG's fsRAMsem          ;D549
     push  gs                   ;clear [bp].free_SG's FS RAM sem        ;@T80
     push  bx                   ;                                       ;P3528
     call  DOSFSRAMSEMCLEAR     ;

     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

   .else
     mov   [bp].rout_savAX,ERROR_VIO_SMG_ONLY
   .endif

   mov  ax,word ptr ds:SGCB_temp      ;restore original SGCB            ;D549
   mov  word ptr ds:SGCB,ax                                             ;D549
   mov  ax,word ptr ds:SGCB_temp+2                                      ;D549
   mov  word ptr ds:SGCB+2,ax                                           ;D549

   popa
   pop   gs                                                             ;@T80
   pop   es
   leave
   pop   ds             ;Restore caller's DS (CDB) ********
   add   sp,4           ;Remove function and dummy (CDB) **
   ret   2              ; '2' added by Don T
VIOFREE endp

cseg ends
     end
