;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; 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    58,132
        TITLE   IDHMAIN.Asm -- Install Device Handler
;/*****************************************************************************
;*
;* SOURCE FILE NAME = IDHMAIN.ASM
;*
;* DESCRIPTIVE NAME = BVS Device Handler for Installation
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  This module is the control point for the Generic Device
;*              handler used by Installation and Initialization.
;*
;* FUNCTIONS    DEVENABLE
;*              InitEnv
;*              SaveRestEnv
;*              GetConfig
;*              RegSave
;*              RegRest
;*              _PhysToUVirt
;*              _FreePhysToUVirt
;*              GetScrHandle
;*              ExamineConfig
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*   01/11/89  @T10       P3464   TPL, Use NULL input parameter for
;*                                free PVB IOCTL,
;*   01/16/89  @@A        P2986   STJ, Add enhanced GetConfig support
;*   03/07/89  @@S3       P3532   STJ, Use the new SCREEN IOCTL,
;*   03/13/89             D184    STJ, Identify additional displays for 8514/A
;*   03/25/89  @P1        D203    TPL, DCR 203 changes
;*   04/10/89             D198    STJ, Install BvsPrtSc and BvsWrtTTY as
;*                                default VDH routines
;*   05/09/89  @BB7       B702184 WKB, Restructure config data structure,
;*   05/22/89  @T30       D511    TPL, DCR 511 changes
;*   05/19/89  @T51       432.10  TPL, 2.0 UNIQUE, Removal of 3xbox code for 2.0
;*   07/14/89  @S17       B704811 STJ, Change PhystoUVirt from FAR to NEAR
;*   07/15/89  @T39       B784056 TPL, Remove hardware dependencies in VDHINIT
;*   07/24/89  @S20       B705116 STJ, 8514/A configs fixed,
;*   08/18/89  @S25       B706860 STJ, Use 1.0 length as default for GetXXXX
;*                                calls,
;*   11/30/89             D811    MS,  2.0 UNIQUE - DCR 811
;*   01/24/90  @T52       D704    TPL, 2.0 UNIQUE - DCR 704 work
;*   07/23/90  @T71       D1293   TPL, DCR 1293 - Support P70 device on Family 1 machines
;*   07/23/90  @T72       D1295   TPL, DCR 1295 - Support recognition of XGA device
;*   09/20/90             B716255 TPL, Return XGA present for Kauai-HS
;*   07/18/91             B724243 WKB, Correctly identify the Compaq plasma
;*                                display (CGA)
;*   04/09/93  @RAD         60272 YEE, Add global variable for machine type
;****************************************************************************/

        PUBLIC  __acrtused              ;@T39
__acrtused equ  1                       ;C compiler work around         ;@T39

        INCLUDE idhequ.inc              ;Install Device Handler Equates
        INCLUDE bvsparms.inc            ;BVS Parameter Equates
        INCLUDE error2.inc              ;CP/DOS Error Codes
        INCLUDE infoseg.inc             ;DOS Info Seg
        .xlist
        INCLUDE struc.inc               ;Structured Macros
        .list

        extrn   BUFFERUPDATE:FAR        ;Text Buffer Update
        extrn   GetCursorInfo:FAR       ;Get Cursor Info
        extrn   SetCursorInfo:FAR       ;Set Cursor Info
        extrn   GetMode:FAR             ;Get Mode
        extrn   SetMode:FAR             ;Set Mode
        extrn   GetCurPos:FAR           ;Get Physical Cursor Position
        extrn   SetCurPos:FAR           ;Set Physical Cursor Position
        extrn   GetVarInfo:FAR          ;Get Variable Information ;@@A
        extrn   SetVarInfo:FAR          ;Set Variable Information ;@@A
        extrn   SetCurType:FAR          ;Set Physical Cursor Shape ;@@A
        extrn   GetDBCSInfo:FAR         ;Get DBCS Display Info          ;@P1
        extrn   GetLVBInfo:FAR          ;Get LVB size Info              ;@P1
        extrn   _getVideoType:NEAR      ;Get video adapter type         ;@T39
        extrn   GetCodePage:NEAR        ;Get Prepare Code Page ;@@A
        extrn   GetState:FAR            ;Get video date                 ;D811
        extrn   SetState:FAR            ;Set video state                ;D811

        extrn   DOSOPEN:FAR             ;Open a file or device
        extrn   DOSDEVIOCTL:FAR         ;Send a request to a device
        extrn   BVHINSTANCE:WORD        ;BVH instance data              ;@T52

IDHGSEG SEGMENT WORD PUBLIC 'DATA'      ;Global data segment for IDH    ;@T52

        idhglobal <>                    ;Global data segment for IDH

_VideoHardware VHardware <>             ; video hardware configuration  ;@T39
        public  _VideoHardware          ;@T39

ProtoEnv idhenvironment <>              ;Prototype environment block

Config  configdata <,cf_a_cga,cf_d_color,1000h,,,,size idhenvironment,0FA0h,0FA0h,-8+size configdata,-4+size configdata,1,cf_af_cga,1,cf_df_color> ;@@A @BB7
        public  Config                  ;@@A

_hScreenDD dd   BVHINSTANCE             ;Screen DD Handle               ;@T52
        public  _hScreenDD                                              ;@T52
_pDMQSdata dd   0                       ;pointer to DMQS data           ;@ISO
        public  _pDMQSdata                                              ;@ISO
_machinetype dw   0                     ;family type indicator          ;@RAD
        public  _machinetype                                            ;@RAD
Scratch dw      0                       ;Scratch Area                   ;@T52


;/*
;** Table of addresses of IDH functions
;*/


        public  FnTable
FnTable dd      BufferUpdate            ;Text Buffer Update
        dd      InitEnv                 ;Initialize Environment
        dd      SaveRestEnv             ;Save Environment
        dd      SaveRestEnv             ;Restore Environment
        dd      GetConfig               ;Return Config Info
        dd      GetDBCSInfo             ;Get DBCS Display Info          ;@P1
        dd      0                       ;Get Color Lookup Table         ;D198
        dd      0                       ;Set Color Lookup Table         ;D198
        dd      GetCursorInfo           ;Get Cursor Info
        dd      SetCursorInfo           ;Set Cursor Info
        dd      0                       ;Get Font                       ;D198
        dd      0                       ;Set Font                       ;D198
        dd      GetMode                 ;Get Mode
        dd      SetMode                 ;Set Mode
        dd      0                       ;Get Palette Registers          ;D198
        dd      0                       ;Set Palette Registers          ;D198
        dd      0                       ;Get Phys Buf                   ;D198
        dd      0                       ;Free Phys Buf                  ;D198
        dd      GetVarInfo              ;Get Variable Info              ;@@A
        dd      SetVarInfo              ;Set Variable Info              ;@@A
        dd      0                       ;Extended VIO Call              ;D198
        dd      0                       ;Print Screen                   ;D198
        dd      0                       ;Write TTY                      ;D198
        dd      GetLVBInfo              ;Get LVB Info Call              ;@P1
        dd      GetState                ;get video state                ;D811
        dd      SetState                ;set video state                ;D811

IDHGSEG ENDS

R2CSEG  SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:R2CSEG

;/****************************************************************************
;*
;*  SUBROUTINE NAME: DevEnable
;*
;*  DESCRIPTIVE NAME: Initialize call vector table
;*
;*  FUNCTION: DevEnable is called via the Presentation Manager DDI
;*            interface.  The entry points of all VDH routines are
;*            appropriately entered into the call vector table.
;*            In addition, display adapter configuration is verified.
;*
;*  ENTRY POINT: DevEnable
;*    LINKAGE:   CALL FAR
;*
;*  INPUT: (Passed on stack)
;*             FAR * Parameter2  ( far pointer to parameter 2 packet )
;*                      FAR *Flags
;*                      FAR *CallVectorTable (BVS's call table)
;*             FAR * Parameter1  ( far pointer to parameter 1 packet )
;*                      ULONG EngineVersion ( Graphics engine ver. )
;*                      ULONG TableSize ( Length of call table )
;*             ULONG Subfunction ( Enable subfunction )
;*         (Referenced)
;*             VDHEntryPoint[] (global data - table of entry points )
;*             HugeShift (global data - huge shift value)
;*             hScreenDD (global data - screen device driver handle)
;*
;*  EXIT-NORMAL: AX = 0
;*               Entries in VDHEntryPoint table are copied to
;*                  CallVectorTable
;*
;*  EXIT-ERROR: AX = ERROR_VIO_BAD_ADAPTER or
;*                   DosGetHugeShift error or
;*                   DosOpen error
;*
;*  EFFECTS: Huge shift value is saved in HugeShift
;*           Screen device driver handle is saved in hScreenDD
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: RegSave, RegRest
;*
;****************************************************************************/

;/*
;**  ASSUMPTION: DevEnable is called every time a VDH is loaded
;*/

DEVENABLE PROC  FAR
        public  DEVENABLE
        Call    RegSave

        mov     ax,-1                   ;PMERR_DEV_FUNC_NOT_INSTALLED ;Preset error
        .if     <<word ptr [bp].stk_function> eq 1>
            mov     ax,ERROR_VIO_INTERNAL_RESOURCE
            .if     <[si+4] ae fn_NextAvail> ;Table large enough for this VDH

                push    IDHGSEG
                pop     ds
                .if     <[bx].idh_ioport eq bx> ;This is first call by System

                    mov     si,offset FnTable ;DS:SI = local table
                    les     di,dword ptr es:[di+4] ;Get Call Table Addr
                    add     di,4*fn_BufferUpdate ;ES:DI = target table
                    mov     cx,fn_NextAvail-fn_BufferUpdate ;# of entries ;D198
                    .repeat             ;D198
                        .if     <<word ptr [si+2]> ne bx> ;Supported ;D198
                            movsw       ;D198
                            movsw       ;Copy addr to table ;D198
                        .else           ;D198
                            add     si,4 ;D198
                            add     di,4 ;Skip this entry ;D198
                        .endif          ;D198
                    .loop               ;D198

                    Call    ExamineConfig ;Get video configuration ;@@A
                    mov     si,offset ProtoEnv ;@@A
                    mov     ax,[bx].idh_fontsize ;Get size of character box ;@@A
                    dec     ax          ;@@A
                    mov     [si].env_endline,ax ;@@A
                    dec     ax          ;@@A
                    mov     [si].env_startline,ax ;Set default cursor shape ;@@A

                .endif
                sub     ax,ax
            .endif
        .endif

        Call    RegRest
        ret     12
DEVENABLE ENDP

;/****************************************************************************
;*
;*  SUBROUTINE NAME: InitEnv
;*
;*  DESCRIPTIVE NAME: Initialize environment
;*
;*  FUNCTION: InitEnv is called by BVS to initialize the video
;*            environment during the creation of a new session.  This
;*            includes initializing the adapter hardware and/or the
;*            environment buffer.
;*
;*  ENTRY POINT: InitEnv
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 257 )
;*
;*  INPUT: (Passed on stack)
;*             FAR *Environment ( Environment buffer for the session )
;*             FAR *ParmBlock
;*                     USHORT Length = length of this packet
;*                     USHORT Flags  = 0 - Environment buffer only
;*                                     1 - Hardware also
;*             ULONG Function ( Call vector table entry = 257 )
;*         (Referenced)
;*             Modes[] (global data - table of supported video modes )
;*
;*  EXIT-NORMAL: AX = 0
;*               Environment buffer is initialized
;*
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS
;*
;*  EFFECTS: If requested, display adapter hardware is initialized to
;*           highest resolution mode supported.
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;****************************************************************************/

InitEnv PROC    FAR
        public  InitEnv
        Call    RegSave

        push    IDHGSEG
        pop     ds
        mov     si,offset ProtoEnv
        mov     cx,size idhenvironment
        rep     movsb                   ;Copy prototype enviroment
        sub     ax,ax

        Call    RegRest
        ret     12
InitEnv ENDP

;/****************************************************************************
;*
;*  SUBROUTINE NAME: SaveRestEnv
;*
;*  DESCRIPTIVE NAME: Save/Restore Environment
;*
;*  FUNCTION: SaveEnv is called by BVS prior to a screen switch
;*            in order to preserve the display adapter hardware state
;*            and/or the full or partial display buffer.
;*
;*  ENTRY POINT: SaveEnv
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 258 )
;*
;*  FUNCTION: RestoreEnv is called by BVS following a screen switch
;*            in order to restore the display adapter hardware state
;*            and/or the full or partial display buffer.
;*
;*  ENTRY POINT: RestoreEnv
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 259 )
;*
;*  INPUT: (Passed on stack)
;*             FAR *Environment ( Environment buffer for the session )
;*             FAR *ParmBlock
;*                     USHORT Length = length of this packet
;*                     USHORT Flags  = 2 - Hardware state
;*                                     4 - Full display buffer
;*                                     8 - Partial display buffer
;*                                    10 - 3xBox being saved
;*                     USHORT PVBHugeSEL = 1st huge selector for PVB
;*             ULONG Function ( Call vector table entry = 258 )
;*
;*  EXIT-NORMAL: AX = 0
;*               Hardware state and/or display buffer is saved in
;*                 environment buffer
;*
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS
;*
;*  EFFECTS: No special processing is done for the 3xBox
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: RegSave, RegRest, SetCurPos
;*
;****************************************************************************/

SaveRestEnv PROC FAR
        public  SaveRestEnv
        Call    RegSave

        mov     ax,fn_BufferUpdate
        xchg    word ptr [bp].stk_function,ax ;Get old/Set new function

        .if     <ax eq fn_SaveEnv>

            mov     cx,sx_ReadCellStr   ;Set the subroutine index

        .else

            Call    SetCurPos           ;Set cursor location from Environment
            Call    SetCurType          ;Set cursor shape from Environment ;@@A
            mov     cx,sx_WriteCellStr  ;Set the subroutine index

        .endif

        mov     ax,[si].vp_sr_lvbsel    ;Get the LVB selector

        mov     [si].vp_parmlength,26   ;Set parameter list length
        mov     [si].vp_flags,vp_f_physical
        mov     [si].vp_index,cx        ;Set the subroutine index

        mov     [si].vp_lvbsel,ax       ;Set the LVB address            ;@P1
        mov     [si].vp_offset,bx
        mov     [si].vp_selector,ax     ;Set the string address

        mov     [si].vp_startrow,bx
        mov     [si].vp_startcol,bx     ;Set the row and column

        mov     ax,word ptr es:[di].env_bufsize
        mov     [si].vp_repeatlength,ax ;Setup the length

        Call    RegRest
        jmp     BufferUpdate            ;Continue with Buffer Save/Restore
SaveRestEnv ENDP

;/****************************************************************************
;*
;*  SUBROUTINE NAME: GetConfig
;*
;*  DESCRIPTIVE NAME: Return video adapter configuration information
;*
;*  FUNCTION: GetConfig is called by BVS to identify the current
;*            display adapter.
;*
;*  ENTRY POINT: RetConfigInfo
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 260 )
;*
;*  INPUT: (Passed on stack)
;*             FAR *Environment ( Environment buffer for the session )
;*             FAR *ParmBlock
;*                     USHORT Length = length of this packet
;*                     USHORT Flags  = 0 ( reserved )
;*                     FAR *ConfigData = VioGetConfig structure
;*             ULONG Function ( Call vector table entry = 260 )
;*         (Referenced)
;*             MemorySize (global data - amount of video memory)
;*
;*  EXIT-NORMAL: AX = 0
;*               Configuration data is returned to caller
;*
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS
;*
;*  EFFECTS: NONE
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;****************************************************************************/

GetConfig PROC  FAR
        public  GetConfig
        Call    RegSave

        mov     ax,ERROR_VIO_INVALID_LENGTH
        .if     <[si].vp_parmlength eq 8> and
        les     di,dword ptr [si].vp_offset ;Get address of config data
        push    IDHGSEG
        pop     ds

        mov     si,offset Config        ;Get offset of config data

        ; If _VideoHardware.display previously initialized in   ;B724243
        ; another routine (such as DetectOEM) then reflect that ;B724243
        ; update in the config data.                            ;B724243

        assume  ds:IDHGSEG                                      ;B724243
        mov     cx, WORD PTR _VideoHardware.display             ;B724243
        .if     <cx ne 0>                                       ;B724243
            mov     WORD PTR ds:Config+cf_display, cx           ;B724243
        .endif                                                  ;B724243

        mov     cx,es:[di].cf_length    ;Get length of config data

        .if     <cx a 1>

            mov     ax,cx
            .if     <al a <size configdata>> ;@S25
                mov     al,cf_confignum ;@S25
            .endif                      ;@S25

            push    di
            sub     al,size cf_length
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_adapter
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_display
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_memory
            .if     <ns>
                movsw
                movsw
            .endif

            sub     al,size cf_confignum
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_version
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_flags
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_envsize
            .if     <ns>
                movsw
                movsw
            .endif

            sub     al,size cf_fullsize
            .if     <ns>
                movsw
                movsw
            .endif

            sub     al,size cf_partsize
            .if     <ns>
                movsw
                movsw
            .endif

            sub     al,size cf_adapteroff
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_displayoff
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_emadapters
            .if     <ns>
                movsw
            .endif

            sub     al,size cf_emdisplays
            .if     <ns>
                movsw
            .endif

            mov     ax,di
            pop     di
            sub     ax,di
            .if     <al a 2>            ;More than just a length request
                stosw                   ;Update length in Mode data
            .endif

            sub     ax,ax               ;Set good return code
        .endif

        Call    RegRest
        ret     12
GetConfig ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = RegSave/RegRest
;*
;* DESCRIPTION   = Save and Restore all registers and flags for VDH routines.
;*                 RegSave also sets BX=0, DS:SI=ParmBlock, and ES:DI=EnvBlock
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

RegSave PROC    NEAR                    ;Routine to save regs
        public  RegSave

        pop     ax                      ;Get return address
        pushf
        pusha
        push    ds
        push    es                      ;Save all registers and flags
        cld
        mov     bp,sp
        push    ax                      ;Restore return address

        sub     bx,bx                   ;Get zero reg for code optimization
        lds     si,[bp].stk_parmblock   ;DS:SI = Parameter Block
        les     di,[bp].stk_envblock    ;ES:DI = Environment Block

        ret
RegSave ENDP

RegRest PROC    NEAR                    ;Routine to restore regs
        public  RegRest

        mov     [bp].stk_regax,ax       ;Save return code
        pop     ax
        xchg    [bp].stk_flags,ax       ;Swap return address w/flags
        push    ax

        popf
        pop     es
        pop     ds
        popa                            ;Restore all registers and flags

        ret
RegRest ENDP

;/****************************************************************************
;*
;*  SUBROUTINE NAME: PhysToUVirt
;*
;*  DESCRIPTIVE NAME: Allocate an LDT sel:off to physical memory
;*
;*  FUNCTION: PhysToUVirt is called by routines who need access to
;*            either the physical display buffer, or the ROM font.
;*            This routine calls the screen device driver (SCREEN$)
;*            via DosDevIOCtl who, in turn, issues a
;*            DevHlp_PhysToUVirt call.
;*
;*  ENTRY POINT: PhysToUVirt
;*    LINKAGE:   CALL FAR
;*
;*  INPUT: (Passed on stack)
;*             FAR *PhysicalAddress ( Physical address )
;*             FAR *LDTSelector     ( Place to return LDT sel:off )
;*             USHORT Length        ( Size of physical memory area )
;*
;*  EXIT-NORMAL: AX = 0
;*               LDT sel:off is returned to caller
;*
;*  EXIT-ERROR: AX = DosDevIOCtl error
;*
;*  EFFECTS: NONE
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: DosDevIOCtl
;*
;****************************************************************************/

_PhysToUVirt PROC NEAR                  ;@S17
        public  _PhysToUVirt

        pushf
        pusha
        push    ds
        push    es                      ;Save all registers and flags
        cld
        mov     bp,sp                   ;Equivalent to RegSave

        Call    GetScrHandle            ;Get current screen dd handle
        .if     <zero ax>

            mov     ax,word ptr [bp].stk_envblock-2 ;Length of PVB ;@S17
            les     di,[bp].stk_parmblock-2 ;Where to put selector ;@S17
            mov     word ptr [bp].stk_parmblock-2,ax ;Overlay the stack parms ;@S17

            push    es
            push    di                  ;Push selector/offset of PVB area
            push    ss
            lea     ax,[bp].stk_function-2 ;@S17
            push    ax                  ;Push ptr to phys sel/off and length
            push    75h                 ;Push function = Allocate       ;@T30
            push    03h                 ;Push category = Video
            push    dx                  ;Push device handle
            Call    DOSDEVIOCTL         ;Get selector/offset of PVB

        .endif
        Call    RegRest
        ret
_PhysToUVirt ENDP

;/****************************************************************************
;*
;*  SUBROUTINE NAME: FreePhysToUVirt
;*
;*  DESCRIPTIVE NAME: Deallocate an LDT selector to physical memory
;*
;*  FUNCTION: FreePhysToUVirt is called by routines who are done
;*            accessing the memory allocated by PhysToUVirt.  This is
;*            done by calling the screen device driver (SCREEN$) via
;*            DosDevIOCtl who, in turn, issues a DevHlp_PhysToUVirt.
;*
;*  ENTRY POINT: FreePhysToUVirt
;*    LINKAGE:   CALL FAR
;*
;*  INPUT: (Passed on stack)
;*             USHORT LDTSelector  ( LDT selector to be deallocated )
;*
;*  EXIT-NORMAL: LDT selector is deallocated
;*
;*  EFFECTS: NONE
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: DosDevIOCtl
;*
;****************************************************************************/

_FreePhysToUVirt PROC NEAR
        public  _FreePhysToUVirt

        pushf
        pusha
        push    ds
        push    es                      ;Save all registers and flags
        cld
        mov     bp,sp                   ;Equivalent to RegSave

        Call    GetScrHandle            ;Get current screen dd handle
        .if     <zero ax>

            push    ax                  ;                               @T10
            push    ax                  ;Push dummy ptr to PVB ptr      @T10
            push    ss
            lea     di,[bp].stk_function-2 ;@S17
            push    di                  ;Push ptr to sel. to deallocate ;@T39
            push    71h                 ;Push function = Deallocate
            push    03h                 ;Push category = Video
            push    dx                  ;Push device handle
            Call    DOSDEVIOCTL         ;Delete selector/offset of PVB
            .if     <zero ax>           ;@T39
                mov     dx,word ptr ss:[di] ;Get deallocated sel.   ;@T39
                .if     <[bp] eq dx>    ;ES selector saved?     ;@T39
                    mov     [bp],ax     ;Clear it               ;@T39
                .endif                  ;                       ;@T39
                .if     <[bp+2] eq dx>  ;DS selector saved?     ;@T39
                    mov     [bp+2],ax   ;Clear it               ;@T39
                .endif                  ;                       ;@T39
            .endif                      ;@T39
        .endif
        Call    RegRest
        ret
_FreePhysToUVirt ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = GetScrHandle
;*
;* DESCRIPTION   = Get Screen Device Driver handle in DX
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

GetScrHandle PROC NEAR
        PUBLIC  GetScrHandle

        push    ds                                                      ;@T52
        push    bx                                                      ;@T52
        mov     ax,IDHGSEG                                              ;@T52
        mov     es,ax
        lds     bx,es:_hScreenDD                                        ;@T52
        sub     ax,ax
        mov     dx,ds:[bx]              ;@T39                           ;@T52
        .if     <zero dx>
            push    es                                                  ;@T52
            push    idh_scr             ;Device name ASCIIZ string
            push    ds                                                  ;@T52
            push    bx                  ;Return for device handle  ;@T39,@T52
            push    es
            push    offset Scratch      ;Action Taken
            push    dx
            push    dx                  ;File Size
            push    dx                  ;File Attribute
            push    00001h              ;Open Flag
            push    000C2h              ;Open Mode
            push    dx
            push    dx                  ;Reserved (0:0)
            Call    DOSOPEN
            mov     dx,ds:[bx]          ;@T39                           ;@T52
        .endif
        pop     bx                                                      ;@T52
        pop     ds                                                      ;@T52

        ret
GetScrHandle ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = ExamineConfig
;*
;* DESCRIPTION   = Identify the video configuration and set the config data.
;*
;* INPUT         = DS = IDHGSEG
;* OUTPUT        = ax, cx, di, si destroyed
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

ExamineConfig PROC NEAR                 ;@@A
        public  ExamineConfig           ;@@A
        assume  ds:IDHGSEG              ;@T39

        call    _getVideoType           ; get video configuration       ;@T39
        mov     ax, _VideoHardware.fVideoType ;@T39

        sub     bx,bx                   ;@T39
        mov     [bx].idh_ioport,3D4h    ;Preset the Color port
        mov     di,offset ProtoEnv      ;Get offset of prototype env.   ;@T39
        mov     si,offset Config        ;Get offset of config data      ;@T39

;/*
;** use monochrome only if it's all that is available
;*/

        .if     <ax eq MPA_BIT> or      ; MPA Mono found?               ;@T39
        .if     <ax eq EGM_BIT>         ; EGA Mono found?               ;@T39
            mov     byte ptr [bx].idh_ioport,0B4h ;Use Mono port
            mov     byte ptr [bx].idh_fontsize,14 ;14-pel font

            mov     word ptr [di].env_gcols,720
            mov     word ptr [di].env_grows,350

            mov     [si].cf_adapter,cf_a_mpa ;Indicate Mono card ;@S20
            mov     [si].cf_emadapters,cf_af_mpa ;Emulate Mono card ;@S20
            mov     [si].cf_display,cf_d_mono ;Indicate Mono display
            mov     word ptr [si].cf_memory,1000h ;Indicate Mono size
            mov     [si].cf_emdisplays,cf_df_mono ;Emulate Mono display

;/*
;** EGAs emulating MPAs use different values
;*/

            test    ax, EGM_BIT
            .if     < nz >              ;EGA Mono found?
                mov     [si].cf_adapter,cf_a_ega
                mov     [si].cf_emadapters,cf_af_mpa+cf_af_ega
            .endif
        .endif

        test    ax, VGA_BITS
        .if     < nz >                  ;VGA found?
            mov     byte ptr [bx].idh_fontsize,16 ;16-pel font

            mov     [di].env_gcols,720
            mov     [di].env_grows,400

            mov     [si].cf_adapter,cf_a_vga
            mov     [si].cf_display,cf_d_vcolor ;@T39
            test    ax, VGM_BIT         ;@T39
            .if     <nz>                ;VGA with Mono display?         ;@T39
                mov     byte ptr [bx].idh_ioport,0B4h ;Use Mono port ;@S20
                mov     [si].cf_display,cf_d_vmono ;@T39
            .endif                      ;@T39
            mov     word ptr [si].cf_memory,bx
            mov     word ptr [si].cf_memory+2,4 ;Always 256K of memory
            mov     [si].cf_emadapters,cf_af_mpa+cf_af_cga+cf_af_ega+cf_af_vga
            mov     [si].cf_emdisplays,cf_df_mono+cf_df_color+cf_df_ecolor+cf_df_vmono+cf_df_vcolor+cf_df_plasma

            test    ax, VGP_BIT
            .if     <nz>                ;VGA with plaza display?
                test    ax, VGM_BIT     ;                               ;@T71
                .if     <nz>            ;P70 in Mono?                   ;@T71
                    mov     byte ptr [bx].idh_ioport,0B4h ;Use Mono port ;@S20
                .endif                                                  ;@T71
                mov     [di].env_gcols,640
                mov     [si].cf_display,cf_d_plasma
            .endif

            Call    GetCodePage

        .else   near

            test    ax, EGA_BIT OR EGC_BIT
            .if     < nz > near         ;EGA found?


;/*
;** determine configuration of EGA in color modes,
;** mono modes determined by monochrome code above
;*/


                mov     [si].cf_adapter,cf_a_ega
                mov     [si].cf_emadapters,cf_af_cga+cf_af_ega

                test    ax, EGA_BIT
                .if     < nz >          ;EGA with enhanced Color indicated
                    mov     [di].env_grows,350
                    mov     [si].cf_display,cf_d_ecolor
                    mov     [si].cf_emdisplays,cf_df_color+cf_df_ecolor
                    mov     byte ptr [bx].idh_fontsize,14 ;14-pel font
                .endif

                                        ; save memory size
                mov     cx, WORD PTR _VideoHardware.memory
                mov     word ptr [si].cf_memory,cx
                mov     cx, WORD PTR _VideoHardware.memory+2
                mov     word ptr [si].cf_memory+2,cx ;Set EGA memory

                Call    GetCodePage
            .endif
        .endif

;/*
;** if 8514 Adapter/Display present record information about it
;*/

        test    ax, A8514_BITS+XGA_BIT                                  ;B716255
        .if     < nz > NEAR             ;8514 or XGA found?             ;@T72
            test    ax, XGA_BIT         ;                               ;@T72
            .if     < nz >              ;XGA found?                     ;@T72
                mov     [si].cf_adapter,cf_a_xga                        ;@T72
                add     [si].cf_emadapters,cf_af_xga                    ;@T72
            .else                       ;8514a found                    ;@T72
                mov     [si].cf_adapter,cf_a_8514a
                add     [si].cf_emadapters,cf_af_8514a
            .endif                                                      ;@T72

            test    ax, A8514M_BIT
            .if     < nz >
                add     [si].cf_emdisplays,cf_df_8514+cf_df_8507_8604+cf_df_8515
                test    ax, XGA_BIT                                     ;@T72
                .if     < z >  OR       ;Only 8514a attached?           ;@T72
                test    ax, VGM_BIT                                     ;@T72
                .if     < nz >          ;Mono attached to VGA also?     ;@T72
                    mov     byte ptr [bx].idh_ioport,0B4h ;Use Mono port ;@S20
                    mov     [si].cf_display,cf_d_8507_8604 ;8514/A with 8507/8604
                .endif                                                  ;@T72
            .endif

            test    ax, A8514A_BIT
            .if     < nz >
                add     [si].cf_emdisplays,cf_df_8514+cf_df_8507_8604+cf_df_8515
                test    ax, XGA_BIT                                     ;@T72
                .if     < z >  OR                                       ;@T72
                test    ax, VGC_BIT                                     ;@T72
                .if     < nz >                                          ;@T72
                    mov     [si].cf_display,cf_d_8514 ;8514/A with 8514
                .endif                                                  ;@T72
            .endif

            test    ax, A8514_15_BIT
            .if     < nz >
                add     [si].cf_emdisplays,cf_df_8514+cf_df_8507_8604+cf_df_8515
                test    ax, XGA_BIT                                     ;@T72
                .if     < z >  OR                                       ;@T72
                test    ax, VGC_BIT                                     ;@T72
                .if     < nz >                                          ;@T72
                    mov     [si].cf_display,cf_d_8515 ;8514/A with 8515
                .endif                                                  ;@T72
            .endif

            test    ax, A8514_03_BIT
            .if     < nz >
                test    ax, XGA_BIT                                     ;@T72
                .if     < z >  OR       ;Only 8514a attached?           ;@T72
                test    ax, VGM_BIT                                     ;@T72
                .if     < nz >          ;Mono attached to VGA also?     ;@T72
                    mov     byte ptr [bx].idh_ioport,0B4h ;Use Mono port ;@S20
                    mov     [si].cf_display,cf_d_vmono ;8514/A with 8503
                .endif                                                  ;@T72
            .endif

            test    ax, A8514C_BIT
            .if     < nz >
                test    ax, XGA_BIT                                     ;@T72
                .if     < z >  OR                                       ;@T72
                test    ax, VGC_BIT                                     ;@T72
                .if     < nz >                                          ;@T72
                    mov     [si].cf_display,cf_d_vcolor ;8514/A with 8512/3
                .endif                                                  ;@T72
            .endif

            mov     cx, WORD PTR _VideoHardware.memory+2 ; save memory size
            mov     word ptr [si].cf_memory+2,cx
        .endif

        .if     <[bx].idh_ioport eq 3B4h> ;@S20
            mov     word ptr [di].env_bufaddr,bx ;Use Mono buffer ;@S20
            mov     word ptr [di].env_type,bx ;Use Mono mode ;@S20
        .endif                          ;@S20

        ret
ExamineConfig ENDP                      ;@@A

R2CSEG  ENDS
        END

