;SCCSID = @(#)bvsinit.asm       6.11 92/02/13
        PAGE    58,132
        TITLE   BvsInit.Asm -- Base Video Subsystem Initialization
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SOURCE FILE NAME:   BvsInit.Asm                                     */
;/*                                                                     */
;/* DESCRIPTIVE NAME:   BVS Process and Session Initialization Routines */
;/*                                                                     */
;/* COPYRIGHT:  na                                                      */
;/*                                                                     */
;/* STATUS:     na                                                      */
;/*                                                                     */
;/* NOTES:      Executes on level 3                                     */
;/*                                                                     */
;/*    DEPENDENCIES:    None                                            */
;/*                                                                     */
;/*    RESTRICTIONS:    None                                            */
;/*                                                                     */
;/*    PATCH LABEL:     na                                              */
;/*                                                                     */
;/* ENTRY POINTS: BvsInit                                               */
;/*                                                                     */
;/* EXTERNAL REFERENCES: DOSALLOCSHRSEG, DOSDEVIOCTL, DOSALLOCHUGE,     */
;/*     DOSGETSEG, DOSGETSHRSEG, DOSREALLOCHUGE, finis                  */
;/************************ END OF SPECIFICATIONS ************************/

INCL_WINPROGRAMLIST  equ   1    ;needed for pmshl.inc defines      ;@D549
INCL_DOSSEMAPHORES  EQU 1                                          ;142736
SESMGR               equ   1    ;needed for pmshl.inc defines      ;@D549

        .xlist
        INCLUDE bvscb.inc               ;BVS Data Structures
        INCLUDE bvsparms.inc            ;BVS Parameter Equates
        INCLUDE bvsextrn.inc            ;BVS external definitions       ;@T52
        INCLUDE bsedos16.inc                                       ;142736
        INCLUDE error.inc               ;Error Equates ;@S23
        INCLUDE error2.inc              ;System error equates
        INCLUDE infoseg.inc             ;Global/Local Info Segments
        INCLUDE struc.inc               ;Structured Macros
        INCLUDE pmshl.inc               ;PM Shell equates for PROG_PM/WIN  ;@D549
        .list

        .386p                   ;@D549

        EXTRN   DOSFSRAMSEMREQUEST:FAR  ;Dos Request Ram Semaphore    ; 142736
        EXTRN   DOSFSRAMSEMCLEAR:FAR    ;Dos Clear Ram Semaphore      ; 142736
        EXTRN   DOSSLEEP:FAR            ;Dos Allocate Shared Segment  ; 142736
        EXTRN   DOSALLOCSHRSEG:FAR      ;Dos Allocate Shared Segment
        EXTRN   DOSDEVIOCTL:FAR         ;Dos Generic I/O Control routine
        EXTRN   DOSGETSEG:FAR           ;Dos Get Segment Selector
        EXTRN   DOSGETSHRSEG:FAR        ;Dos Get Shared Segment

        EXTRN   DOSALLOCHUGE:FAR        ;Dos Allocate Huge Segment
        EXTRN   DOSREALLOCHUGE:FAR      ;Dos Re-Allocate Huge Segment
        EXTRN   DOSREALLOCSEG:FAR       ;Dos Re-Allocate Segment
        EXTRN   DOSSIZESEG:FAR          ;Dos Read Segment Size ;@S30
        EXTRN   DOSSMGETMEM:FAR         ;Dos SesMgr Get Memory ;@D549
        EXTRN   DOSSMFREEMEM:FAR        ;Dos SesMgr Free Memory ;@D549  ;@T

        extrn   AllVDH:NEAR             ;Common VDH call routine in BvsMain
        extrn   UpdateLVBSize:NEAR      ;Sync hardware and resize the LVB
        extrn   AllSetVarInfo:NEAR      ;Common routine for SetVarInfo ;@S43
        extrn   finis:NEAR              ;Error exit in BVSMAIN

        extrn   GetDBCSInfo:NEAR        ;Update DBCS display information ;@P1
        extrn   GetScrollRect:NEAR      ;Update DBCS display information ;@P1
        extrn   ClearScreen:NEAR        ;Clear the screen                ;@P1
        extrn   ILASTVDH:WORD           ;Config # of last VDH installed  ;@P1
        extrn   BVSGETVIDEOCALLTABLES:FAR ;Entry points in BvsLDrvr.C   ;@T48
        extrn   WndwConfig:WORD         ;VIO windowable config data ;@S33
        extrn   ArraySeg:WORD           ;Common array selector declared ;@T18
                                        ;  in OS2CHAR.ASM               ;@T18
        extrn   bvsi_sg1_bvssel:WORD    ;BVSCB backup for SG 1          ;@T71

BVSGSEG SEGMENT WORD PUBLIC 'FAR_DATA' USE16    ;@D549                  ;@T52
sersem  DOSFSRSEM       <14,0,0,0,0,0>                                  ;142736
BVSGSEG ENDS

BVSISEG SEGMENT WORD PUBLIC 'DATA' USE16        ;@D549                  ;@T52
BVSISEG ENDS

CTEXT_TUNE5 SEGMENT BYTE PUBLIC 'CODE' USE16                            ;MDLL;@D549
        ASSUME  CS:CTEXT_TUNE5,DS:NOTHING,ES:NOTHING                    ;MDLL

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsInit                                           */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Process Initialization      */
;/*                                                                     */
;/* FUNCTION:  Initializes BVS and the BVSCB                            */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsInit                                               */
;/*   LINKAGE:  Call BvsInit from BvsMain                               */
;/*                                                                     */
;/* INPUT:  DS = PPBVSCB, ES = Common Data Segment                      */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*                                                                     */
;/* EXIT-ERROR:  None                                                   */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  PPBVSCB, BVSCBsg, LVBsg                       */
;/*   ROUTINES:  BvsPMIni                                               */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES:  DOSDEVIOCTL                                            */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsInit
;    If the Per Process BVSCB has not been initialized
;      Get current session number of this process
;      If BVS is not calling itself (this is outermost call by this process)
;        Preset session number to current session
;        If session is shell or hard error AND not ShellInit pid
;          If Save/Restore/Free
;            Use session number of session to be Saved/Restored/Freed
;          Elseif PrtSc/PrtScToggle
;            Use session number of foreground session
;          Endif
;          If session number not zero (not the hard error session)
;            Get CB selectors used by selected session from master table
;          Else (hard error session)
;            If a non-recursive Save/Restore/Free/PrtSc/PrtScToggle
;              Set flag to avoid recursion
;              Mark all CBs as uninitialized to force allocation of temp CBs
;            Endif
;          Endif
;        Endif
;      Endif
;      If session is changing and this is not the SesMgr (this is a popup transition)
;        Toggle the popup flag
;        If starting a popup
;          Force allocation of new CBs for the popup
;          Refresh the PVB selector to make it valid in the background
;        Else
;          Free the popup CBs
;          Restore the old CBs for the session
;      Endif
;      If this is a Windowable session
;          Call DosLoadVideoHandler to load/access the Windowed VDH
;      Else
;          For each VDH in the system
;              Call BvsLoadVideoHandler to get access to the VDH
;          Endif
;      Call BvsGetCallTables to init all the VDHs
;      Call GetBVSCB to access/allocate all the session control blocks
;    Endif
;    If the BVSCB is uninitialized
;        Call InitBVSCB to initialize the session
;    Endif
;End BvsInit

;Begin GetBVSCB
;    If master LVB selector already exists for this session
;        Call DosGetSeg to access the LVB
;        If failure
;            Return directly to VIO with ERROR_VIO_INTERNAL_RESOURCE
;        Endif
;    Else
;        Call DosAllocHuge for the LVB
;        If failure
;            Return directly to VIO with ERROR_VIO_INTERNAL_RESOURCE
;        Endif
;        Fill the LVB with blanks
;        Save the master LVB selector for this session
;    Endif
;
;    Call DOSALLOCSHRSEG to get the BVSCB and save its selector
;    If error
;        Call DOSGETSHRSEG and save the selector
;        If failure
;            Return directly to VIO with ERROR_VIO_INTERNAL_RESOURCE
;        Endif
;    Else
;        Mark the BVSCB as uninitialized
;    Endif
;End GetBVSCB

;Begin InitBVSCB
;    Initialize the default BVS and ANSI fields in the BVSCB
;    Set the background flag to reflect the state of the current process
;    Allocate the Environment buffer
;    Call InitEnvironment in VDH to initialize the Environment buffer
;    If this is the Shell pid
;        For the Hard Error, Real Mode, and Popup session
;            Call GetBVSCB to allocate the control blocks
;            Copy the Shell BVSCB to the new BVSCB
;        Endfor
;    Endif
;End InitBVSCB

BvsInit PROC    NEAR                    ;On entry:  DS = Instance, ES = Global
        PUBLIC  BvsInit

;----------------------------------------------------------------------
;Get current session number of this process
;If BVS is not calling itself (this is outermost call by this process)
;  Preset session number to current session
;  If session is shell or hard error AND not ShellInit pid
;    If Save/Restore/Free
;      Use session number of session to be Saved/Restored/Freed
;    Elseif PrtSc/PrtScToggle
;      Use session number of foreground session
;    Endif
;    --See next block comment--
;  Endif
;Endif
;----------------------------------------------------------------------

        .if     <ds:bvsi_level eq bx> near ;Non-Recursive call          ;@T52
            push    es
            mov     es,ds:bvsi_ldtsel                                   ;@T52
            mov     si,es:[bx].LIS_CurScrnGrp                           ;@T14fff
            mov     dl,es:[bx].LIS_ProcType                             ;@T14fff
            mov     di,ds:bvsi_sgnum                                    ;@T14fff
            .if     <di ne si> and                                      ;@T14fff
            .if     <di ne 3> and                                       ;@T14fff
            .if     <si ne 3>                                           ;@T14fff
                mov     ds:bvsi_sgnum,si
            .endif
            pop     es

            mov     ax,[bp].p_viofunc ;Get function code in AX          ;@T71
            cmp     al,vf_AssociateDC                                   ;@T71
            .if     <ae>                                                ;@T71
                mov     ds:bvsi_sgnum,si                                ;@T71
            .elseif <si be 1> and near  ;ScrnGrp 0/1 to fix hard errors ;@T71
            .if     <dl ne LIS_PT_DETACHED> and near                    ;@T14fff
            .if     <es:bvsg_initpid ne bx> near                        ;@T52
                .if     <al ae vf_Save>   ;Save/Restore/Free etc.
                    mov     si,[bp].sr_sgnum ;Get sg for Save/Restore
                    .if     <al eq vf_Free>
                        mov     si,[bp].p_viohandle ;Get screen group for Free
                    .elseif <<byte ptr [bp].sr_sgnum+1> eq PROG_VDM>;FSMVDM @C39
                        mov     si,3*4      ;offset to Popup selector list ;@C39
                        lgs     si,es:bvsg_seltable[si]               ;@C39,@T80
                        mov     gs:[si].selt_flags,0   ;set init flag to 0 ;@T80
                        mov     si,3        ;set instance to Popup SG      ;@C39
                    .endif
                    and     si,0FFh ;zero out hi byte for type          ;@D549
                .else
                    .if     <al eq vf_PrtSc> or ;PrtSc or
                    .if     <al eq vf_TogglePrtSc> ;CtrlPrtSc Toggle
                        mov     es,ds:bvsi_gdtsel                       ;@T52
                        mov     al,es:[bx].SIS_CurScrnGrp ;FG Screen Group
                        mov     si,ax
                    .endif
                .endif

;----------------------------------------------------------------------
;If session number not zero (not the hard error session)
;  Get the CB selectors used by the selected session from the master table
;Else (hard error session)
;  If a non-recursive Save/Restore/Free/PrtSc/PrtScToggle
;    Set flag to avoid recursion
;    Mark all CBs as uninitialized to force allocation of temporary CBs
;  Endif
;Endif
;----------------------------------------------------------------------

                push    BVSGSEG         ;D261
                pop     es              ;D261

                .if     <ds:bvsi_sgnum ne bx>                           ;@T52
                    mov     ds:bvsi_sgnum,si ;Force new session info    ;@T52
                    shl     si,2        ;shift index by 4 to align Dword;@D549
                    .if     <es:bvsg_seltable[si] eq 0>           ;@D549;@T52
                        xor     ax,ax                                   ;@D549
                    .else                                               ;@D549
                        lgs     di,es:bvsg_seltable[si]       ;@T52,@T74,@T80
                        mov     ax,gs:[di].selt_bvscb        ;@D549,@T74,@T80
                    .endif                                              ;@D549
                    .if     <[bp].p_viofunc e vf_Free>  ;@B25
                        .if     <zero ax> or            ;@B25
                        verw    ax                      ;@B25
                        .if     <nz>                    ;@B25
                            mov     eax,es:bvsg_seltable[si]            ;@T74f
                            or      eax,eax                             ;@T74f
                            .if     <nz>                ;sellist there? ;@T74f
                                push    eax                             ;@T74f
                                call    DOSSMFREEMEM    ;free sellist   ;@T74
                                sub     eax,eax         ;@B25           ;@T74
                                mov     dword ptr es:bvsg_seltable[si],eax ;@T74
                            .endif                                      ;@T74f
                            jmp     finis               ;@B25
                        .endif                          ;@B25
                    .endif                              ;@B25

                    verr    ax             ;; verify BVSCB             ;;76155
                    .if <nz>               ;; (someone didn't clean up);;76155
                        xor     ax,ax      ;; if not readable zero     ;;76155
                    .endif                 ;; for re-init.             ;;76155

                    mov     ds:bvsi_bvssel,ax ;Get saved BVSCB selector ;@T52

                    push    ds          ;@S10
                    pop     es          ;@S10
                    mov     ds,ax       ;DS = BVSCB, ES = Instance ;@S10

                    Call    InitConfig  ;Update the instance data ;@S10

                    push    es          ;@S10
                    pop     ds          ;Restore DS = Instance ;@S10
                .else
                    .if     <es:bvsg_sg0flag eq bx> and ;Non-recursive  ;@T52
                    mov     ax,[bp].p_viofunc
                    .if     <al ae vf_Save> or
                    .if     <al eq vf_PrtSc> or
                    .if     <al eq vf_TogglePrtsc> ;SG0 for other SG
                        mov     es:bvsg_sg0flag,ax                      ;@T52
                        mov     ax,ds:bvsi_bvssel                       ;@T52
                        mov     es:bvsg_sg0bvssel,ax                    ;@T52
                        mov     ax,ds:bvsi_envsel                       ;@T52
                        mov     es:bvsg_sg0envsel,ax                    ;@T52
                        mov     ax,ds:bvsi_lvbsel                       ;@T52
                        mov     es:bvsg_sg0lvbsel,ax                    ;@T52
                        mov     ds:bvsi_sgnum,si  ;Force other SG       ;@T52

                        mov     ds:bvsi_bvssel,bx ;Force alloc of BVSCB ;@T52
                        mov     ds:bvsi_envsel,bx ;Force alloc of ENVB  ;@T52
                        mov     ds:bvsi_lvbsel,bx ;Force alloc of LVB   ;@T52
                    .endif
                .endif
            .endif
        .endif

;----------------------------------------------------------------------
;If session is changing and this is not the SesMgr (this is a popup transition)
;  Toggle the popup flag
;  If starting a popup
;    Force allocation of new CBs for the popup
;  Else
;    Free the popup CBs
;    Restore the old CBs for the session
;Endif
;----------------------------------------------------------------------

        mov     es,ds:bvsi_ldtsel       ;Address local info seg         ;@T52
        mov     ax,es:[bx].LIS_CurScrnGrp ;Get current SG

        .if     <ax ne ds:bvsi_sgnum> NEAR ;Current SG <> ppbvs SG      ;@T52
          .if     <ax a 1>  or NEAR        ;and NOT sess mgr SG         ;@T14fff
          .if     <es:[bx].LIS_ProcType e LIS_PT_DETACHED> NEAR         ;@T14fff

            xor     ds:bvsi_flags,bvsi_f_popup                          ;@T52
            test    ds:bvsi_flags,bvsi_f_popup                          ;@T52
            .if     <nz> NEAR           ;First call inside popup        ;@T14ff

                mov     dx,ds:bvsi_sgnum ;Save original SG              ;@T52
                mov     ds:bvsi_pop_sgnum,dx                            ;@T52
                mov     ds:bvsi_sgnum,ax ;Place popup SG in ppbvs seg   ;@T52
                mov     ax,ds:bvsi_bvssel       ;Save the current       ;@T18
                mov     ds:bvsi_pop_bvssel,ax   ;  BVSCB selector       ;@T18

                push    BVSGSEG         ;                          ;@T48,@T14
                pop     es              ;                          ;@T48,@T14

                .if     <dx a es:bvsg_maxbase> and ;Windowable or  ;@T48;@T52
                test    ds:bvsi_pop_vdh,fs_vdh_loaded ; AVIO?      ;@T48;@T52
                .if     <z>             ;Loading necessary?             ;@T48
                    push    es          ;Load the fullscreen            ;@T48
                    push    offset bvsg_calltables ; VDH(s) for VIO;@T48;@T52
                    push    bx          ;  Windowable or                ;@T48
                    push    bx          ;  AVIO process                 ;@T48
                    push    bx          ;                               ;@T48
                    push    bx          ;                               ;@T48
                    Call    BVSGETVIDEOCALLTABLES                       ;@T48
                    .if     <nonzero ax>                                ;@T48
                        jmp     finis   ;                               ;@T48
                    .endif              ;                               ;@T48
                    or      ds:bvsi_pop_vdh,fs_vdh_loaded ;@T48         ;@T52
                .endif                  ;                       ;@T48

;----------------------------------------------------------------------
;@C39 Force re-init of Popup BVSCB here instead of in BVSSAVE
;     needed for MVDM regular popups
;----------------------------------------------------------------------
;@T14ff         xor     es:bvsg_flags,bvsg_f_tpopup  ;toggle tpopup bit    ;@C39
                test    es:bvsg_flags,bvsg_f_tpopup  ;if set, then it's    ;@C39
                .if     <z>                          ;NOT transparent pop  ;@C39
;@T14ff             xor     es:bvsg_flags,bvsg_f_tpopup  ;toggle bit off   ;@C39
                    lgs     di,es:bvsg_seltable[3*4] ;dword index to SG 3  ;@T80
                    mov     ax,gs:[di].selt_bvscb    ;Popup BVSCB selector ;@T80
                    verw    ax                                             ;@C39
                    .if     <nz>                                           ;@C39
                        mov     ds:bvsi_bvssel,bx    ;Force getseg of BVSCB;@C39
                        mov     si,ds:bvsi_sgnum                           ;@C39
                        Call    GetBVSCB                                   ;@C39
                        mov     ax,gs:[di].selt_bvscb ;Popup BVSCB sel     ;@T80
                    .endif                                                 ;@C39
                    .if     <BIT es:bvsg_flags nand bvsg_f_tpopup>         ;@T14fff
                        mov     gs,ax                                      ;@T80
                        mov     gs:[bx].bvs_bvssize,bx  ;Re-init BVSCB     ;@T80
                        or      es:bvsg_flags,bvsg_f_popup ;no re-init  ;@T14ff
                    .endif                                              ;@T14ff
                .endif                                                     ;@C39

                mov     ax,ds:bvsi_pop_popsel   ;Use popup BVSCB        ;@T18
                mov     ds:bvsi_bvssel,ax       ;  selector             ;@T18
            .else                       ;First call after a popup

                mov     si,ds:bvsi_pop_sgnum                            ;@T52
                mov     ds:bvsi_sgnum,si        ;Restore Session number ;@T52
                mov     ax,ds:bvsi_pop_bvssel   ;Restore orginal        ;@T18
                mov     ds:bvsi_bvssel,ax       ;  BVSCB selector       ;@T18

                mov     al,es:[bx].LIS_ProcType ;Get Process Type       ;@T14ff
                mov     si,es:[bx].LIS_CurScrnGrp                       ;@T14fff
                push    BVSGSEG         ;Clear all popup flags          ;@T14ff
                pop     es              ;                               ;@T14ff
                and     es:bvsg_flags, NOT (bvsg_f_popup+bvsg_f_tpopup) ;@T14ff

                .if     <al e LIS_PT_DETACHED>  ;Detached process?      ;@T14ff
                                                ;Borrow session number  ;@T14fff
                    mov     ds:bvsi_sgnum,si    ; from the FG session   ;@T14fff
                    mov     ax, ERROR_VIO_DETACHED                      ;@T14f
                    jmp     finis                                       ;@T14f
                .endif                                                  ;@T14f
            .endif

            mov     ds:bvsi_envsel,bx   ;Force alloc/restore of ENVB    ;@T52
            mov     ds:bvsi_lvbsel,bx   ;Force alloc/restore of LVB     ;@T52
          .endif                                                        ;@T14fff
        .endif

;----------------------------------------------------------------------
;Allocate and initialize the CBs for the selected session
;----------------------------------------------------------------------
reit:                                                   ;142736
        mov     ax,BVSGSEG                              ;142736
        push    ax                                      ;142736
        mov     ax,offset sersem                        ;142736
        push    ax                                      ;142736
        xor     ax,ax                                   ;142736
        push    ax                                      ;142736
        mov     ax,150H                                 ;142736
        push    ax                                      ;142736
        call    DOSFSRAMSEMREQUEST                      ;142736
        cmp     ax,0000                                 ;142736
        jne     reit                                    ;142736

        .if     <ds:bvsi_envsel eq bx>                             ;@T52;@T18
            mov     si,ds:bvsi_sgnum                                    ;@T52
            Call    GetBVSCB            ;Error --> finis
        .endif
        inc     ds:bvsi_level           ;Increase level of recursion    ;@T52

        Call    InitConfig              ;Ensure correct selectors ;@S10

        mov     ax,BVSGSEG                              ;142736
        push    ax                                      ;142736
        mov     ax,offset sersem                        ;142736
        push    ax                                      ;142736
        call    DOSFSRAMSEMCLEAR                        ;142736

        sub     ax,ax

        RET
BvsInit ENDP

;----------------------------------------------------------------------
; Get the BVSCB, as well as the Environment Block and Logical Video Buffer
;       On entry: SI = Session Number for which to allocate control blocks
;----------------------------------------------------------------------

GetBVSCB PROC   NEAR
        public  GetBVSCB

        push    ds
        push    si
        push    es                      ;D261
        push    di
        push    dx                                                      ;@T18

        mov     dx,si                   ;Save session number in DX      ;@T18
        mov     ax,si                   ;Get session number for name generation

        push    BVSGSEG
        pop     ds
        mov     si,offset bvsg_bvscbname ;Get ptr to BVSCB name struc   ;@T52

        push    ss
        pop     es
        lea     di,[bp].vp_parm1        ;Get ptr to name for alloc
        push    di

        mov     cx,offset bvsg_mouddname                                ;@T52
        sub     cx,offset bvsg_bvscbname                                ;@T52
        rep     movsb                   ;Move name to work area
        sub     di,3                    ;Point to Session number in name

        sub     ah,ah
        ror     ax,4                    ;Convert ahAL to AhaL (LOW in AH)
        ror     ah,4                    ;Convert AhaL to aHaL (HIGH in AL)
        or      ax,3030h                ;Convert 0-F to 30-3F

        cmp     ah,3ah
        .if     ae
            add     ah,07h              ;Convert 3A-3F to 41-46
        .endif

        cmp     al,3ah
        .if     ae
            add     al,07h              ;Convert 3A-3F to 41-46
        .endif

        stosw                           ;Put the session number in the name
        pop     di                      ;Restore name pointer

        push    BVSISEG
        pop     es                      ;DS = Global, ES = Instance

        .if     <es:bvsi_bvssel e bx>   ;Attempt to allocate BVSCB?     ;@T18

            push    ds:bvsg_bvscbsize   ;Set computed length of BVSCB   ;@T52
            push    ss
            push    di                  ;Ptr to BVSCB name
            push    es
            push    offset bvsi_bvssel  ;Ptr to BVSCB selector field    ;@T52
            Call    DOSALLOCSHRSEG      ;Allocate BVSsg

            .if     <nonzero ax>        ;Allocate failed, Get old selector
                push    ss
                push    di              ;Ptr to BVSCB name
                push    es
                push    offset bvsi_bvssel ;Ptr to BVSCB selector field ;@T52
                Call    DOSGETSHRSEG       ;BVSsg selector/offset
                .if     <nonzero ax>
                    mov     es:bvsi_level,bx                            ;@T52
                    mov     ax,ERROR_VIO_INTERNAL_RESOURCE
                    jmp     finis               ;Return with error code
                .endif

            .else                               ;Allocation succeeded
                push    es                      ;D261;@S10
                mov     es,es:bvsi_bvssel       ;@S10                   ;@T52
                sub     di,di                   ;@S10
                mov     cx,ds:bvsg_bvscbsize    ;@S10                   ;@T52
                rep     stosb                   ;Clear BVSCB/Force re-init ;@S10
                mov     es:[bx].bvs_curconfig,1 ;Preset first configuration;@S10
                pop     es                      ;D261;@S10
            .endif                                                      ;@T18
        .endif

;@T18   pop     di                      ;@S10   restoring Screen group #
        mov     es,es:bvsi_bvssel                            ;@S10;@D549;@T52
        mov     si,dx                   ;Put session # into SI    ;@D549,@T18
        shl     si,2        ;shift index by 4 to align Dword            ;@D549
        .if     <ds:bvsg_seltable[si] eq 0>                       ;@D549;@T52
            push    ds                  ;address of sellist ptr         ;@D549
            lea     ax,ds:bvsg_seltable[si]                       ;@D549;@T52
            push    ax                                                  ;@D549
            push    ds:bvsg_seltablesz  ;size of sellist          ;@D549;@T52
            call    DOSSMGETMEM         ;get memory from SesMgr         ;@D549
            .if     <nonzero ax>                                        ;@D549
                mov     ax,BVSISEG                                      ;@T18
                mov     ds,ax                                           ;@T18
                mov     ds:bvsi_level,bx                     ;@D549,@T52,@T18
                mov     ax,ERROR_VIO_INTERNAL_RESOURCE                  ;@D549
                jmp     finis           ;Return with error code         ;@D549
            .endif                                                      ;@D549

            lgs     si,ds:bvsg_seltable[si]     ;sellist ptr       ;@T52,@T80
            mov     gs:[si].selt_bvscb,es       ;Save master copy ;@D549,@T80
        .else                                                           ;@D549
            mov     ax,BVSISEG                                          ;@T18
            mov     gs,ax                                          ;@T18,@T80
            mov     ax,word ptr ds:bvsg_seltable[si]+2                  ;@T18
            .if     <gs:ArraySeg ne ax>         ;Have access to SGCB?   ;@T80
              push    ax                        ;            ;@D549;@T52;@T18
              call    DOSGETSEG                 ;get access to sellist  ;@D549
            .endif                                                      ;@T18
            lgs     si,ds:bvsg_seltable[si]     ;sellist ptr       ;@T52,@T80
        .endif                          ;@S10

;----------------------------------------------------------------------
; Loop through all configurations and pre-allocate all ENVBs and LVBs
;----------------------------------------------------------------------

        push    es:[bx].bvs_curconfig   ;Save current configuration #   @S10
        mov     cx,ds:ILASTVDH          ;Number of configurations ;@S10
        mov     es:[bx].bvs_curconfig,1 ;Use first configuration ;@S10
        .if     <dx a ds:bvsg_maxbase>  ;@S10                      ;@T52,@T18
            mov     cx,1                ;@S10
            mov     es:[bx].bvs_curconfig,bx ;Use VDHWNDW ;@S10
        .endif                          ;@S10

        push    si                      ;Save offset to selector entry ;@TL1
;@T18   mov     ax,di                   ;Save SG number ;@TL1
        lea     di,gs:[si].selt_envb    ;Offset of 1st ENVB selector ;@D549,@T80
        push    dx                      ;Save SG number                 ;@T18
        .repeat                         ;@S10
            push    cx                  ;@S10
            push    di                  ;@S10;@S23

            lea     ax,[bp].vp_parm1    ;@S10;@S23
            mov     [bp].vp_offset,ax   ;@S10;@S23
            mov     [bp].vp_selector,ss ;Set the config data pointer ;@S10;@S23
            mov     [bp].vp_parm1,cf_fullsize+4 ;Get ENVB and LVB sizes ;@S10;@S23

            mov     di,fn_GetConfig     ;@S10;@S23
            mov     [bp].vp_flags,bx    ;@S10;@S23
            Call    AllVDH              ;@S10;@S23

            pop     di                  ;@S10;@S23

            mov     cx,gs:[di]          ;Get master ENVB selector ;@D549,@T80
            .if     ncxz
                push    ds              ;If the current process have    ;@T18
                push    BVSISEG         ;  gone through popup at least  ;@T18
                pop     ds              ;  once then it isn't necessary ;@T18
                .if     <ds:bvsi_pop_popsel e 0> ; to call DosGetSeg    ;@T18
                    push    cx                   ; again                ;@T18
                    Call    DOSGETSEG   ;Get selector for this process
                .endif                                                  ;@T18
                pop     ds                                              ;@T18
                .if     <zero ax> and   ;@S30

                push    cx              ;@S30
                push    es              ;@S30
                push    bvs_envsize     ;@S30
                Call    DOSSIZESEG      ;@S30
                .if     <zero ax> and   ;@S30

                mov     dx,word ptr es:[bx].bvs_envsize+2 ;@S30
                .if     <dx b <word ptr [bp+vp_parm1+cf_envsize+2]>> or ;@S30
                .if     <eq> and        ;@S30
                mov     dx,word ptr es:[bx].bvs_envsize ;@S30
                .if     <dx b <word ptr [bp+vp_parm1+cf_envsize]>> ;@S30

                    push    word ptr [bp+vp_parm1+cf_envsize+2] ;@S23
                    push    word ptr [bp+vp_parm1+cf_envsize] ;Push the ENVB size ;@S23
                    push    cx          ;@S23
                    Call    DOSREALLOCHUGE ;Increase the size of the ENVB ;@S23

                .endif                  ;@S30
                .if     <nonzero ax>    ;@S23
                    mov     ax,ERROR_VIO_INTERNAL_RESOURCE ;@S23
                    jmp     finis       ;End it all ;@S23
                .endif                  ;@S23
            .else
                mov     ax,word ptr [bp+vp_parm1+cf_envsize+2] ;@S10
                .if     <<word ptr [bp+vp_parm1+cf_envsize]> ne bx> ;@S10
                    inc     ax          ;@S10
                .endif                  ;@S10
                .if     <zero ax>       ;@S10
                    inc     ax          ;@S10
                .endif                  ;@S10

                push    word ptr [bp+vp_parm1+cf_envsize+2] ;@S10
                push    word ptr [bp+vp_parm1+cf_envsize] ;Push the ENVB size ;@S10
                push    gs              ;@S10;@D549,@T80
                push    di              ;Ptr to return selector ;@S10
                push    ax              ;Max number of selectors ;@S10
                push    2               ;Allow DOSGETSEG
                Call    DOSALLOCHUGE    ;Get a GETtable segment
                .if     <nonzero ax>
                    mov     ax,ERROR_VIO_INTERNAL_RESOURCE
                    jmp     finis       ;End it all
                .endif
            .endif
            add     di,2                ;@S10

            mov     cx,gs:[di]          ;Get master LVB selector ;@D549,@T80
            .if     ncxz
                push    ds              ;If the current process have    ;@T18
                push    BVSISEG         ;  gone through popup at least  ;@T18
                pop     ds              ;  once then it isn't necessary ;@T18
                .if     <ds:bvsi_pop_popsel e 0> ; to call DosGetSeg    ;@T18
                    push    cx                   ; again                ;@T18
                    Call    DOSGETSEG   ;Get selector for this process
                .endif                                                  ;@T18
                pop     ds                                              ;@T18
                .if     <nonzero ax>
                    mov     ax,ERROR_VIO_INTERNAL_RESOURCE
                    jmp     finis       ;End it all
                .endif

            .else                       ;LVB not yet allocated

                mov     ax,word ptr [bp+vp_parm1+cf_fullsize+2]         ;@S10
                mov     cx,word ptr [bp+vp_parm1+cf_fullsize]
                push    bx              ;
                push    2               ;Push the default LVB length

                .if     <ncxz>          ;@S10 @TL3
                    inc     ax          ;@S10
                .endif                  ;@S10
                .if     <zero ax>       ;@S10
                    inc     ax          ;@S10
                .endif                  ;@S10

                push    gs              ;@S10;@D549,@T80
                push    di              ;Ptr to return selector ;@S10
                push    ax              ;Max number of selectors ;@S10
                push    2               ;Allow DOSGETSEG
                Call    DOSALLOCHUGE    ;Get a huge GETtable segment
                .if     <nonzero ax>
                    mov     ax,ERROR_VIO_INTERNAL_RESOURCE
                    jmp     finis       ;End it all
                .endif
            .endif
            add     di,2                ;@S10

            inc     es:[bx].bvs_curconfig ;@S10
            pop     cx                  ;@S10
            dec     cx                  ;@S10
        .until  <z> near                ;@S10
        pop     dx                      ;Restore SG number              ;@T18
        pop     si                      ;Restore offset to selector entry ;@TL1
        pop     ax                      ;Restore current configuration #   @S10
        mov     es:[bx].bvs_curconfig,ax ;@S10

        push    BVSISEG                 ;@S10
        pop     es                      ;@S10

        .if     <dx e 3> and                    ;Real popup session and ;@T18
        .if     <es:bvsi_sgnum e dx>            ;  NOT the shell?       ;@T18
            mov     dx,es:bvsi_bvssel           ;Save popup session's   ;@T18
            mov     es:bvsi_pop_popsel,dx       ;BVSCB selector         ;@T18
        .endif                                                          ;@T18

        .if     <nonzero ax>            ;Configuration already set ;@S10
            dec     ax                  ;Convert 1 base to 0 base ;@S10
            imul    ax,selt_nextenvb-selt_envb ;@S10
            add     si,ax               ;Add adjustment to offset ;@S10
        .endif                          ;@S10

        mov     ax,gs:[si].selt_envb    ;@S10,@D549,@T80
        mov     es:bvsi_envsel,ax       ;@S10                           ;@T52
        mov     ax,gs:[si].selt_lvb     ;@S10,@D549,@T80
        mov     es:bvsi_lvbsel,ax       ;@S10                           ;@T52

        pop     dx                                                      ;@T18
        pop     di
        pop     es                      ;D261
        pop     si
        pop     ds
        ret
GetBVSCB ENDP

;----------------------------------------------------------------------
; Initialize the BVSCB.
;       On entry: BVSISEG:bvsi_bvssel = Selector of BVSCB
;----------------------------------------------------------------------

InitBVSCB PROC  NEAR
        public  InitBVSCB

        push    ds
        push    es                      ;@S14

        push    ds
        pop     es                      ;Get pointer to BVSCB

        push    BVSGSEG
        pop     ds                      ;Get pointer to Global data

        mov     cx,ds:bvsg_bvscbsize    ;Get computed BVSCB size        ;@T52
        mov     al,0
        sub     di,di
        rep     stosb                   ;Clear the new BVSCB

        mov     si,offset bvsg_cprtemp
        mov     di,bvs_cprTemp
        mov     cx,offset bvsg_bvscbname                                ;@T52
        sub     cx,offset bvsg_cprtemp                                  ;@T52
        rep     movsb                   ;Move Cpr template to bvscb

        mov     cx,ds:ILASTVDH          ;Get last available VDH (#configs) ;@S10
        mov     ax,ds:bvsg_flags        ;Get Global flags ;@S10         ;@T52

        push    es
        pop     ds                      ;DS = Session data (BVSCB)
        push    BVSISEG
        pop     es                      ;ES = Instance data

        mov     [bx].bvs_flags,bvs_f_ansi+bvs_f_ansiwrap ;Default = ANSI ON
        mov     word ptr [bx].bvs_ttycell,0720h ;Scroll cell

        test    ax,bvsg_f_mouactive
        .if     <nz> and                ;Mouse active in system
        .if     <es:bvsi_sgnum ne bx>   ;Not session 0                  ;@T52
            or      [bx].bvs_flags,bvs_f_mouactive+bvs_f_mounotify ;Use mouse
        .endif

        push    ds
        mov     ds,es:bvsi_gdtsel                                       ;@T52
        mov     al,[bx].SIS_MaxScrnGrp  ;Max base session
        cbw                                                             ;@T52
        pop     ds
        mov     [bx].bvs_curconfig,1    ;Preset PowerUp VDH
        mov     [bx].bvs_numconfigs,cx  ;Init number of configurations  ;@S10
        .if     <es:bvsi_sgnum ae ax> or ;Windowable/AVIO session  ;@T52,@T71
        .if     <es:bvsi_sgnum e 1> and                                 ;@T71
        .if     <es:bvsi_sg1_bvssel a bx>                               ;@T71
            mov     [bx].bvs_curconfig,bx ;Set Windowable VDH
            mov     [bx].bvs_numconfigs,bx ;Disallow switching and mouse
            and     [bx].bvs_flags,NOT (bvs_f_mouactive+bvs_f_mounotify)
            or      [bx].bvs_flags, bvs_f_wrtthru         ;OK Write Thru  ;@B30

;*****************************************************************************
;NOTE:  Assuming dummy RESTORE always 1st call for VioWindowable so if this
;       is a Restore call then it must be window else it must be avio     ;@D549
;*****************************************************************************
            .if     <[bp].p_viofunc eq vf_Restore>                        ;@D549
                or      [bx].bvs_flags, bvs_f_window
            .else
                or      [bx].bvs_flags, bvs_f_avio
            .endif
        .endif

        sub     ax,ax
        pop     es                      ;@S14
        pop     ds
        ret
InitBVSCB ENDP

;----------------------------------------------------------------------
; InitConfig -- Initialize a video configuration
;----------------------------------------------------------------------

InitConfig PROC NEAR                    ;@S10
        public  InitConfig              ;@S10

        push    es                      ;Save BVSCB ;@S10

        mov     ax,BVSISEG              ;@S10
        mov     es,ax                   ;Set ES = BvsInstance ;@S10
        mov     ax,es:bvsi_bvssel       ;@S10                           ;@T52

        .if     <nonzero ax> near       ;@S10
            push    ds                  ;@S10
            mov     ds,ax               ;Set DS = BVSCB ;@S10

            push    [bx].bvs_bvssize    ;@S10
            mov     cx,[bx].bvs_curconfig ;@S10
            .if     <ncxz>              ;@S10
                dec     cx              ;Header in place of config 0 ;@S10
            .endif                      ;@S10

            mov     ax,BVSGSEG          ;@S10;@B14
            mov     ds,ax               ;@S10;@B14

            mov     si,es:bvsi_sgnum                         ;@S10,@D549;@T52
            shl     si,2                       ;adjust for dword align  ;@D549
            lgs     si,ds:bvsg_seltable[si]                             ;@T80

            mov     dx,2                ;@S10
            shl     dx,cl               ;Get mask for this config ;@S10

            mov     di,cx               ;@S10
            imul    di,selt_nextenvb-selt_envb ;@S10
            add     di,si               ;Get base for correct config ;@S10

            pop     cx                  ;Get BVSCB size ;@S10

            mov     ax,gs:[di].selt_envb   ;@S10,@D549,@T80
            mov     es:bvsi_envsel,ax   ;@S10                           ;@T52
            .if     <nonzero ax> and near                               ;AR07349
            mov     ax,gs:[di].selt_lvb    ;@S10,@D549,@T80
            mov     es:bvsi_lvbsel,ax   ;@S10                           ;@T52
            .if     <nonzero ax> near                                   ;AR07349

                .if     <cxz> or            ;BVSCB not initialized ;@S10
                .if     <bit gs:[si].selt_flags nand dx> near ;Config not yet init ;@T80
                    push    ds              ;@S14
                    push    si              ;@S14
                    push    dx              ;@S14

                    mov     ds,es:bvsi_bvssel ;Restore BVSCB selector  ;@S10;@T52
                    mov     [bp].vp_ev_selector,ax ;Pass the LVB selector

                    .if     <zero cx>       ;@S14
                        Call    InitBVSCB   ;Init BVSCB as required ;@S14
                    .endif                  ;@S14

;----------------------------------------------------------------------
; Initialize the Environment Buffer and the video mode
;----------------------------------------------------------------------

                    .if     <[bp].p_viofunc e vf_Restore> ;Dummy restore? ;@T71
                        mov     ax,[bp].sr_sgnum                        ;@D549
                        .if     <ah eq PROG_FULLSCREEN>                 ;@D549
                            xor   ah,ah                                 ;@D549
                        .endif                                          ;@D549
                    .else                                               ;@T71
                        mov     ax,es:bvsi_sgnum                        ;@T71
                        .if     <nonzero ax>                ;AVIO?      ;@T71
                            mov     ah,PROG_PM                          ;@T71
                        .endif                                          ;@T71
                    .endif                                              ;@T71
                    mov     [bp].vp_ev_session,ax ;Pass the session number
                    mov     di,fn_InitEnv   ;VDH Init Environment function
                    Call    AllVDH
                    .if     <nonzero ax>    ;@S18
                        mov     es:bvsi_level,bx ;@S18                  ;@T52
                        mov     ax,ERROR_VIO_INTERNAL_RESOURCE ;@S18
                        jmp     finis       ;End it all ;@S18
                    .endif                  ;@S18

;----------------------------------------------------------------------
; Synchronize the Mode and Cursor data and increase LVB size as needed.
;----------------------------------------------------------------------

                    mov     si,es:bvsi_lvbsel ;@@A                      ;@T52
                    Call    UpdateLVBSize   ;Increase LVB size, as needed
                    .if     <nonzero ax> and    ;@@A
                    .if     <[bp].p_viofunc ne vf_free>                 ;AR07349
                        mov     es:bvsi_level,bx                        ;@T52
                        mov     ax,ERROR_VIO_INTERNAL_RESOURCE
                        jmp     finis       ;End it all
                    .endif

;----------------------------------------------------------------------
; Clear the screen, if not an AVIO session
;----------------------------------------------------------------------
                    .if     <zero ax>                                   ;J200261
                        test    [bx].bvs_flags,bvs_f_avio
                        .if     <z>             ;Not AVIO, can handle buffer update
                            call    ClearScreen ;Clear the screen ;@P1
                        .endif

                        call    GetDBCSInfo     ;Get the DBCS display info ;@P1
                        call    GetScrollRect   ;@P1
                    .endif                                              ;J200261
;----------------------------------------------------------------------
; Re-enable video at end of initialization
;----------------------------------------------------------------------

                    mov     ax,vp_f_enable  ;@S43
                    mov     [bp].vp_enable,1 ;@S43
                    Call    AllSetVarInfo   ;Enable the video signal ;@S43

                    pop     ax              ;@S14
                    pop     si              ;@S14
                    pop     ds              ;@S14
                    or      gs:[si].selt_flags,ax ;Record successful init ;@S10;@S14;@T80

;----------------------------------------------------------------------
; Set the Shell config for Windowed VIO as required
;----------------------------------------------------------------------

                    .if     <es:bvsi_sgnum eq 1> and ;Shell ;@S33  ;@T52,@TL8f
                    .if     <ds:WndwConfig.cf_adapter e bx>             ;@TL8f
                        mov     [bp].vp_offset,OFFSET WndwConfig ;@S33
                        mov     [bp].vp_selector,ds ;@S33
                        mov     ax,size configdata ;@S33
                        mov     word ptr ds:WndwConfig,ax ;Set config size ;@S33

                        mov     di,fn_GetConfig ;@S33
                        Call    AllVDH      ;@S33
                    .endif                  ;@S33

                    mov     ax,ds:bvsg_bvscbsize ;@S14                  ;@T52
                    mov     ds,es:bvsi_bvssel    ;@S14                  ;@T52
                    mov     [bx].bvs_bvssize,ax ;Record successful BVSCB init ;@S14

                .endif                      ;@S10
            ;;;; - 82351
            .else
            mov     es:bvsi_envsel,ax
            ;;;; - 82351
            .endif                                                      ;AR07349

            pop     ds                  ;@S10
            sub     ax,ax               ;Always good ;@S10

        .else                           ;No BVSCB ;@S10
            mov     es:bvsi_envsel,ax   ;@S10                           ;@T52
            mov     es:bvsi_lvbsel,ax   ;Clear other selectors ;@S10    ;@T52
        .endif                          ;@S10

        pop     es                      ;@S10
        ret                             ;@S10
InitConfig ENDP                         ;@S10

CTEXT_TUNE5 ENDS                                                        ;MDLL
        END

;@@A = 12/12/88 STJ, Update sizes of ENVB and LVB as needed, P3088
;@P1 = 03/25/89  PL, DCR 132 changes
;@B1 = 03/26/89  BB, Reduce LVB hugh selector allocation, B700554
;D198 = 04/13/89 STJ, Install BvsPrtSc and BvsWrtTTY as VDH default routines
;D261 = 04/21/89 STJ, Use CONFIG.SYS instead of OS2.INI and optimize
;@S10 = 05/11/89 STJ, Retain separate ENVB/LVB for each config, B701174
;@T51 = 05/26/89 TPL, Removal of 3xbox code for 2.0, DCR 432.10
;@S14 = 06/08/89 STJ, Fix initialization of AVIO session, B703158
;@B14 = 07/05/89 WKB, Performance enhancements, B702527
;@S18 = 07/19/89 STJ, Return InitEnv error codes, B704913
;@S23 = 08/16/89 STJ, Reallocate the ENVB after Shell Init, B706727
;@T48 = 09/13/89 TPL, Load VDH after a popup, fix to PTR B707495, PTR B707542
;@S30 = 09/22/89 STJ, Use DosSizeSeg to determine need to ReAlloc, B707664
;@C34 = 09/26/89 CJJ, Call GetLVBInfo to get default attributes, B785912
;@S33 = 10/09/89 STJ, Set Shell config for Windowed VIO, B786058, B708074
;@C36 = 10/11/89 CJJ, Deleted code for B785912 (@C34), SM86158
;@TL1 = 10/12/89 TPL, Pre-allocate 3xBox LVB to max, B786201
;@B25 = 10/13/89 WKB, Avoid trap on BVSFREE of an AVIO session, HM00772
;@D549 = 11/02/89 CJJ, Seltable changes due to rangeless sessions, DCR 549
;@TL3 = 10/25/89 TPL, Use config memory size for 3xBox LVB allocation, B786201
;@S43 = 11/13/89 STJ, Video must be enabled at end of InitConfig, AR05447
;@B30 = 12/01/89 WKB, Allow VIOSHOWBUF updates in WINDOW and AVIO, B787183
;@T52 = 01/16/90 TPL, DCR 704 work
;@T14 = 03/29/90 TPL, @T48 fix
;@T18 = 04/30/90 TPL, Avoid doing DosGetSegs to SGCB if not necessary, B712103
;@T71 = 07/06/90 TPL, Allow Shell to make AVIO calls, Hursley DCR 25177, B714347
;@TL8f = 08/14/90 TPL, DCR 1093 fix - OEM DISP DRVR doesn't do setmode, B715356
;AR07349=10/18/90 TPL, Handle out of resource situations in InitConfig
;@C39 = 01/15/91 CJJ, MVDM transparent popup changes, PTR SM84577
;J200261= 02/13/91 TPL, Don't call ClearScreen when UpdateLVBSize failed under VioFree
;@T74 = 02/25/91 TPL, Make sure AVIO SelTable entry is remove on VioFree, B719886
;@T14f= 05/08/91 TPL, Allow Detached to issue multiple popups, B790735
;@T14ff=07/19/91 TPL, Don't InitEnv if a process spawned in the popup session
;                     issues VIO calls, B724902
;@T14fff=07/19/91 TPL, Fix for viowrttty incorrect output, AA04427.
;@T80 = 02/06/92 TPL, Don't use the reserved register FS, B732479
;MDLL = 01/10/94 BJN, Page Tune segments for Merged DLL.
;76155 = 5/17/94 (2.11+) 76155 ChgTeam  Verify  BVSCB selector before loading.
;142736 = 04/02/96 MNH, keep fix for tcorbs100
