;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        page    ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = INIT.ASM
;*
;* DESCRIPTIVE NAME = Driver Initialization routines
;*
;*
;* VERSION      V2.0
;*
;* DATE         03/06/87
;*
;* DESCRIPTION  This file contains all the functions which are performed only at     
;*              boot time.  This includes those initialization functions which are   
;*              performed the very first time that the Enable function is called.    
;*
;*              Load procedure called once when module is loaded.                      
;*                                                                                     
;*              At 16bit driver level, register contents are:
;*                                                                                     
;*                    AX = module handle of loading "application"                      
;*                    SI = HEAPSIZE parameter                                          
;*                    DI = module handle of .DLL                                       
;*                    DS = DGROUP for module if there is one, otherwise appl's DS      
;*             
;* FUNCTIONS    Public: DisplayInit
;*                      one_time_init
;*                      get_rip_flag
;*                      DDL_initialization
;*                      ring3_VioGetConfig
;*                      ring3_VioGetMode
;*                      ring3_LoadDosNls
;*                                                    
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   03/06/87                     Hock Lee [hockl] - Created
;*   05/26/88                     Bob Grudem [bobgru]
;*                                  Now saves a copy of screen selector in
;*                                  PtrData.
;*   10/03/91                     David Kerr - use VioGetMode to determine if
;*                                  color @DAKCOL PTR SM05623
;*   02/27/89                     Data Connections - support for new fonts
;*   01/25/88                     Walt Moore [waltm] - The big rewrite
;*   04/30/88                     ronm
;*                                  Added default_vio_cpid to define the      
;*                                  meaning of zero code page ids for (A)Vio  
;*                                  presentation spaces.                      
;*   01/25/88                     Walt Moore [waltm] - Wrote one_time_init
;*   09/26/87                     Walt Moore [waltm] - Wrote DLL_initialization
;*   09/26/87                     John Colleran  [johnc]
;*                                  Created ring3_VioGetConfig
;*****************************************************************************/

        .xlist
        include cmacros.inc

INCL_DOSNLS             equ     1
INCL_FONTFILEFORMAT     equ     1
INCL_GRE_FONTS          equ     1
INCL_DEV                equ     1
INCL_VIO                equ     1
        include pmgre.inc
DINCL_VIO       equ     1
DINCL_ERROR     equ     1
DINCL_ENABLE    equ     1
        include driver.inc
        include fontseg.inc
        include assert.mac
        include njmp.mac
        .list

        ??_out  init
ifdef PP8  ; PP8 is true for 8514 only
        EXTRN    PrfQueryProfileInt:FAR
endif

        errcode <INSUFFICIENT_MEMORY,BASE_ERROR>

        externFP GetScreenSelector
        externFP GetPMDDCodeSelector
        externFP DosGetResource2        ;OS|2 functions
        externFP DosGetEnv
        externFP DosCallback
        externFP DosOpen
        externFP DosDevIOCTL
        externFP DosClose
        externFP DosGetProcAddr
        externFP VioGetConfig
        externFP DosLoadModule
        externFP Get_CP_Map
        externFP device_specific_init
        externFP device_specific_post_init

        IFNDEF CGA      ;this is required for EGA/VGA/8514 drivers only

        VDD_SUPPORT equ 1
        externFP DosOpenVDD
IFDEF   SEAMLESS
        externFP DosRequestVDD
        externFP DosCloseVDD
ENDIF   ;SEAMLESS

IFDEF   SLITE
IFDEF   VDD_SUPPORT
IFDEF   VGA
IFNDEF  DosRequestVDD
        externFP DosRequestVDD
ENDIF   ;DosRequestVDD
ENDIF   ;VGA
ENDIF   ;VDD_SUPPORT
ENDIF   ;SLITE

        ENDIF ;!CGA

sBegin  Data
        externW  selCompileData
        externW  selCompileCode
        externW  wSVGAtype
sEnd    Data

sBegin  PtrData
        externW  selScreenPtr
IFDEF   SEAMLESS
        externA reserved_latches
        externB fbShadowFlags
        externB fControllerOwned
        externB fControllerNotify
        externA shadow_size
        externB shadow_data
        externB shadowed_graf_mode
        globalB fVDMControllerMine,0
ENDIF   ;SEAMLESS

IFDEF   SLITE
IFDEF   VDD_SUPPORT
IFDEF   VGA
        externB fStarlight      ; Starlight Present/Enabled flags
ENDIF   ;VGA
ENDIF   ;VDD_SUPPORT
ENDIF   ;SLITE

sEnd    PtrData

IFDEF   SEAMLESS
sBegin  PtrCode
        externFP far_exclude
        externFP far_unexclude
        externFP init_hw_regs
sEnd    PtrCode
ENDIF   ;SEAMLESS

sBegin  InitSeg
        externNP init_heap              ;MEMMAN.ASM
        externNP init_far_heap          ;MEMMAN.ASM
sEnd

sBegin  Data
ifdef PP8   ; PP8 is true for 8514 only
        externW f8514FastSS
        externW fAltSysFont
        pAppName db 'PM_IBMBGA',0
        pKeyName db 'FASTSS',0
        pKeyNam2 db 'ALTSYSFONT',0
endif
        externW cbHeap                  ;Heap size
        externW hModule                 ;Module handle
        externD hVideoVDD
        externB fbOffScreen
        IFDEF   VDD_SUPPORT
        externB drqVideo
IFDEF   SEAMLESS
        externB semDriver

NUM_SM_ADDRESSES        EQU     4

        public  SM_WINDRV
SM_WINDRV       _SM_WINDRV      < , far_exclude, far_unexclude, init_hw_regs, semDriver, wHeartbeat, PtrDataBASE, fControllerOwned, \
                                  fControllerNotify, fbShadowFlags, fVDMControllerMine, shadowed_graf_mode.vvr_value >

        public          SM_PMDISP_ADDRESSES

SM_RING2_16BIT_CODE_MAP    EQU  SM_RING2 OR SM_CODE_ADDRESS OR SM_ADDRESS_16BIT OR SM_MAPPING
SM_RING2_16BIT_DATA_MAP    EQU  SM_RING2 OR SM_DATA_ADDRESS OR SM_ADDRESS_16BIT OR SM_MAPPING
SM_RING3_16BIT_CODE_MAP    EQU  SM_RING3 OR SM_CODE_ADDRESS OR SM_ADDRESS_16BIT OR SM_MAPPING
SM_RING2_16BIT_DATA_PASS   EQU  SM_RING2 OR SM_DATA_ADDRESS OR SM_ADDRESS_16BIT OR SM_PASSTHRU

SM_PMDISP_ADDRESSES     _SM_PMDISP_ADDRESSES < SM_RING2_16BIT_DATA_MAP, 0, 0, DataBASE >
                        _SM_PMDISP_ADDRESSES < SM_RING2_16BIT_DATA_MAP, 0, 0, PtrDataBASE >
                        _SM_PMDISP_ADDRESSES < SM_RING2_16BIT_CODE_MAP, 0, 0, PtrCodeBASE >
                        _SM_PMDISP_ADDRESSES < SM_RING2_16BIT_DATA_PASS, 0, OFFSET SM_WINDRV, DataBASE >

SM_SETSIZE              VMSSIZE <, 12h, 640, 480, 1, 1, 28h, 14h, 8>

globalW wHeartbeat,0    ;VDM Heartbeat
globalB fSeamless,0     ;Set to true if initialization of seamles windows
                        ;  was successful.
globalD hWinVDD,0       ;Handle to VWIN.SYS
externA SCREEN_CX       ;Need this to determine is we are 640x480 VGA

ENDIF   ;SEAMLESS
        ENDIF
        externD lnbTotalScreenSize

        externB adDevCapsData
        externA DEVCAPS_HORIZONTAL_RESOLUTION
        externA DEVCAPS_VERTICAL_RESOLUTION
        externD gsspScreen              ;GSS structure for screen
        externW cResource               ;Number of resources to load
        externW selDeathToUse
        externB fbRip                   ;Driver rip flag
        externB ddcInit
        externB rddcInit

        externW wAdapter                ; Display and Adapter Type
        externW wDisplay

DESPERATION_CP  equ     437             ; Used when we can't get the
                                        ; defined by DosGetCtryInfo.

        globalW default_vio_cpid,0      ; The meaning of code page zero...

        IFDEF   VDD_SUPPORT
        IFNDEF  PP8
        globalB szSQ,<'\DEV\SINGLEQ$',0>
        ENDIF
        globalB szVideoVDD,<'VVIDEO1$',0>

        globalB OemHelp,<'OEMHLP$',0>

IFDEF SEAMLESS
        globalB szWinVDD,<'VWIN',0>
ENDIF ;SEAMLESS

        ENDIF

        globalB szGetCtryInfo,<'DOSGETCTRYINFO',0>
        globalB szGetDBCSEv,<'DOSGETDBCSEV',0>

        globalD lpfnGetDBCSEv,0
sEnd    Data


ALIASPARM   STRUC
ap_len      DW  ?                       ; Length of the parm block
ap_ds       DW  ?                       ; Data selector
ALIASPARM   ENDS


sBegin  InitSeg
        assumes cs,InitSeg

globalW InitSegData,DataBASE
staticD ring3_GetConfig,ring3_VioGetConfig
staticD ring3_LoadNls,ring3_LoadDosNls

;/***************************************************************************
;*
;* FUNCTION NAME = DisplayInit()
;*
;* DESCRIPTION   = Save local heap size to be initialized later, and the     
;*                 module handle This routine is called once, when the module
;*                 is loaded.
;*
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,FLAGS
;*                 Registers Preserved:
;*                       SI,DI,ES,DS
;*
;* INPUT         = SI = size of heap 
;*                 DI = module handle
;* OUTPUT        = None
;*
;* RETURN-NORMAL = AX = 1   
;* RETURN-ERROR  = none     
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing

cProc   DisplayInit,<FAR,PUBLIC,NODATA>,<ds>
cBegin
        mov     ds,InitSegData
        assumes ds,Data

        mov     cbHeap,si               ;Save local heap size

;/*
;**  Save the module handle in all the structures which need it initialized
;*/

        mov     hModule,di

        ; set module handle into font loading info table
        mov     cx,cResource            ; get number of fonts
        lea     bx,cResource[2]         ; address start of table
@@:
        mov     fr_hModule[bx],di       ; save handle in table entry
        add     bx,size FONT_RES        ; move to next entry
        loop    @B                      ; iterate

        mov     ax,1
cEnd
page

;/***************************************************************************
;*
;* FUNCTION NAME = one_time_init
;*
;* DESCRIPTION   = This gets called ONE TIME ONLY!! on the first call to 
;*                 fill_log_dev_blk (not once per process)
;*              
;*                 All initialization code which cannot be performed at load time
;*                 (which is almost all of it thanks to there being no guarantee
;*                 of load ordering) is performed by this routine.  This routine
;*                 will be called by the Enable function when the first 
;*                 FillLogDevBlock call is received.
;*              
;*                 one_time_init does:
;*                   1. Get screen pointer into selDeathToUse, and selScreenPtr
;*                   2. Gets the codepage
;*                   ;REMOVED! 3. Inits the heap
;*                   4. Sets up padBitmapFormats, and adDevCapsData
;*                   5. COMMENTED OUT !!! Gets a CS Alias for bitblt to use.
;*                   6. Loads the font resources (sets ddc_ca.ca_fs, and each fr_pp)
;*                   7. Sets up the default pick window.
;*                   8. Tries to setup drqVideo with the VDD (sets fbOffScreen)
;*                 
;*                   Registers Destroyed:
;*                         AX,BX,CX,DX,ES,DS,FLAGS
;*                   Registers Preserved:
;*                         SI,DI,BP
;*
;*                   Calls:
;*                         get_rip_flag
;*                         init_heap
;*                         device_specific_init
;*                         device_specific_post_init
;*                         GetScreenSelector
;*                         DosGetResource2
;*                         PrfQueryProfileInt
;*                  
;* INPUT         = DS = Data 
;* OUTPUT        = None
;*
;* RETURN-NORMAL = AX = 0 
;* RETURN-ERROR  = AX <> 0                  
;*                 error has not been logged
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

cProc   one_time_init,<FAR,PUBLIC,NONWIN>,<si,di,ds>

        errnz   <ctryc_country  - ctryi_country>
        errnz   <ctryc_codepage - ctryi_codepage>

        localW  hSQ
        localW  c_returned
        localV  ctrycode,%(size COUNTRYCODE)
        localV  ctryinfo,%(size COUNTRYCODE)
        localV  aliasdata,%(size ALIASPARM)
        localV  SVGAdata,%(size SVGAstruct)

        localD  lpfnGetCtryInfo
        localW  OemHndl
;/*
;**  ctryinfo is supposed to be the leading portion of a COUNTRYINFO
;**  structure.  We assume that prefix matches the COUNTRYCODE structure.
;*/

cBegin
ifdef PP8 ; PP8 is true only for the 8514

;/*
;**  Initialization of f8514FastSS (see DATA.ASM) - this enables FastScreenSwitch
;**  on an 8514. 0=disable, 1=enable.
;*/

        xor     ax,ax
        dec     ax
        push    ax            ; 0xFFFFFFFF for HINI_USER
        push    ax
        inc     ax            ; ax assumed to be 0 in about 10 lines ...
        lea     cx,pAppName
        push    ds            ; far pointer to app name
        push    cx
        lea     cx,pKeyName
        push    ds            ; far pointer to key name
        push    cx
        push    ax            ; default of 0
        call    PrfQueryProfileInt  ; Will return a 0 as the normal case - if
        and     ax,1                ; anyone knows about this hook they can
        dec     ax                  ; add an entry in the .INI file to return
        mov     f8514FastSS,ax      ; 1 instead to enable FSS. No other values
                                    ; are allowed. f8514FastSS is set to 0 or
                                    ; -1 for faster code later.

;/*
;**  initialisation of fAltSysFont - 0 is normal font, 1 is alternate font
;**  see comments in DATA.ASM
;*/
        xor     ax,ax
        dec     ax
        push    ax            ; 0xFFFFFFFF for HINI_USER
        push    ax
        inc     ax            ; ax assumed 0 in about 10 lines
        lea     cx,pAppName
        push    ds            ; far pointer to app name
        push    cx
        lea     cx,pKeyNam2
        push    ds            ; far pointer to key name
        push    cx
        push    ax            ; default of 0
        call    PrfQueryProfileInt  ; Will return a 0 as the normal case - use
        and     ax,1                ; this hook to flip system fonts 8515/8514
        mov     fAltSysFont,ax

endif
        save    <ds>
        cCall   DosCallback,<ring3_LoadNls>
        or      ax,ax
        jz      oti_nls_loaded
        jmp     oti_exit

oti_nls_loaded:
        mov     ax,InstanceDataBASE
        mov     es,ax
        mov     es:hModDosNls,dx

;/*
;**  Get DosGetCtryInfo proc address
;*/

        lea     ax,szGetCtryInfo
        farPtr  lpszGetCtryInfo,ds,ax
        lea     bx,lpfnGetCtryInfo
        farPtr  lppfnGetCtryInfo,ss,bx
        save    <es>
        cCall   DosGetProcAddr,<es:hModDosNls,lpszGetCtryInfo,lppfnGetCtryInfo>
        or      ax,ax
        jz      @F
        jmp     oti_exit

;/*
;**  Get DosGetDBCSEv proc address
;*/

@@:     lea     ax,szGetDBCSEv
        farPtr  lpszGetDBCSEv,ds,ax
        lea     bx,lpfnGetDBCSEv
        farPtr  lppfnGetDBCSEv,ds,bx
        cCall   DosGetProcAddr,<es:hModDosNls,lpszGetDBCSEv,lppfnGetDBCSEv>
        or      ax,ax
        jz      oti_got_proc_addr
        jmp     oti_exit

oti_got_proc_addr:
        xor     ax,ax
        mov     ctrycode.ctryc_country,ax
        mov     ctrycode.ctryc_codepage,ax
        lea     ax,ctrycode
        lea     bx,ctryinfo
        lea     cx,c_returned
        mov     dx,size COUNTRYCODE

        regPtr  fp_country_code_arg,ss,ax
        regPtr  fp_country_info_result,ss,bx
        regPtr  fp_c_returned,ss,cx

        arg     dx
        arg     fp_country_code_arg
        arg     fp_country_info_result
        arg     fp_c_returned

        cCall   lpfnGetCtryInfo

        mov     ax,ctryinfo.ctryi_codepage
        mov     default_vio_cpid,ax

        call    get_rip_flag
        call    init_heap
        mov     ax,PMERR_INSUFFICIENT_MEMORY
        jcxz    oti_exit_relay

        call    init_far_heap
        mov     ax,PMERR_INSUFFICIENT_MEMORY
        jcxz    oti_exit_relay

;/*
;**  If no code page to glyph map exists for the given code page,
;**  we convert the default to the base hardware code page (437).
;*/

        cCall   Get_CP_Map,<default_vio_cpid>
        or      ax,ax
        jnz     cp_map_available

        mov     ax,DESPERATION_CP
        mov     default_vio_cpid,ax


cp_map_available:

        call    device_specific_init
        jcxz    oti_exit_relay

;/*
;**  If the driver needs a screen selector, get a global one
;*/

        cmp     gsspScreen.gssp_size,size GSSP
        jne     have_screen_sel
        farPtr  pTemp,ds,<DataOFFSET gsspScreen>
        cCall   GetScreenSelector,<pTemp>
        mov     selDeathToUse,ax
        or      ax,ax
        jnz     have_screen_sel
        rip     text,<Getting the screen selector failed>
        mov     ax,PMERR_BASE_ERROR     ;!!! error code for BX???
        jmp     short oti_exit_relay

oti_resource_load_error:
        rip     text,<DosGetResource2 returned an error>
        xchg    ax,bx                   ; error in BX
        mov     ax,PMERR_BASE_ERROR
oti_exit_relay:
        jmp     oti_exit

;/*
;**  Store a copy of the screen selector in the pointer data segment.
;*/

have_screen_sel:
        push    ds
        mov     si,PtrDataBASE
        mov     ds,si
        assumes ds,PtrData
        mov     selScreenPtr,ax
        pop     ds
        assumes ds,Data

;/*
;**  Get a CS Alias selector for the CompileData Data segment (from pmdd.sys)
;*/

        farPtr  pSel,ds,<DataOFFSET selCompileData>
        cCall   GetPMDDCodeSelector,<pSel>
        or      ax,ax
        jnz     have_alias_sel
        mov     ax,PMERR_BASE_ERROR     ;!!! error code for BX???
        jmp     short oti_exit_relay

have_alias_sel:
        mov     selCompileCode,ax

;/*
;**  Loop through all the font resources which need to be loaded and
;**  load them.
;*/

        cld
        mov     si,DataOFFSET cResource
        lodsw                           ;Get count of resources to load
        xchg    ax,cx
        njcxz   resources_loaded
resource_load_loop:
        les     bx,[si].fr_pp
        farPtr  pselTemp,<es>,<bx>
        arg     ([si].fr_hModule)
        arg     ([si].fr_usType)
        arg     ([si].fr_usId)
        arg     pselTemp
        cCall   DosGetResource2
ifdef   FIREWALLS
        les     bx,[si].fr_pp
        assert  [bx].lo,E,0             ; Currently Fonts must be seg aligned
endif   ;FIREWALLS
        or      ax,ax
        jnz     oti_resource_load_error
        add     si,size FONT_RES
        loop    resource_load_loop

        mov     si,DataOFFSET cResource
        add     si,2                    ; get past count
        les     bx,[si].fr_pp
        mov     dx,es:[bx].hi           ;--> where selector goes
        mov     bx,DataOFFSET ddcInit

;/*
;**  Now reach into the font and pull out lots of good information so we
;**  can set a bunch of different CA_ flags.
;*/

        access  ax,dx                   ;Make sure we can access font
        mov     es,dx
        assumes es,FontSeg
        xor     ax,ax
        test    fsMetrics.foca_fsTypeFlags,FM_TYPE_64K
        njnz    oti_resource_load_error
        or      cx,CA_VECTOR
        test    fsMetrics.foca_fsDefn,FM_DEFN_OUTLINE
        jne     @F              ;!!! test for raster instead of vector
        and     cx,not CA_VECTOR        ;It is raster
@@:
        cmp     fsDef.fdCellWidth,8
        jne     @F
        or      cx,CA_WIDTH_IS_8
@@:
        test    fsMetrics.foca_fsTypeFlags,FM_FIXED_PITCH
        jz      @F
        or      cx,CA_FIXED_PITCH
@@:
        cmp     fsDef.fdh_fsChardef,FONTDEFCHAR3
        jne     compute_pick
        or      cx,CA_ABC_SPACE

compute_pick:
        mov     [bx].ddc_ca.ca_fs,cx    ; save flags

;/*
;**  Set up the default pick window.
;**  cW = ((cH * HorzRes) + VertRes/2) / VertRes
;*/

        mov     ax,DEVCAPS_HORIZONTAL_RESOLUTION
        mov     dx,adDevCapsData[CAPS_GRAPHICS_CHAR_HEIGHT*SIZE_DWORD].lo
        mul     dx
        mov     cx,DEVCAPS_VERTICAL_RESOLUTION
        shr     cx,1
        add     ax,cx
        adc     dx,0
        mov     cx,DEVCAPS_VERTICAL_RESOLUTION
        div     cx
        shr     ax,1                    ; width /2
        cwd
        mov     bx,DataOFFSET rddcInit
        mov     [bx].rddc_rclPick.rcl_xRight.lo,ax
        mov     [bx].rddc_rclPick.rcl_xRight.hi,dx
        neg     ax
        cwd
        mov     [bx].rddc_rclPick.rcl_xLeft.lo,ax
        mov     [bx].rddc_rclPick.rcl_xLeft.hi,dx

;/*
;**  cH = cH
;*/

        mov     ax,adDevCapsData[CAPS_GRAPHICS_CHAR_HEIGHT*SIZE_DWORD].lo
        shr     ax,1                    ; width /2
        cwd
        mov     [bx].rddc_rclPick.rcl_yTop.lo,ax
        mov     [bx].rddc_rclPick.rcl_yTop.hi,dx
        neg     ax
        cwd
        mov     [bx].rddc_rclPick.rcl_yBottom.lo,ax
        mov     [bx].rddc_rclPick.rcl_yBottom.hi,dx

resources_loaded:
        save    <ds>                    ;trashed by upward ring transition
        cCall   DosCallback,<ring3_GetConfig>
        mov     wAdapter,bx
        mov     wDisplay,cx
        mov     lnbTotalScreenSize.lo,ax
        mov     lnbTotalScreenSize.hi,dx

IFDEF VGA       ;Dont even bother with CGA, EGA or 8514

;/*
;**        get super VGA adapter type
;*/

        push    ax                      ;Allocate space for wAction
        mov     cx,sp
        push    ds                      ;lpDevice -> device name string
        push    DataOFFSET OemHelp
        push    ss                      ;pass -> handle return value
        lea     ax,OemHndl
        push    ax
        push    ss                      ;SS:CX -> wAction return value
        push    cx
        xor     ax,ax
        push    ax                      ;filesize (zero)
        push    ax
        push    ax                      ;file attribute (zero)
        push    1                       ;open flag (open existing file)
        push    0000000011000010b       ;open mode
        push    ax                      ;reserved
        push    ax                      ;reserved
        call    DosOpen
        pop     cx                      ;ignore wAction field
        or      ax,ax


        push    ss
        lea     ax,SVGAdata
        push    ax

        push    0
        push    0
        push    08h
        push    80h
        push    OemHndl
        call    DosDevIOCTL

        mov     ax,SVGAdata
        mov     wSVGAtype,ax

        push    OemHndl
        call    DosClose

endif ;VGA

        IFDEF   VDD_SUPPORT             ;this is required for EGA/VGA/8514 drivers only
        farPtr  phvdd,ds,<DataOFFSET hVideoVDD>
        farPtr  pszvdd,ds,<DataOFFSET szVideoVDD>
        cCall   DosOpenVDD,<pszvdd,phvdd>
        or      ax,ax                   ;was Video VDD loaded?
IFDEF   SEAMLESS
        njnz    no_vdd                  ;no
ELSE
        jnz     no_vdd                  ;no
ENDIF   ;SEAMLESS

        IFNDEF  PP8
        push    ax                      ;Allocate space for wAction
        mov     cx,sp
        push    ds                      ;lpDevice -> device name string
        push    DataOFFSET szSQ
        push    ss                      ;pass -> handle return value
        lea     ax,hSQ
        push    ax
        push    ss                      ;SS:CX -> wAction return value
        push    cx
        xor     ax,ax
        push    ax                      ;filesize (zero)
        push    ax
        push    ax                      ;file attribute (zero)
        push    1                       ;open flag (open existing file)
        push    0000000011000000b       ;open mode
        push    ax                      ;reserved
        push    ax                      ;reserved
        call    DosOpen
        pop     cx                      ;ignore wAction field
        or      ax,ax

IFDEF   SEAMLESS
        njnz    no_vdd                  ;if error on DosOpen, can't use VDD
ELSE
        jnz     no_vdd                  ;if error on DosOpen, can't use VDD
ENDIF   ;SEAMLESS

        mov     aliasdata.ap_len,SIZE ALIASPARM
        mov     aliasdata.ap_ds,PtrDataBASE
        push    0
        push    0
        push    ss
        lea     ax,aliasdata
        push    ax
        push    71h
        push    03h
        push    hSQ
        call    DosDevIOCTL
        or      ax,ax
IFDEF   SEAMLESS
        njnz    no_vdd_close            ;if error on DosDevIOCTL, can't use VDD
ELSE
        jnz     no_vdd_close            ;if error on DosDevIOCTL, can't use VDD
ENDIF   ;SEAMLESS

        mov     ax,aliasdata.ap_ds      ;get ring 0 alias
        ELSE
        sub     ax,ax
        ENDIF   ;!PP8

        mov     drqVideo.vvd_pfbShadowFlags.sel,ax
        mov     drqVideo.vvd_pfControllerOwned.sel,ax
        mov     drqVideo.vvd_pfControllerNotify.sel,ax
        mov     drqVideo.vvd_pShadowData.sel,ax

        or      fbOffScreen,OFFSCR_VDD  ;we can use the VDD now

IFDEF   SEAMLESS
        mov     ax,SCREEN_CX            ;Only allow seamless to work on the
        cmp     ax,640                  ;  standard 640x480 VGA mode for now
        je      @f
        jmp     seamless_exit
@@:
        farPtr  phvdd,ds,<DataOFFSET hWinVDD>
        farPtr  pszvdd,ds,<DataOFFSET szWinVDD>
        cCall   DosOpenVDD,<pszvdd,phvdd>
        or      ax,ax                   ;was Win VDD loaded?
        jz      sm_found_vwin           ;yes

        IFDEF   FIREWALLS
        color_puts      WHITE,BLUE,<   PMVGA: Could not open VWIN.>
        ENDIF   ;FIREWALLS
        jmp     seamless_exit           ;Can't find VWIN

sm_found_vwin:
        IFDEF   FIREWALLS
        color_puts      BLUE,BLACK,<   PMVGA: Opened VWIN successfully.>
        ENDIF   ;FIREWALLS

CPUMode 386
        xor     eax,eax
        lea     bx,SM_PMDISP_ADDRESSES.ulLength

        mov     cx,DataBASE

;/*
;**  VWIN only needs access to the fixed part of the data segment, if
;**  the data segment grows above 4K, this value must be increased.
;*/

        mov     eax, 1000h
;       lsl     ax,cx
        mov     dword ptr [bx],eax      ;Store the actual length of the segment in the structure passed to VWIN
        add     bx,SIZE _SM_PMDISP_ADDRESSES

        mov     cx,PtrDataBASE
        lsl     ax,cx
        mov     dword ptr [bx],eax      ;Store the actual length of the segment in the structure passed to VWIN
        add     bx,SIZE _SM_PMDISP_ADDRESSES

        mov     cx,PtrCodeBASE
        lsl     ax,cx
        mov     dword ptr [bx],eax      ;Store the actual length of the segment in the structure passed to VWIN
CPUMode 286

        sub     dx,dx
        farPtr  hvdd,hWinVDD.hi,hWinVDD.lo
        farPtr  cbInput,dx,NUM_SM_ADDRESSES
        farPtr  pInput,ds,<DataOFFSET SM_PMDISP_ADDRESSES>
        farPtr  cbOutput,dx,dx
        farPtr  pOutput,dx,dx
        cCall   DosRequestVDD,<hvdd,dx,VWIN_INIT,cbInput,pInput,cbOutput,pOutput>
        or      ax,ax                   ;was call to Win VDD successfull?
        jz      @f                      ;yes

        IFDEF   FIREWALLS
        color_puts      WHITE,BLUE,<   PMVGA: Send init packet to VWIN failed.>
        ENDIF   ;FIREWALLS

        farPtr  phvdd,ds,<DataOFFSET hWinVDD>
        cCall   DosCloseVDD,<phvdd>
        jmp     short   seamless_exit
@@:
        sub     dx,dx
        farPtr  hvdd,hWinVDD.hi,hWinVDD.lo
        farPtr  cbInput,dx,%(size SM_SETSIZE)
        farPtr  pInput,ds,<DataOFFSET SM_SETSIZE>
        farPtr  cbOutput,dx,dx
        farPtr  pOutput,dx,dx
        cCall   DosRequestVDD,<hvdd,dx,VWIN_SETSIZE,cbInput,pInput,cbOutput,pOutput>
        or      ax,ax                   ;was call to Win VDD successfull?
        jz      seamless_ok             ;yes

        IFDEF   FIREWALLS
        color_puts      WHITE,BLUE,<   PMVGA: Send of mode info to VWIN failed.>
        ENDIF   ;FIREWALLS

        farPtr  phvdd,ds,<DataOFFSET hWinVDD>
        cCall   DosCloseVDD,<phvdd>
        jmp     short   seamless_exit

seamless_ok:
        or      fSeamless,SEAMLESS_ACTIVE       ;Make seamless active
CPUMode 386
        mov     semDriver.fsrs_Timeout,DWORD PTR SEAMLESS_TIMEOUT
CPUMode 286
        IFDEF   FIREWALLS
        color_puts      BLUE,BLACK,<   PMVGA: Initialization with VWIN successful.>
        ENDIF   ;FIREWALLS

seamless_exit:
ENDIF   ;SEAMLESS

no_vdd_close:
        IFNDEF  PP8
        push    hSQ
        call    DosClose
        ENDIF
no_vdd:
        ENDIF   ;VDD_SUPPORT

        call    device_specific_post_init

IFDEF   SLITE
IFDEF   VDD_SUPPORT
IFDEF   VGA

        test    fbOffScreen,OFFSCR_VDD          ;Are we talking to VVIDEO?
        jz      @f                              ;No, skip notification.
        push    ax
        push    es
        mov     ax,PtrDataBASE
        mov     es,ax
        assumes es,PtrData
        test    es:[fStarlight],00000001b       ;are we on a Starlight
        jz      pop_and_exit                    ;no--never mind

        mov     ax,aliasdata.ap_ds              ;get ring 0 alias
        sub     dx,dx
        farPtr  hvdd,hVideoVDD.hi,hVideoVDD.lo
        farPtr  cbInput,ax,<PtrDataOFFSET fStarlight>
        farPtr  pInput,dx,dx
        farPtr  cbOutput,dx,dx
        farPtr  pOutput,dx,dx
        cCall   DosRequestVDD,<hvdd,dx,VVDSYSREQ_SETOEMFLAG,cbInput,pInput,cbOutput,pOutput>
pop_and_exit:
        pop     es
        pop     ax
@@:

ENDIF   ;VGA
ENDIF   ;VDD_SUPPORT
ENDIF   ;SLITE

oti_exit:
cEnd
page

;/***************************************************************************
;*
;* FUNCTION NAME = get_rip_flag
;*
;* DESCRIPTION   = The environment is searched for a SVGAFLAGS entry.  If it is      
;*                 set to "R", then the rip flag will be passed to WinSetErrorInfo.  
;*                 This feature will be in both the FIREWALLed and non FIREWALLed    
;*                 version of the driver.                                            
;*
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,ES,FLAGS
;*                 Registers Preserved:
;*                       SI,DI,DS,BP
;*                  
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

abGreFlags      label   byte
        db      'GREFLAGS='
SIZE_GREFLAGS   =       $-abGreFlags    ;Size of the string in bytes

        assumes ds,Data
        assumes es,nothing

cProc   get_rip_flag,<NEAR>,<ds,si,di>
        localW  selEnv
        localW  npCmdLine
cBegin
        lea     bx,selEnv
        lea     cx,npCmdLine
        farPtr  pSel,ss,bx
        farPtr  pCmd,ss,cx
        cCall   DosGetEnv,<pSel,pCmd>
        or      ax,ax
        jnz     have_rip_flag           ;Probably no environment present yet
        cld
        xor     al,al                   ;NULLS are handy
        xor     di,di
        mov     es,selEnv               ;ES:DI -->environemnt
        assumes es,nothing

match_next_string:
        mov     si,InitSegOFFSET abGreFlags
        mov     cx,SIZE_GREFLAGS
        repe    cmps byte ptr cs:[si],byte ptr es:[di]
        jne     goto_next_string

;/*
;**  We want to make the test of the flags are a word test to make sure that
;**  we match only on the flag value, not a somehting like "RI".
;*/

        cmp     es:[di],GREFLAGS_RIP
        je      set_rip_flag
        cmp     es:[di],GREFLAGS_RIP_LC
        jne     have_rip_flag
set_rip_flag:
        mov     fbRip,DDF_RIP_ERROR     ;Non-zero to show rip
        jmp     short have_rip_flag

goto_next_string:
        cmp     es:[di][-1],al          ;Have we found a null char?
        jz      done_this_string        ;  Yes
        mov     cx,0FFFFh
        repne   scasb                   ;Find first null

done_this_string:
        cmp     es:[di][0],al           ;End of environment strings?
        jne     match_next_string       ;  No, search next

have_rip_flag:

cEnd

sEnd    InitSeg

sBegin InstanceData
globalW hModDosNls,0
sEnd   InstanceData

sBegin Ring3Data
globalB szDosNls,<'NLS',0>
sEnd   Ring3Data

sBegin  Ring3Code
        assumes cs,Ring3Code

;/***************************************************************************
;*
;* FUNCTION NAME = DLL_initialization
;*
;* DESCRIPTION   = This stub invokes the actual display driver initialization
;*                 code.  It must reside at ring 3 since there is a     in
;*                 OS/2 which currently doesn't allow a DLL's initialization 
;*                 procedure to reside at ring 2. We could put all our       
;*                 initialization code at ring 3, but then our Data segment  
;*                 would also have to be at ring 3, which we really don't    
;*                 want.
;*                 
;*                 Registers Destroyed:
;*                       Per DisplayInit
;*                 Registers Preserved:
;*                       Per DisplayInit
;*                 Calls:
;*                       Per DisplayInit
;*
;* INPUT         = SI = size of heap  
                   DI = module handle 
;* OUTPUT        = None
;*
;* RETURN-NORMAL = Per DisplayInit 
;* RETURN-ERROR  = Per DisplayInit 
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

cProc   DDL_initialization,<FAR,PUBLIC,NODATA,NONWIN>

cBegin
        cCall   DisplayInit
cEnd

;/***************************************************************************
;*
;* FUNCTION NAME = ring3_VioGetConfig 
;*
;* DESCRIPTION   = Calls Vio32GetConfig at ring 3.
;*                
;*                 Registers Preserved:
;*                       SI,DI,BP,DS
;*                 Registers Destroyed:
;*                       AX,BX,CX,FLAGS
;*                 Calls:
;*                       VioGetConfig
;*
;* INPUT         = es:bx = initialized pvioin 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = BX = Display type                  
;*                 CX = Adapter type
;*                 DX:AX = display adapter memory size
;* RETURN-ERROR  = AX = Vio error return code 
;*
;**************************************************************************/

cProc   ring3_VioGetConfig,<FAR,PUBLIC,NODATA>
        localV  vioin,%(size VIOCONFIGINFO)
cBegin
        mov     vioin.vioin_cb,size VIOCONFIGINFO
        lea     bx,vioin
        farPtr  pvioin,ss,bx
        cCall   VioGetConfig,<0,pvioin,0>
        assert  ax,E,0
        mov     bx,vioin.vioin_adapter
        mov     cx,vioin.vioin_display
        mov     ax,vioin.vioin_cbMemory.lo
        mov     dx,vioin.vioin_cbMemory.hi
        IFNDEF  PP8
        shr     dx,1
        rcr     ax,1
        shr     dx,1
        rcr     ax,1                    ;DX:AX == display adapter memory size
        ENDIF
cEnd


;/***************************************************************************
;*
;* FUNCTION NAME = ring3_LoadDosNls
;*
;* DESCRIPTION   = ring3_LoadDosNls makes the actual calls to DosLoadModule   
;*                 for NLS.DLL
;*                 
;*                 Registers Preserved:
;*                       SI,DI,BP,DS
;*                 Registers Destroyed:
;*                       AX,BX,CX,FLAGS
;*
;*                 Calls:
;*                       DosLoadModule
;*
;* INPUT         = None
;* OUTPUT        = None
;*
;* RETURN-NORMAL = AX = 0          
;*                 DX = mod handle
;* RETURN-ERROR  = AX = Dos error return code 
;*
;**************************************************************************/

cProc   ring3_LoadDosNls,<FAR,PUBLIC,NODATA>
        localW  hMod
cBegin
        farPtr  lpszObjName,0,0
        farPtr  lpModName,Ring3DataBASE,<Ring3DataOFFSET szDosNls>
        lea     ax,hMod
        regPtr  lphMod,ss,ax
        cCall   DosLoadModule,<lpszObjName,0,lpModName,lphMod>
        mov     dx,hMod
cEnd

sEnd    Ring3Code

end     DDL_initialization
