;       SCCSID = @(#)vioinit.asm        6.7 92/02/13
        PAGE    58,132
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        SUBTTL  Data declarations, etc.
        TITLE   VIOINIT.ASM -- VIDEO PROCESS and SESSION INITIALIZATION
;******************************************************************************
;*******   C H A N G E       H I S T O R Y   **********************************
;******************************************************************************
;@T52 = 01/15/90 TPL, DCR 704 work
;@T18 = 04/30/90 TPL, B712103 - Optimize popup processing by getting access
;                               to popup SGCB at VIOPROCESSINIT
;@T73 = 07/27/90 TPL, Code/data reduction/optimization and swap tune
;@T74 = 02/07/91 TPL, Avoid Trap D on WrtTTY for detached in a popup, B718071
;@T14f= 05/08/91 TPL, Allow Detached to issue multiple popups, B790735
;001B = 07/03/91 TPL, Avoid calling BVS at Process Init time to allow
;                     invalid BVH DLLs to unlink immediately, B724540
;@C51 = 08/01/91  CJJ, Get codepage during session init, VioSetCP in router.
;@C51f= 08/15/91  WKB, Call initCP in VIOINITPROCESS, B725894
;@T80 = 02/06/92 TPL, Don't use the reserved register FS, B732479
;MDLL = 01/10/94 BJN, Page Tune segments for Merged DLL.

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* Source File Name:  VIOINIT.ASM                                      */
;/*                                                                     */
;/* Descriptive Name:  Process and Session Initialization for VIOCALLS  */
;/*                                                                     */
;/* Function:  Call DosGetInfoSeg to get info on the current SG and     */
;/*            process, load BVSCALLS and get access to BvsMain,        */
;/*            create/open Prtsc and Popup semaphores, add exit list    */
;/*            processing routines and initialize the SGCB.             */
;/*                                                                     */
;/* Notes:                                                              */
;/*                                                                     */
;/* Entry Points:  VIOINITPROCESS, VIOINITSESSION                       */
;/*                                                                     */
;/* External References:  Base Video Subsystem                          */
;/*            Routines:  DosGetProcAddr, DosLoadModule, DosGetInfoSeg, */
;/*                       DosOpenSem, DosCreateSem, DosSMGetSGCB,       */
;/*                       DosExitList, DosFSRamSemRequest,              */
;/*                       DosGetDBCSEv, DosFSRamSemClear                */
;/*                                                                     */
;/* Internal References:                                                */
;/*         Common Data:                                                */
;/*                  BVS_MOD - Base Video Subsystem name                */
;/*                  BVS_EP  - Base Video Subsystem entry procedure name*/
;/*                  dbcsctrycode - default country codepage            */
;/*       Instance Data:                                                */
;/*                  gdtinfo - GDTINFO selector                         */
;/*                  ldtinfo - LDTINFO selector                         */
;/*                  procTYPE - current process type                    */
;/*                  currPID - current process ID                       */
;/*                  currSG  - current screen group                     */
;/*                  mmio_sel - performance trace selector              */
;/*                  bvs_off - Base Video Subsystem BVSMAIN offset      */
;/*                  bvs_hand - Base Video Subsystem handle             */
;/*                  pu_sel_lo - popup semaphore handle                 */
;/*                  popupsem - popup semaphore name                    */
;/*                  prtscsemlo - prtsc semaphore handle                */
;/*                  prtscsem - prtsc semaphore name                    */
;/*                  SGCB - Screen Group Control Block pointer          */
;/*                  fsRAMsel - selectot to SG semaphore                */
;/*                  fsRAMoff - offset to SG semaphore                  */
;/*           SGCB Data:                                                */
;/*                  VIO_fsRAMSGinit - SG initialization semaphore      */
;/*                  VIO_fsRAMSsem - SG semaphore                       */
;/*                  VIO_dbcsrangebuf - ranges for double-byte chars    */
;/*                  VIO_dbcsflag - flag for DBCS info                  */
;/*                  VIO_sg_init - flag for SG initialization           */
;/*            Routines: initCP, VIOFSRAMEXIT0, VIOFSRAMEXIT            */
;/*                                                                     */
;/*********************** END OF SPECIFICATIONS *************************/


.xlist
include error.inc
include error2.inc
include struc.inc
include infoseg.inc
include vioequ.inc
include viocdata.inc
include viomac.inc
include vioidata.inc
;@T73 include viogdata.inc
include vioextrn.inc
.list

.386p

IFDEF MMIOPH
EXTRN   viopretrace:NEAR
EXTRN   vioposttrace:NEAR
ENDIF

EXTRN   DOSGETDBCSEV:FAR
EXTRN   DOSFSRAMSEMREQUEST:FAR
EXTRN   DOSFSRAMSEMCLEAR:FAR
EXTRN   VIOFSRAMEXIT:FAR
EXTRN   VIOFSRAMEXIT0:FAR
EXTRN   initCP:NEAR
EXTRN   BVSMAIN:FAR        ; resides in CODE02 group                    ;MDLL

EXTRN   _InitFlag:WORD     ; bit 1 set means avoid loading BVSMAIN      ;MDLL
                           ; see definition in BVSMAIN.C                ;MDLL

public  VIOINITPROCESS  ;FAR public routines
public  VIOINITSESSION


instance segment byte public 'data' USE16
instance ends

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

CTEXT_TUNE2   segment byte public 'code'   USE16                        ;MDLL
CTEXT_TUNE2   ends                                                      ;MDLL

CODE02   GROUP CTEXT_TUNE2                                              ;MDLL

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

        SUBTTL VIOINITPROCESS - VIOROUTER PROCESS INITILIZATION PROCEDURE
        page
;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: VIOINITPROCESS                                     */
;/*                                                                     */
;/* DESCRIPTIVE NAME: VIOROUTER pre process initialization procedure    */
;/*                                                                     */
;/* FUNCTION: Puts GDTINFO and LDTINFO selectors in Instance data       */
;/*           Puts current SG and process info in Instance data         */
;/*           Attempt to load the Base video Subsystem module           */
;/*           Create/open system semaphores for popup and prtsc         */
;/*           Adds exitlist routines VIOFSRAMEXIT and VIOFSRAMEXIT0     */
;/*           Gets access to per screen group data area (DOSSMGETCB)    */
;/*           Calls VIOINITSESSION to initialize SGCB                   */
;/*                                                                     */
;/* NOTES:    Called on a per process basis                             */
;/*                                                                     */
;/*                                                                     */
;/*                                                                     */
;/* ENTRY POINT: VIOINITPROCESS                                         */
;/*     LINKAGE: FAR CALL (from CP/DOS dynamic-linker/loader)           */
;/*                                                                     */
;/* INPUT: None.                                                        */
;/*                                                                     */
;/* EXIT-NORMAL: AX = NO_ERROR                                          */
;/*                                                                     */
;/* EXIT-ERROR: AX = 0FFFFH (-1)                                        */
;/*                                                                     */
;/* EFFECTS: The contents of AX are destroyed.                          */
;/*                                                                     */
;/* INTERNAL                                                            */
;/* REFERENCES:                                                         */
;/*         Common Data:                                                */
;/*                  BVS_MOD - Base Video Subsystem name                */
;/*                  BVS_EP  - Base Video Subsystem entry procedure name*/
;/*       Instance Data:                                                */
;/*                  gdtinfo - GDTINFO selector                         */
;/*                  ldtinfo - LDTINFO selector                         */
;/*                  procTYPE - current process type                    */
;/*                  currPID - current process ID                       */
;/*                  currSG  - current screen group                     */
;/*                  mmio_sel - performance trace selector              */
;/*                  bvs_off - Base Video Subsystem BVSMAIN offset      */
;/*                  bvs_hand - Base Video Subsystem handle             */
;/*                  pu_sel_lo - popup semaphore handle                 */
;/*                  popupsem - popup semaphore name                    */
;/*                  prtscsemlo - prtsc semaphore handle                */
;/*                  prtscsem - prtsc semaphore name                    */
;/*                  SGCB - Screen Group Control Block pointer          */
;/*                  fsRAMsel - selectot to SG semaphore                */
;/*                  fsRAMoff - offset to SG semaphore                  */
;/*           SGCB Data:                                                */
;/*                  VIO_sg_init - flag for SG initialization           */
;/*   ROUTINES: VIOFSRAMEXIT0 - early exitlist routine                  */
;/*             VIOFSRAMEXIT  - exitlist routine                        */
;/*             VIOINITSESSION - SGCB initialization                    */
;/*                                                                     */
;/* EXTERNAL                                                            */
;/* REFERENCES: None.                                                   */
;/*   ROUTINES: DOSCREATESEM - create system semaphore                  */
;/*             DOSOPENSEM - open system semaphore                      */
;/*             DOSGETINFOSEG - get global/local info segment selectors */
;/*             DOSGETPROCADDR - get descriptor for a dynamic-link      */
;/*             DOSLOADMODULE - load dynamic-link module                */
;/*             DOSSMGETSGCB - get a SGCB                               */
;/*********************** END OF SPECIFICATIONS *************************/
;
;psuedo code
;
; call DosGetInfoSeg
; if no error
;   get current process and SG info
; load BVSCALLS
; if no error
;   create/open popup semaphore
;   if no error
;     create/open prtsc semaphore
;     if no error
;       get SGCB for current SG
;       if no error
;         add exitlist routines
;         if no eror
;           initialize fsRAMoff/fsRAMsel in instance data
;           if SGCB not initialized
;             call VIOINITSESSION
;

VIOINITPROCESS proc far         ;new routine for D549

   pushf                        ;save flags and registers
   push bx                      ;
   push cx                      ;
   push dx                      ;
   push ds                      ;
   push es                      ;
   push gs                      ;                                       ;@T80
   push si                      ;
   push di                      ;

   mov  ax,instance             ;DS <-- instance data selector
   mov  ds,ax

   push ds                      ;sel:off to GDTINFO selector
   push offset gdtinfo          ;                                       ;@T52
   push ds                      ;sel:off to LDTINFO selector
   push offset ldtinfo          ;                                       ;@T52
   call DOSGETINFOSEG

   .if <zero ax>
     mov  es,ds:ldtinfo
     mov  al,es:[LIS_ProcType]  ;procTYPE <-- current process type
     mov  ds:procTYPE,ax        ;
     mov  ax,es:[LIS_CurProcID] ;currPID <-- current process PID
     mov  ds:currPID,ax         ;
     mov  ax,es:[LIS_CurScrnGrp];currSG <-- current screen group ID
     mov  ds:currSG,ax          ;

     IFDEF MMIOPH
       mov  es,ds:gdtinfo
       mov  ax,es:[SIS_MMIOBase]  ;get performance trace selector
       mov  ds:mmio_sel,ax        ;
     ENDIF

   .endif

   mov  ax,common               ;get addressability to common data
   mov  es,ax
   xor  ax,ax

   .if  <ds:currSG ne 3>        ;don't get popup SGCB again             ;@T18
     push ds                    ;                                       ;@T18
     push offset SGCB_pop       ;                                       ;@T18
     push 3                     ;                                       ;@T18
     push Look_up_SGID          ;                                       ;@T18
     call DOSSMGETSGCB          ;get popup SGCB address                 ;@T18
   .endif                       ;                                       ;@T18

   .if  <zero ax> NEAR                                             ;@T18,@T74
     mov  eax, ds:SGCB_pop      ;initialize default SGCB pointer        ;@T74
     mov  ds:SGCB, eax          ;  for detached process                 ;@T74
     sub  eax, eax                                                      ;@T74
     .if  <ds:procTYPE ne LIS_PT_DETACHED> ;Not a detached process?     ;@T14
       .if <BIT es:_InitFlag, AND 02h> ;BVSMAIN forwarded to DOSCALL1?  ;MDLL
         mov  ds:bvs_sel, CODE02                                        ;MDLL
         mov  ds:bvs_off, OFFSET BVSMAIN                                ;MDLL
       .else                                                            ;MDLL
         push ax                ;
         push ax                ;address to ObjNameBuf
         push ax                ;ObjNameBufL (length of ObjNameBuf in bytes)
         push es                ;sel:off to module name
         push offset bvs_mod    ;                                       ;@T52
         push ds                ;sel:off to module handle (returned)
         push offset bvs_hand   ;                                       ;@T52
         call DOSLOADMODULE     ;load dynamic-link module (BVSCALLS.EXE)

         .if <zero ax>
           push ds:bvs_hand     ;module handle
           push ax              ;sel:off to BVS entry proc. name
           push es:bvs_ep       ;BVSMAIN entry point ordinal       ;@T52,@T18
           push ds              ;sel:off to sel:off (returned)
           push offset bvs_off  ;                                       ;@T52
           call DOSGETPROCADDR  ;get addressability to dyn-link proc.
         .endif
         ;                                                              ;MDLL
         ; If the address obtained is forwarded back to us then         ;MDLL
         ; set _InitFlag to skip DOSLOADMODULE on BVSMAIN               ;MDLL
         ;                                                              ;MDLL
         .if <zero ax>                                                  ;MDLL
           .if <ds:bvs_sel eq CODE02> AND                               ;MDLL
           .if <ds:bvs_off eq <OFFSET BVSMAIN>>                         ;MDLL
             or es:_InitFlag, 02h                                       ;MDLL
             push ds:bvs_hand                                           ;MDLL
             call DOSFREEMODULE                                         ;MDLL
           .endif                                                       ;MDLL
         .endif                                                         ;MDLL
       .endif                                                           ;MDLL
     .else                                                              ;@T14f
        lgs  bx,ds:SGCB         ;load gs:[bx] with SGCB ptr       ;@T14f,@T80
                                                                        ;@T14f
        mov  gs:[bx].VIO_fsRAMSGinit,14                           ;@T14f,@T80
        lea  bx,[bx].VIO_fsRAMsem                                       ;@T14f
        mov  ds:fsRAMoff,bx     ;initialize fsRAMoff for SG             ;@T14f
        mov  ds:fsRAMsel,gs     ;semaphore                        ;@T14f,@T80
     .endif
   .endif                                                               ;@T74

   .if <zero ax>
     ;**********************************************************************
     ; open POPUP semaphore, if error need to create it, if error from create
     ; another process was switched to who created it so try open again
     ;**********************************************************************

     push ds                    ;sel:off to sem. handle (returned)
     push offset pu_sem_lo      ;                                       ;@T52
     push es                    ;sel:off to sem. name
     push offset popupsem       ;                                       ;@T52
     call DOSOPENSEM            ;open popup semaphore

     .if <nonzero ax>
       push 1                   ;non-exclusive ownership
       push ds                  ;sel:off to semaphore handle
       push offset pu_sem_lo    ;  (returned)                           ;@T52
       push es                  ;sel:off to ASCIIZ sem. name
       push offset popupsem     ;                                       ;@T52
       call DOSCREATESEM        ;;; This must be non-exclusive!!!

       .if <nonzero ax>
         push ds                ;sel:off to sem. handle (returned)
         push offset pu_sem_lo  ;                                       ;@T52
         push es                ;sel:off to sem. name
         push offset popupsem   ;                                       ;@T52
         call DOSOPENSEM        ;try open popup semaphore again
       .endif

     .endif

  .endif

  .if <zero ax> and near                                                ;@T14
  .if <ds:procTYPE ne LIS_PT_DETACHED> near   ;Not a detached ?         ;@T14
    ;********************************************************************
    ; open PRTSC semaphore, if error need to create it, if error from
    ; create, another process was switched to who created it so try open
    ; again
    ;********************************************************************

    push ds                     ;sel:off to sem. handle (returned)
    push offset prtscsemlo      ;                                       ;@T52
    push es                     ;sel:off to sem. name
    push offset prtscsem        ;                                       ;@T52
    call DOSOPENSEM             ;open prtsc semaphore

    .if <nonzero ax>
      push 0000H                ;exclusive ownership
      push ds                   ;sel:off to semaphore handle
      push offset prtscsemlo    ;  (returned)                           ;@T52
      push es                   ;sel:off to ASCIIZ sem. name
      push offset prtscsem      ;                                       ;@T52
      call DOSCREATESEM         ;

      .if <nonzero ax>
        push ds                 ;sel:off to sem. handle (returned)
        push offset prtscsemlo  ;                                       ;@T52
        push es                 ;sel:off to sem. name
        push offset prtscsem    ;                                       ;@T52
        call DOSOPENSEM         ;try open prtsc semaphore again
      .endif

    .endif

    .if <zero ax>
      push ds                   ;sel:off to SGCB address
      push offset SGCB          ;  (returned)                           ;@T52
      push ds:currSG            ;
      push Look_up_SGID         ;
      call DOSSMGETSGCB         ;get addressability to Screen Grp CB

      .if <zero ax>
        push 0C081H             ;add early exitlist routine
        mov  ax,cs              ;
        or   ax,3               ;
        push ax                 ;
        push offset VIOFSRAMEXIT0
        call DOSEXITLIST        ;

        push 0C001H             ;add routine to exit list
        mov  ax,cs              ;
        or   ax,3               ;
        push ax                 ;
        push offset VIOFSRAMEXIT
        call DOSEXITLIST        ;

        lgs  bx,ds:SGCB         ;load gs:[bx] with SGCB ptr             ;@T80

        lea  ax,[bx].VIO_fsRAMsem                                       ;@T14
        mov  ds:fsRAMoff,ax     ;initialize fsRAMoff for SG
        mov  ds:fsRAMsel,gs     ;semaphore                              ;@T80

        test gs:[bx].VIO_sg_init,1                                 ;001B,@T80
        .if <z>                 ;call session initialization       ;@T14,001B
          call  VIOINITSESSION
        .endif

         call initCP            ;setup DOS codepage ID                  ;C51f
         xor  ax,ax
      .endif

    .endif

  .endif

   pop  di                      ;restore flags and registers and return
   pop  si                      ;
   pop  gs                      ;                                       ;@T80
   pop  es                      ;
   pop  ds                      ;
   pop  dx                      ;
   pop  cx                      ;
   pop  bx                      ;
   popf                         ;
   ret                          ;
VIOINITPROCESS endp


        SUBTTL VIOINITSESSION - per-session VIO initialization
        page
;/*********************** START OF SPECIFICATIONS ****************************/
;/* SUBROUTINE NAMES:  VIOINITSESSION                                        */
;/*                                                                          */
;/* DESCRIPTIVE NAMES: initialize a session's SGCB                           */
;/*                                                                          */
;/* FUNCTIONS:  The first VIO call for a session will cause VIOINITPROCESS() */
;/*             to call VIOINITSESSION().                                    */
;/*             After synchronizing with the SESSION init SEM, initialize    */
;/*             the SG fsRAMsem, init session's video codepage(via INITCP)   */
;/*             to the process's system codepage and call DOSGETDBCSEV to    */
;/*             get the valid ranges for DBCS.                               */
;/*                                                                          */
;/* ENTRY POINTS:  VIOINITSESSION                                            */
;/*     LINKAGES:  NEAR CALL (from VIOINITPROCESS)                           */
;/*                                                                          */
;/* INPUT: N/A                                                               */
;/*                                                                          */
;/* EXIT-NORMAL:  N/A                                                        */
;/*                                                                          */
;/* EXIT-ERROR:  N/A                                                         */
;/*                                                                          */
;/* EFFECTS:  sets a session's video codepage to its process codepage,       */
;/*           initializes the session's fsRAMsem length and sets the         */
;/*           the valid ranges for DBCS                                      */
;/*                                                                          */
;/* External References:  None.                                              */
;/*            Routines:  DosFSRamSemRequest - request FS RAM semaphore      */
;/*                       DosFSRamSemClear - claer FS RAM semaphore          */
;/*                       DosGetDBCSEv - get DBCS environment                */
;/*                                                                          */
;/* Internal References:                                                     */
;/*         Common Data:                                                     */
;/*                  dbcsctrycode - default country codepage                 */
;/*       Instance Data:                                                     */
;/*                  currSG  - current screen group                          */
;/*           SGCB Data:                                                     */
;/*                  VIO_fsRAMSGinit - SG initialization semaphore           */
;/*                  VIO_fsRAMSsem - SG semaphore                            */
;/*                  VIO_dbcsrangebuf - ranges for double-byte chars         */
;/*                  VIO_dbcsflag - flag for DBCS info                       */
;/*                  VIO_sg_init - flag for SG initialization                */
;/*            Routines: InitCP - initialize session's video codepage to     */
;/*                               system codepage                            */
;/*********************** END OF SPECIFICATIONS ******************************/
;
;psuedo code
;
; request SG initialization semaphore
; if SGCB not initialized
;   initialize fsRAMsem length
;   if not Shell
;     call initCP
;   call DosGetDBCSEv
;   set dbcsflag
;   set SGCB init flag
; clear SG initialization semaphore
;

VIOINITSESSION proc near

   mov  gs:[bx].VIO_fsRAMSGinit,14     ;initialize fsRAMsem length      ;@T80

   mov  dx,bx           ;DX <-- offset of SESSION init SEM
   add  dx,VIO_fsRAMSGinit

   push gs              ;block multiple callers                         ;@T80
   push dx              ;  only first caller "does real work"
;  push 0FFFFh          ;wait
   push dword ptr -1    ;   until sem is available                      ;@T18
   call DOSFSRAMSEMREQUEST

   test gs:[bx].VIO_sg_init,1                                      ;001B,@T80
   .if <z>                                                              ;001B

     mov  gs:[bx].VIO_fsRAMsem,14   ;initialize fsRAMsem length         ;@T80

     .if <ds:currSG ne 1>           ;call initCP if not shell SG
       or   gs:[bx].VIO_sg_init,1   ;prevent recursion        ;@T14,001B,@T80
;C51f  call initCP                  ;initialize proccp             ;@C51

       push 10                      ;DBCS environment (list of valid
       push es                      ;ranges for double-byte's 1st byte
       push offset dbcsctrycode     ;terminated by 2 bytes of 0's)      ;@T52
       push gs                                                          ;@T80
       lea  ax,gs:[bx].VIO_dbcsrangebuf                                 ;@T80       ;D549
       push ax
       call DOSGETDBCSEV

       mov  gs:[bx].VIO_dbcsflag,1  ;set DBCS flag                      ;@T80

;001B  mov  gs:[bx].VIO_sg_init,1   ;set SG init flag
     .endif

   .endif


   push gs              ;unblock all other callers                      ;@T80
   push dx              ;
   call DOSFSRAMSEMCLEAR;

   ret
VIOINITSESSION endp

CTEXT_TUNE2    ends                                                     ;MDLL
        end  ;VIOINITPROCESS                                            ;@T52
