;      SCCSID = @(#)initdc1.asm 6.7 92/02/24

        TITLE   initdc1 - Initialize the DOSCALL1 library.

;**     initdc1 - Initialize the DOSCALL1 library.
;
;        IBM/Microsoft Confidential
;
;        Copyright (c) IBM Corporation 1987, 1989
;        Copyright (c) Microsoft Corporation 1987, 1989
;
;        All Rights Reserved
;
;
;***    Modification History
;
;       11/18/93        noto    Define which segment for Page Tuning DLL


page    ,132
.386p

.xlist
include basemaca.inc
include mi.inc
include dc1segs.inc
include infoseg.inc
.list

        EXTRN   DOSGETINFOSEG:FAR
        EXTRN   DOSGETDBCSEV:FAR
        EXTRN   DOSLOADMODULE:FAR
        EXTRN   DOSGETPROCADDR:FAR
        EXTRN   NLS_Init:FAR
        EXTRN   MSGINIT:FAR
;MDLL   EXTRN   _MonInstanceInit:FAR
        EXTRN   _DYNAINIT:FAR           ; QUECALLS global init routine  ;MDLL
        EXTRN   SMGGLOBALINIT:FAR       ; SESMGR global init routine    ;MDLL
        EXTRN   OS2BASEINIT:FAR         ; OS2CHAR instance init routine ;MDLL

        ifdef   MMIOPH
            EXTRN   _globptr:dword      ;pointer used in Mon_Sys_Trace and NLS_Sys_Trace
        endif                           ;MMIOPH


;
; When/if the loader ever executes library initialization modules
; whenever a library is linked to, this segment can go away.
;

SHRDATA SEGMENT

        PUBLIC  _globalIS
_globalIS LABEL word                    ; allow C to reference var

        PUBLIC  globalIS
globalIS DW     ?                       ; global InfoSeg selector

        PUBLIC  localIS
localIS DW      ?                       ; local InfoSeg selector

;       This is the data area that receives the information about the
;        ranges of the DBCS lead bytes from DOSGETDBCSEV.
;       There are a low and high byte for each range, with 2 terminating
;        zeros. For 1.1 there are a max of 5 ranges, making 12 bytes in all.

        public  dbcs_data
dbcs_data db    12 DUP (0)

dbcs_data_size equ $ - dbcs_data

input_dbcs_data dw 0                    ;get current data
        dw      0

DC1InitDone db  0

DOSCALL2Not db  0                       ; 0 = need to load
                                        ; 1 = not present, skip load

pbDOSCALL2Name db "DOSCALL2",0

hDummyMTE dw    0

pbEmulatorName db "NPXEMLTR",0

pfnBaseInit dd  0
pbFPEMHandler db "NPXNPHandler",0
pbFPEMDataSize db "NPXFPDataSize",0
lFPEMHandler dd 0
lFPEMDataSize dd 0

SHRDATA ENDS

DATA    SEGMENT

        ALIGN   4

        PUBLIC  FenceLAddr
FenceLAddr dd   ?

        PUBLIC  FenceShrLAddr
FenceShrLAddr dd ?

        PUBLIC  FencePckLAddr
FencePckLAddr dd ?

        PUBLIC  FenceSel
FenceSel dw     ?

        PUBLIC  FenceShrSel
FenceShrSel dw  ?

        PUBLIC  FencePckSel
FencePckSel dw  ?

DATA    ENDS

CODE16_TUNE1 SEGMENT DWORD USE16 PUBLIC 'CODE'
CODE16_TUNE1 ENDS


CODE16_TUNE1 SEGMENT

        ASSUME  cs:CODE16_TUNE1, ds:NOTHING, es:NOTHING, ss:NOTHING

;**     InitDOSCALL1    - initialization routine for the DOSCALL1 library
;
;       This routine will get executed whenever a link is made to the
;       DOSCALL1 library.
;
;       It peforms the following initialization functions:
;
;               1) Get the global and local InfoSegs.
;               2) Get the DBCS table.
;               3) If emulating floating point, load the emulator
;
;       ENTRY:
;               NONE
;
;       EXIT:
;               globalIS = global InfoSeg selector
;               localIS = local InfoSeg selector
;
;       USES:
;               flags
;

procedure InitDOSCALL1, FAR

        SaveReg <ds,bx>

        mov     ax,SHRDATA
        mov     ds,ax
        ASSUME  ds:SHRDATA

        xor     ax,ax

                                        ; load the NPX emulator DLL if no coprocessor

        smsw    bx
        test    bx,CR0_EM
        jz      idc10

        push    ax
        push    ax
        push    ax
        push    ds                      ; SHRDATA
        push    offset SHRDATA:pbEmulatorName
        push    ds
        push    offset SHRDATA:hDummyMTE
        call    DOSLOADMODULE
        or      ax,ax                   ; DOSLOADMODULE failed?
        jnz     idc40                   ; yes, return exit with error


idc10:                                  ; load and init DOSCALL2 if needed

        cmp     DOSCALL2Not,al
        jnz     idc11

        push    ax
        push    ax
        push    ax
        push    ds
        push    offset SHRDATA:pbDOSCALL2Name
        push    ds
        push    offset SHRDATA:hDummyMTE
        call    DOSLOADMODULE

        or      ax,ax                   ; no error - continue
        jz      short idc11

        cmp     ax,2                    ; error other than not found - abort
        jnz     idc40

        inc     DOSCALL2Not             ; not found so never try to load again

idc11:  cmp     DC1InitDone,0           ; global init done?
        jne     idc20                   ; no, skip global init          ;MDLL

        call    NLS_Init                ; Initialize NLS
        or      ax,ax
        jz      idc40

        call    MSGINIT                 ; Initialize MSG
        or      ax,ax
        jz      idc40

        call    _DYNAINIT               ; Initialize QUECALLS           ;MDLL
        or      ax,ax                   ;MDLL
        jz      idc40                   ;MDLL

        call    SMGGLOBALINIT           ; Initialize SESMGR             ;MDLL
        or      ax,ax                   ;MDLL
        jz      idc40                   ;MDLL

        push    ds
        push    offset ds:globalIS      ; ds:ax -> globalIS
        push    ds
        push    offset ds:localIS       ; ds:ax -> localIS
        call    DOSGETINFOSEG

ifdef   MMIOPH
        mov     ax, globalIS
        push    es                      ; _globptr resides SHRDATA,
        push    DATA                    ;    declared in QUECALLS\SUB3Q.C
        pop     es
        ASSUME  es:DATA
        mov     es:[_globptr].Segmt,ax  ; setup pointer to global infoseg
        mov     es:[_globptr].Offst,0   ; for MMIO hooks
        pop     es
        ASSUME  es:NOTHING
endif


                                        ; Get DBCS info also

        push    dbcs_data_size          ; size of buffer
        push    SHRDATA                 ; address of input data
        push    offset SHRDATA:input_dbcs_data
        push    SHRDATA                 ; address of buffer
        push    offset SHRDATA:dbcs_data
        mov     DC1InitDone,1
        call    DOSGETDBCSEV            ; Get dbcs info

                                        ; Set the fence variables for the local info segment.

idc20:  push    es
        push    fs

        mov     es,ds:[localIS]         ; ax = local info segment
        ASSUME  es:NOTHING

        mov     ax,DATA
        mov     fs,ax
        ASSUME  fs:DATA

        .386p

        mov     ax,es:[LIS_PackSel]
        mov     fs:[FenceSel],ax
        shr     ax,3
        shl     eax,16
        mov     fs:[FenceLAddr],eax

        mov     ax,es:[LIS_PackShrSel]  ; KDH - get PackShrSel.
        mov     fs:[FenceShrSel],ax
        shr     ax,3
        shl     eax,16                  ; that is packed.
        mov     fs:[FenceShrLAddr],eax

        mov     ax,es:[LIS_PackPckSel]
        mov     fs:[FencePckSel],ax
        shr     ax,3                    ; FencePckLAddr is just above the
        shl     eax,16                  ; highest address that is packed.
        mov     fs:[FencePckLAddr],eax

        .286p

        pop     fs
        pop     es

;MDLL   call    _MonInstanceInit        ; Remove MONCALLS from DOSCALL1
;MDLL   or      ax,ax                   ;   to improve process init
;MDLL   jz      idc40                   ;   performance

        call    OS2BASEINIT             ;MDLL
        or      ax,ax                   ;MDLL
        jz      idc40                   ;MDLL

idc30:  mov     ax,1                    ; return init worked ok

idc50:  RestoreReg <bx,ds>
        ret

idc40:  xor     ax,ax                   ; return error init failed
        jmp     short idc50



InitDOSCALL1 ENDP

CODE16_TUNE1 ENDS

END
