;*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   IDHINFO.Asm -- Windowable Device Handler Info Routines
;/*****************************************************************************
;*
;* SOURCE FILE NAME = IDHINFO.Asm
;*
;* DESCRIPTIVE NAME = Install Device Handler - Cursor/Variable Info  
;*
;*
;* VERSION      V2.0
;*
;* DATE         
;*
;* DESCRIPTION  Windowable Device Handler Info Routines 
;*              This source file contains VDH entry points for setting
;*              and getting cursor and variable information.
;*
;* FUNCTIONS    GetState 
;*              SetState 
;*              GetCurPos 
;*              SetCurPos 
;*              SetCurType 
;*              CopyFont 
;*              FixVGABug 
;*              GetCursorInfo 
;*              SetCursorInfo 
;*              GetVarInfo 
;*              SetVarInfo 
;*              GetCodePage 
;*              RandomRead 
;*              GetDBCSInfo 
;*              GetLVBInfo  
;*
;* NOTES        NONE
;*             
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES   RegSave, RegRest           
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*   01/12/89  @@A        P2986   STJ, Enhance Cursor and Codepage support,    
;*   03/06/89  @@S1       B700065 STJ, Enhance flag checking for GetXXXInfo         
;*                                calls
;*   03/25/89  @P1        D132    TPL, DCR 132 changes
;*   05/22/89  @T30       D511    TPL, DCR 511 changes
;*   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,                   
;*   11/30/89  D811       D811    MS,  DCR 811
;*   01/24/90  @T52       D704    TPL, DCR 704 work
;*   05/15/90  @TL8       B711846 TPL, GetCursorInfo fix,                      
;*****************************************************************************/

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

        INCLUDE cdib.inc                          ;CodePage Data Info Block ;@@A
        INCLUDE fontfile.inc                      ;Font File structures ;@@A

        EXTRN   DOSALLOCSEG:FAR                   ;Dos Allocate Segment routine ;@@A
        EXTRN   DOSGETSHRSEG:FAR                  ;Dos Get Shared Segment routine ;@@A
        EXTRN   DOSFREESEG:FAR                    ;Dos Free Segment routine ;@@A

        EXTRN   DOSOPEN:FAR                       ;Dos Open routine ;@@A
        EXTRN   DOSREAD:FAR                       ;Dos Read routine ;@@A
        EXTRN   DOSCHGFILEPTR:FAR                 ;Dos Change File Ptr routine ;@@A
        EXTRN   DOSCLOSE:FAR                      ;Dos Close routine ;@@A

        extrn   _PhysToUVirt:NEAR                 ;@@A;@S17
        extrn   _FreePhysToUVirt:NEAR             ;@@A;@S17

        extrn   RegSave:NEAR
        extrn   RegRest:NEAR

        extrn   Config:WORD                       ;@@A

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

R2SEG   SEGMENT BYTE PUBLIC 'CODE'      ;IOPL Segment
        ASSUME  CS:R2SEG

;/****************************************************************************
;*                                                    
;*  SUBROUTINE NAME: GetState                         
;*                                                    
;*  DESCRIPTIVE NAME:  Get the requested video state    
;*                                                    
;*  FUNCTION:                                         
;*                                                    
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 280 )  
;*                                                  
;*  INPUT: (Passed on stack)                          
;*             FAR *Environment ( Environment buffer for the session )  
;*             FAR *ParmBlock                         
;*             ULONG Function ( Call vector table entry = 280 )  
;*                                                    
;*  EXIT-NORMAL: If OEM defines this function then    
;*                 AX = 0                             
;*                 user defined information is returned   
;*               Else                                 
;*                 AX = ERROR_VIO_INVALID_PARMS    
;*                                                    
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS        
;*                                                  
;*  EFFECTS:  None                                    
;*                                                    
;*  INTERNAL REFERENCES:                              
;*    ROUTINES: None                                  
;*                                                    
;*  EXTERNAL REFERENCES:                              
;*    ROUTINES:  None                                 
;*                                                    
;****************************************************************************/

Public   GetState                                     ;D811
GetState Proc Far                                     ;D811
         mov ax, ERROR_VIO_INVALID_PARMS              ;D811
         ret 12                                       ;D811
GetState EndP                                         ;D811

;/****************************************************************************
;*                                                    
;*  SUBROUTINE NAME: SetState                         
;*                                                  
;*  DESCRIPTIVE NAME:  Set the requested video state    
;*                                                    
;*  FUNCTION:                                         
;*                                                    
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 280 )  
;*                                                    
;*  INPUT: (Passed on stack)                          
;*             FAR *Environment ( Environment buffer for the session )  
;*             FAR *ParmBlock                         
;*             ULONG Function ( Call vector table entry = 281 )  
;*                                                    
;*  EXIT-NORMAL: If OEM defines this function then    
;*                 AX = 0                           
;*                 user defined information is set    
;*               Else                                 
;*                 AX = ERROR_VIO_INVALID_PARMS    
;*                                                    
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS        
;*                                                    
;*  EFFECTS:                                          
;*                                                    
;*  INTERNAL REFERENCES:                              
;*    ROUTINES: NONE                                  
;*                                                    
;*  EXTERNAL REFERENCES:                              
;*    ROUTINES:                                     
;*                                                    
;****************************************************************************/

Public   SetState                                     ;D811
SetState Proc Far                                     ;D811
         mov ax, ERROR_VIO_INVALID_PARMS              ;D811
         ret 12                                       ;D811
SetState EndP                                         ;D811

;/****************************************************************************
;*
;* FUNCTION NAME = GetCurPos
;*
;* DESCRIPTION   = 
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

GetCurPos PROC  FAR
        public  GetCurPos

        push    ds
        push    IDHGSEG
        pop     ds
        mov     dx,[bx].idh_ioport               ;Base address for video ;@@A
        pop     ds

        mov     al,hp_cursoraddrh
        out     dx,al
        inc     dl
        in      al,dx
        mov     ah,al                             ;Get high byte of cursor address

        dec     dl
        mov     al,hp_cursoraddrl
        out     dx,al
        inc     dl
        in      al,dx                             ;Get low byte of cursor address

        sub     dx,dx
        div     es:[di].env_cols

        .if     <ax b es:[di].env_rows> and
        .if     <dx b es:[di].env_cols> ;Values are in valid range
            mov     es:[di].env_row,ax           ;Update number of rows
            mov     es:[di].env_col,dx           ;Update number of columns
        .endif

        ret
GetCurPos ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = SetCurPos
;*
;* DESCRIPTION   = 
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

SetCurPos PROC  FAR
        public  SetCurPos

        mov     ax,es:[di].env_cols              ;Number of columns
        mul     es:[di].env_row
        add     ax,es:[di].env_col
        mov     cx,ax                             ;Get cursor address in CX

        push    ds
        push    IDHGSEG
        pop     ds
        mov     dx,[bx].idh_ioport               ;Base address for video ;@@A
        pop     ds

        mov     al,hp_cursoraddrh
        mov     ah,ch
        out     dx,ax                             ;Set high byte of cursor address

        mov     al,hp_cursoraddrl
        mov     ah,cl
        out     dx,ax                             ;Set low byte of cursor address

        ret
SetCurPos ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = SetCurType
;*
;* DESCRIPTION   = 
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

SetCurType PROC FAR                               ;@@A
        public  SetCurType

        push    ds
        push    IDHGSEG
        pop     ds
        mov     dx,[bx].idh_ioport               ;Base address for video
        mov     al,byte ptr ds:Config+cf_adapter
        mov     ah,byte ptr [bx].idh_fontsize ;AH/AL = Fontsize/Adapter
        pop     ds

        mov     cl,byte ptr es:[di].env_startline
        mov     ch,byte ptr es:[di].env_endline

        .if     <es:[di].env_attr eq -1> ;Attribute = Hidden
            mov     cl,0FFh                       ;Turn off cursor
        .endif
        .if     <al eq cf_a_ega>                 ;EGA quirks
            .if     <ch ne cl>                    ;if top ne bot
                inc     ch
            .endif
            .if     <ch ae ah> and               ;Bottom of char box
            and     cl,cl
            .if     <nonzero cl>                 ;top not equal to zero
                sub     ch,ch                     ;Wrap to top of char box
            .endif
        .endif

        mov     al,hp_cursorstart
        mov     ah,cl
        out     dx,ax                             ;Starting line of cursor

        mov     al,hp_cursorend
        mov     ah,ch
        out     dx,ax                             ;Ending line of cursor

        ret
SetCurType ENDP                                   ;@@A

;/*
;**  Copy the font from the work buffer to the video font buffer.
;*/

CopyFont PROC   FAR                               ;@@A
        public  CopyFont

;/*
;**  Map the video font buffer at A0000h
;*/

        mov     dx,03C4h                          ;=03C4h
        mov     ax,0100h                          ;Set synch reset
        cli                                       ;Disable interrupts
        out     dx,ax                             ;Write to reg pair

        mov     dl,0CEh                           ;=03CEh
        mov     ax,0204h
        out     dx,ax                             ;Read Map Select register

        mov     ax,0005h
        out     dx,ax                             ;Graphics Mode register

        mov     ax,0406h
        out     dx,ax                             ;Graphics Misc register

        mov     dl,0C4h                           ;=03C4h
        mov     ax,0402h                          ;write font to bp only bi plane 0
        out     dx,ax                             ;Write Map Select

        mov     ax,0404h
        out     dx,ax                             ;Turn on odd/even

        Call    FixVGABug

        mov     ax,0300h                          ;Turn off synchronous reset
        out     dx,ax                             ;Write data to reset register
        sti

;/*
;**  Copy the font from the work buffer to the video font buffer
;*/

        push    ds
        mov     dx,[bx].idh_fontsize
        mov     ds,[bx].idh_selector              ;Get the work buffer selector

        sub     si,si
        sub     di,di                             ;Get the font buffer ptr in ES:DI

        mov     ax,256                            ;For all 256 characters
        .repeat
            mov     cx,dx
            rep     movsb                         ;Refresh one character of the font
            add     di,32
            sub     di,dx
            dec     ax
        .until  z

        pop     ds

;/*
;**  Restore the original video buffer
;*/

        mov     cx,0A06h                          ;Setup mono buffer with chaining
        .if     <[bx].idh_ioport eq 03D4h>
            mov     cx,0E06h                      ;Setup color buffer with chaining
        .endif

        mov     dx,03C4h                          ;=03C4h
        mov     ax,0100h                          ;Set synch reset
        cli                                       ;Disable interrupts
        out     dx,ax                             ;Write to reg pair

        mov     dl,0CEh                           ;=03CEh
        mov     ax,0004h
        out     dx,ax                             ;Read Map Select register

        mov     ax,1005h
        out     dx,ax                             ;Graphics Mode register

        mov     ax,cx
        out     dx,ax                             ;Graphics Misc register

        mov     dl,0C4h
        mov     ax,0302h
        out     dx,ax                             ;Write Map Select

        mov     ax,0004h
        out     dx,ax                             ;Turn off odd/even

        Call    FixVGABug

        mov     ax,0300h                          ;Turn off synchronous reset
        out     dx,ax                             ;Write data to reset register
        sti

        ret
CopyFont ENDP                                     ;@@A

;/****************************************************************************
;*
;* FUNCTION NAME = FixVGABug
;*
;* DESCRIPTION   = 
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

FixVGABug PROC  NEAR                              ;@@A
        mov     ax,ds:Config+cf_adapter
        .if     <al eq cf_a_vga> or
        .if     <al eq cf_a_8514a>                ;if this is a VGA
            push    dx
            mov     ax,013Fh                      ;Set full instead of half cycles
            mov     dx,[bx].idh_ioport
            out     dx,ax
            pop     dx
        .endif
        ret
FixVGABug ENDP                                    ;@@A

R2SEG   ENDS

R2CSEG  SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:R2CSEG

;/****************************************************************************
;*                                                   
;*  SUBROUTINE NAME: GetCursorInfo                  
;*                                                   
;*  DESCRIPTIVE NAME: Get cursor position and/or cursor type  
;*                                                   
;*  FUNCTION: GetCursorInfo is called by BVS to return selected 
;*            information about either the cursor position or the 
;*            cursor type.  If the request specifies hardware and the 
;*            hardware is readable, the actual hardware setting will 
;*            be read and returned.  Otherwise the returned
;*            information will be taken from the environment buffer, 
;*            if it has been passed.                
;*                                                   
;*  ENTRY POINT: GetCursorInfo                      
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 265 ) 
;*                                                   
;*  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  
;*                     USHORT Row                 
;*                     USHORT Column                
;*                     USHORT TopScanLine          
;*                     USHORT BottomScanLine       
;*                     USHORT Width                 
;*                     USHORT Attribute            
;*             ULONG Function ( Call vector table entry = 265 ) 
;*                                                   
;*  EXIT-NORMAL: AX = 0                              
;*               Cursor information is returned.   
;*                                                   
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS       
;*                                                   
;*  EFFECTS: If hardware specified and hardware is readable, the
;*           environment buffer is updated, if passed.   
;*                                                   
;*  INTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;*  EXTERNAL REFERENCES:                             
;*    ROUTINES: RegSave, RegRest, SecureSema4, ReleaseSema4  
;*                                                   
;****************************************************************************/

GetCursorInfo PROC FAR
        public  GetCursorInfo
        Call    RegSave

        mov     ax,ERROR_VIO_INVALID_LENGTH
        .if     <[si].vp_parmlength ae vp_c_attr+2> or ;@@S1
        .if     <[si].vp_parmlength ae vp_c_col+2> and ;@@S1
        test    [si].vp_flags,vp_f_curtype ;@@S1
        .if     <z>                               ;@@S1

            test    [si].vp_flags,vp_f_curpos ;@@S1
            .if     <nz>                          ;@@S1
                test    [si].vp_flags,vp_f_physical
                .if     <nz>
                    Call    GetCurPos            ;Read the hardware
                .endif

                mov     ax,es:[di].env_row
                mov     [si].vp_c_row,ax
                mov     ax,es:[di].env_col
                mov     [si].vp_c_col,ax
            .endif                                ;@@S1

            test    [si].vp_flags,vp_f_curtype ;@@S1;@TL8
            .if     <nz>                          ;@@S1
                mov     ax,es:[di].env_startline
                mov     [si].vp_c_startline,ax
                mov     ax,es:[di].env_endline
                mov     [si].vp_c_endline,ax
                mov     ax,es:[di].env_width
                mov     [si].vp_c_width,ax
                mov     ax,es:[di].env_attr
                mov     [si].vp_c_attr,ax
            .endif                                ;@@S1

            sub     ax,ax                         ;Set good return code
        .endif

        Call    RegRest
        ret     12
GetCursorInfo ENDP

;/****************************************************************************
;*                                                   
;*  SUBROUTINE NAME: SetCursorInfo                  
;*                                                   
;*  DESCRIPTIVE NAME: Set cursor position and/or cursor type  
;*                                                   
;*  FUNCTION: SetCursorInfo is called by BVS to set selected  
;*            information about either the cursor position or the 
;*            cursor type.  If the request specifies hardware, the 
;*            hardware and the environment buffer, if passed, will be 
;*            updated.  Otherwise just the environment buffer, if 
;*            passed, will be updated.             
;*                                                   
;*  NOTES: This routine puts the PS cursor fields in synch with BVS. 
;*         then advises the Engine of the changes.  Note that the 
;*         PS cursor references the bottom left, rather than top left. 
;*                                                   
;*  ENTRY POINT: SetCursorInfo                    
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 266 ) 
;*                                                   
;*  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  
;*                     USHORT Row                   
;*                     USHORT Column                
;*                     USHORT TopScanLine          
;*                     USHORT BottomScanLine       
;*                     USHORT Width               
;*                     USHORT Attribute            
;*             ULONG Function ( Call vector table entry = 266 ) 
;*                                                   
;*  EXIT-NORMAL: AX = 0                              
;*               Cursor information is set         
;*                                                   
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS       
;*                                                   
;*  INTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;*  EXTERNAL REFERENCES:                             
;*    ROUTINES: RegSave, RegRest, SecureSema4, ReleaseSema4, GreEntry
;*                                                   
;****************************************************************************/

SetCursorInfo PROC FAR
        public  SetCursorInfo
        Call    RegSave

        mov     ax,ERROR_VIO_INVALID_LENGTH
        .if     <[si].vp_parmlength ae vp_c_attr+2> or ;@@S1
        .if     <[si].vp_parmlength ae vp_c_col+2> and near ;@@S1
        test    [si].vp_flags,vp_f_curtype ;@@S1
        .if     <z> near                          ;@@S1

            test    [si].vp_flags,vp_f_curpos
            .if     <nz>                          ;Cursor position update
                mov     ax,[si].vp_c_row
                mov     es:[di].env_row,ax
                mov     ax,[si].vp_c_col
                mov     es:[di].env_col,ax

                test    [si].vp_flags,vp_f_physical
                .if     <nz>
                    Call    SetCurPos            ;Update the hardware
                .endif
            .endif

            test    [si].vp_flags,vp_f_curtype
            .if     <nz>                          ;Cursor type update
                mov     ax,ERROR_VIO_INVALID_PARMS
                push    ds
                push    IDHGSEG
                pop     ds
                mov     ax,[bx].idh_fontsize
                pop     ds
                test    [si].vp_c_width,NOT 1
                .if     <z> and
                .if     <[si].vp_c_startline b ax> AND
                .if     <[si].vp_c_endline be 31>
                    mov     ax,[si].vp_c_startline
                    mov     es:[di].env_startline,ax
                    mov     ax,[si].vp_c_endline
                    mov     es:[di].env_endline,ax
                    mov     ax,[si].vp_c_width
                    mov     es:[di].env_width,ax
                    mov     ax,[si].vp_c_attr
                    mov     es:[di].env_attr,ax

                    Call    SetCurType
                    sub     ax,ax
                .endif
            .endif

            sub     ax,ax                         ;Set good return code
        .endif

        Call    RegRest
        ret     12
SetCursorInfo ENDP

;/****************************************************************************
;*                                                   
;*  SUBROUTINE NAME: GetVarInfo                     
;*                                                   
;*  DESCRIPTIVE NAME: Get selected variable information  
;*                                                   
;*  FUNCTION: GetVariableInfo is called by BVS to return selected 
;*            information about video state - blink versus background 
;*            intensity, overscan color, underscore scan line, video 
;*            enable, 8514/A display mask, and the current codepage. 
;*                                                 
;*  NOTES: Since only the codepage is actually returned for  
;*         Windowable sessions, the semaphore is not taken to  
;*         read only one word from the PSCB.       
;*                                                   
;*  ENTRY POINT: GetVarInfo                          
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 269 ) 
;*                                                   
;*  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  
;*                     USHORT Blink                 
;*                     USHORT Overscan             
;*                     USHORT Underscore           
;*                     USHORT VideoEnable          
;*                     ULONG  DisplayMask          
;*             ULONG Function ( Call vector table entry = 269 ) 
;*                                                   
;*  EXIT-NORMAL: AX = 0                              
;*               Selected variable information is returned  
;*                                                   
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS       
;*                   ERROR_VIO_INVALID_LENGTH      
;*                                                   
;*  EFFECTS: If hardware specified and hardware is readable, the 
;*           environment buffer is updated, if passed.   
;*                                                   
;*  INTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;*  EXTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;****************************************************************************/

GetVarInfo PROC FAR                               ;@@A
        public  GetVarInfo
        Call    RegSave

        mov     ax,ERROR_VIO_INVALID_PARMS
        test    [si].vp_flags,NOT (vp_f_physical+vp_f_codepage+vp_f_scrlrect+vp_f_scrndim) ;@@S1
        .if     <z> and
        mov     ax,ERROR_VIO_INVALID_LENGTH
        .if     <[si].vp_parmlength ae vp_scrncols+2>                   ;@P1

            mov     [si].vp_blink,bx             ;Blink state
            mov     [si].vp_border,bx            ;Border color
            mov     [si].vp_underscore,bx ;Underscore line
            mov     [si].vp_dispmask1,bx ;Display mask (bits 0-15)
            mov     [si].vp_dispmask2,bx ;Display mask (bits 16-31)

            mov     ax,es:[di].env_scrlleft                             ;@P1
            mov     [si].vp_scrlleft,ax ;Scrollable Rectange of screen  ;@P1
            mov     ax,es:[di].env_scrltop                              ;@P1
            mov     [si].vp_scrltop,ax   ;Scrollable Rectange of screen ;@P1
            mov     ax,es:[di].env_scrlright                            ;@P1
            mov     [si].vp_scrlright,ax;Scrollable Rectange of screen  ;@P1
            mov     ax,es:[di].env_scrlbottom                           ;@P1
            mov     [si].vp_scrlbottom,ax ;Scrollable Rectange of screen;@P1
            mov     ax,es:[di].env_rows                                 ;@P1
            mov     [si].vp_scrnrows,ax ;Screen Dimensions              ;@P1
            mov     ax,es:[di].env_cols                                 ;@P1
            mov     [si].vp_scrncols,ax ;Screen Dimensions              ;@P1

            push    IDHGSEG
            pop     es
            mov     ax,es:[bx].idh_codepage
            mov     [si].vp_codepage,ax ;Codepage

            sub     ax,ax                         ;Set good return code
        .endif

        Call    RegRest
        ret     12
GetVarInfo ENDP                                   ;@@A

;/****************************************************************************
;*                                                   
;*  SUBROUTINE NAME: SetVarInfo                     
;*                                                   
;*  DESCRIPTIVE NAME: Set selected variable information  
;*                                                   
;*  FUNCTION: SetVariableInfo is called by BVS to set selected  
;*            information about video state - blink versus background 
;*            intensity, overscan color, underscore scan line, video 
;*            enable, or 8514/A display mask. If the request specifies 
;*            hardware the hardware and the environment buffer, if 
;*            passed, will be updated.  Otherwise just the environment 
;*            buffer, if passed, will be updated.   
;*                                                   
;*  ENTRY POINT: SetVarInfo                          
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 270 ) 
;*                                                   
;*  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  
;*                     USHORT Blink                 
;*                     USHORT Overscan             
;*                     USHORT Underscore           
;*                     USHORT VideoEnable          
;*                     ULONG  DisplayMask          
;*             ULONG Function ( Call vector table entry = 270 ) 
;*                                                   
;*  EXIT-NORMAL: AX = 0                              
;*               Selected variable information is set   
;*                                                   
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS       
;*                   ERROR_VIO_INVALID_LENGTH      
;*                   ERROR_VIO_BAD_CP               
;*                                                   
;*  INTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;*  EXTERNAL REFERENCES:                             
;*    ROUTINES: AccessCursorBlink, AccessCursorOverscan  
;*              AccessCursorUnderscore, AccessCursorVideoEnable 
;*              AccessDisplayMask                   
;*                                                   
;****************************************************************************/

SetVarInfo PROC FAR                               ;@@A
        public  SetVarInfo
        Call    RegSave

        mov     ax,ERROR_VIO_INVALID_PARMS
        test    [si].vp_flags,NOT (vp_f_physical+vp_f_codepage)
        .if     <z> and
        mov     ax,ERROR_VIO_INVALID_LENGTH
        .if     <[si].vp_parmlength ae vp_codepage+2>
            mov     ax,ERROR_VIO_BAD_CP
            mov     cx,[si].vp_codepage
            push    IDHGSEG
            pop     ds
            .if     <cx eq [bx].idh_codepage>
                sub     ax,ax
            .endif
        .endif

        Call    RegRest
        ret     12
SetVarInfo ENDP                                   ;@@A

;/****************************************************************************
;*                                                   
;* SUBROUTINE NAME:  GetCodePage                    
;*                                                   
;* DESCRIPTIVE NAME:   Get the Prepared CodePage for the VDH  
;*                                                   
;* FUNCTION:   Loads the font buffer with the first prepared codepage 
;*                                                   
;* NOTES:  Executes on Level 3                      
;*                                                   
;* ENTRY POINT:  GetCodePage                         
;*   LINKAGE:  Call GetCodePage                     
;*                                                   
;* INPUT:  DS = PPBVSCB, ES = CodePage Data Info Block (CDIB)  
;*         CX = Number of CodePages                 
;*         SI = Offset of CodePage substructure in CDIB  
;*                                                   
;* EXIT-NORMAL:  N/A                               
;*                                                   
;* EXIT-ERROR:   N/A                             
;*                                                   
;* EFFECTS:  None                                    
;*                                                   
;* INTERNAL REFERENCES: None                         
;*   ROUTINES:  ReadFont, RandomRead                
;*                                                   
;* EXTERNAL REFERENCES:  CDIB                        
;*   ROUTINES: DOSOPEN, DOSREAD, DOSCHGFILEPTR, DOSCLOSE,  
;*             DOSGETSHRSEG, DOSFREESEG            
;****************************************************************************/

GetCodePage PROC NEAR
        public  GetCodePage

        push    ax                                ;Save VideoConfig type  ;@T39
        push    si                                ;Save Config offset  ;@T39
        push    di                                ;Save ENV offset  ;@S20

        push    ds
        push    idh_cdib                          ;Ptr to CDIB name
        push    ds
        push    idh_selector                      ;Ptr to CDIB selector
        Call    DOSGETSHRSEG                      ;Get the CDIB selector

        .if     <zero ax>
            mov     es,ds:[bx].idh_selector
            mov     di,es:[bx].CDIB_codepage_ptr ;ES:DI = CodePage Info
            mov     cx,es:[di].CDIB_cp_number_codepages

            mov     ax,ERROR_VIO_BAD_CP
            .if     <ncxz>                        ;Some codepages prepared

                mov     si,es:[di].CDIB_cp_first_id ;Get first CP in SI

                mov     di,es:[bx].CDIB_screen_ptr ;Get offset of screen
                .if     <nonzero di>             ;Screen substructure found
                    mov     di,es:[di].CDIB_dev_filename_ptr ;Offset of file name
                .endif

                .if     <nonzero di>             ;Filename specified
                    push    es
                    push    di                    ;Device name ASCIIZ string
                    push    ds
                    push    idh_handle           ;Return for device handle
                    push    ds
                    push    idh_scratch ;Action Taken
                    push    bx
                    push    bx                    ;File size
                    push    bx                    ;File Attribute
                    push    00001h               ;Open Flag = Fail if missing
                    push    00020h               ;Open Mode = Read Only/Deny Write
                    push    bx
                    push    bx                    ;Reserved (0:0)
                    Call    DOSOPEN              ;Open the CodePage file
                .endif
            .endif
        .endif

        push    ax
        push    [bx].idh_selector
        Call    DOSFREESEG                        ;Relinquish use of the CDIB
        pop     ax

        .if     <zero ax> near                    ;File opened properly

            mov     ax,[bx].idh_fontsize
            xchg    al,ah
            push    ax                            ;Size of font segment
            push    ds
            push    idh_selector                 ;Selector return ptr
            push    bx                            ;Do not share this segment
            Call    DosAllocSeg                  ;Allocate work buffer
            .if     <zero ax> near               ;Buffer allocated properly

                sub     dx,dx
                sub     di,di                     ;Point to file header

                mov     es,[bx].idh_selector
                mov     cx,size fontfilehdr
                Call    RandomRead               ;Read the font file header
                .if     <zero ax> near           ;Font header read properly

                    mov     cx,word ptr es:[bx].ffh_numfonts ;Number
                    mov     di,word ptr es:[bx].ffh_ptroffset ;Offset

                    .repeat
                        push                     cx ;Number of fonts left in file
                        sub                      dx,dx
                        push                     di ;Fonthdr ptr

                        mov                      cx,4
                        Call                     RandomRead ;Read the fonthdr ptr
                        .if                      <zero ax> and

                        mov                      di,word ptr es:[bx]
                        mov                      dx,word ptr es:[bx+2] ;Get fonthdr ptr
                        mov                      cx,size fonthdr
                        Call                     RandomRead ;Read the fonthdr
                        .if                      <zero ax>

                            .if     <es:[bx].fh_cpid eq si> and
                            mov     cx,[bx].idh_fontsize
                            .if     <es:[bx].fh_cellrows eq cl> and
                            .if     <es:[bx].fh_cellcols eq 8>
                                                 add di,es:[bx].fh_dataoffset
                                                 adc dx,bx ;32-bit Offset of font in file
                                                 xchg cl,ch ;Get size to read
                                                 Call RandomRead ;Read the font data

                                                 .if <zero ax>
                                                     mov     [bx].idh_codepage,si ;Mark as found

                                                     push    bx    ;@T30
                                                     push    bx
                                                     mov     ax,sp ;Make room for a return value

                                                     push    2000h ;Size of video font buffer
                                                     push    ss
                                                     push    ax ;Return area for selector
                                                     push    000Ah
                                                     push    bx ;Address of video font buffer
                                                     Call    _PhysToUVirt ;Allocate new PVB selector
                                                     add     sp, 12 ;Balance the stack ;@T30

                                                     pop     es ;Get the video font selector
                                                     push    es ;Save it for Free below
                                                     Call    CopyFont ;Init font buffer

                                                     mov     es,bx ;Avoid trap when popping ES
                                                     Call    _FreePhysToUVirt ;Free the selector
                                                     add     sp, 2 ;Balance the stack
                                                 .endif
                            .endif

                        .endif

                        pop                      di
                        add                      di,4 ;Next ptr to font ptr
                        pop                      cx
                    .leave  <[bx].idh_codepage ne bx> ;Until font found
                    .loop                         ;Until all fonts examined
                .endif

                push    [bx].idh_selector
                Call    DOSFREESEG               ;Relinquish use of work buffer
            .endif
            push    [bx].idh_handle
            Call    DOSCLOSE                      ;Close the Font File
        .endif

        pop     di                                ;Save ENV offset  ;@S20
        pop     si                                ;Restore Config offset  ;@T39
        pop     ax                                ;Restore VideoConfig type ;@T39
        RET
GetCodePage ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = RandomRead:
;*
;* DESCRIPTION   = 
;*
;* INPUT         = DX:DI = New file offset          
;*                         ES:0  = Ptr to buffer    
;*                         CX    = Length of buffer 
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/


RandomRead PROC NEAR                              ;@@A
        public  RandomRead

        push    [bx].idh_handle                  ;File handle
        push    dx
        push    di                                ;Distance
        push    bx                                ;Type = Abs from Start
        push    ds
        push    idh_scratch                       ;New ptr return area
        Call    DOSCHGFILEPTR                     ;Set new file read location

        push    [bx].idh_handle                  ;File handle
        push    es
        push    bx                                ;Buffer ptr
        push    cx                                ;Read Length
        push    ds
        push    idh_scratch                       ;Return Length
        Call    DOSREAD                           ;Read from current location

        ret
RandomRead ENDP                                   ;@@A

;/****************************************************************************
;*                                                   
;*  SUBROUTINE NAME: GetDBCSInfo                    
;*                                                   
;*  DESCRIPTIVE NAME: Get DBCS character display width information 
;*                                                   
;*  FUNCTION: GetDBCSInfo is called by BVS to get character display 
;*            width information for use with WrtTTY.  The call should 
;*            return the ranges of characters that require two cells 
;*            for display.  On us adapters there are none.  
;*                                                   
;*  ENTRY POINT: GetDBCSInfo                         
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 261 ) 
;*                                                   
;*  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  
;*                     USHORT Table Length length of following table 
;*                     USHORT Beginning of first range   
;*                     USHORT End of first range   
;*                                              ...     
;*                     USHORT Beginning of nth range   
;*                     USHORT End of nth range    
;*             ULONG Function ( Call vector table entry = 261 ) 
;*                                                   
;*  EXIT-NORMAL: AX = 0                              
;*               The table is returned (Table length = 0)  
;*                                                   
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS       
;*                   ERROR_VIO_INVALID_LENGTH      
;*                                                   
;*  INTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;*  EXTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;****************************************************************************/

GetDBCSInfo PROC FAR                                                    ;@P1
        public  GetDBCSInfo                                             ;@P1
        Call    RegSave                                                 ;@P1


        mov     ax,ERROR_VIO_INVALID_LENGTH                             ;@P1
        .if     <[si].vp_parmlength e 2> near                           ;@P1
            xor     ax,ax                                               ;@P1
            mov     [si].vp_parmlength,(vp_di_tbllen + 2)               ;@P1
        .else                                                           ;@P1
            .if     <[si].vp_parmlength ae 4> near                      ;@P1
                mov     ax,ERROR_VIO_INVALID_PARMS                      ;@P1
                cmp     [si].vp_flags,bx                                ;@P1
                .if     <z> and                                         ;@P1
                mov     ax,ERROR_VIO_INVALID_LENGTH                     ;@P1
                .if     <[si].vp_parmlength ae 6>                       ;@P1
                    mov     [si].vp_di_tbllen,bx                        ;@P1
                    sub     ax,ax                ; Set good return code ;@P1
                .endif                                                  ;@P1
            .endif                                                      ;@P1
        .endif                                                          ;@P1

        Call    RegRest                                                 ;@P1
        ret     12                                                      ;@P1
GetDBCSInfo ENDP                                                        ;@P1

;/****************************************************************************
;*                                                   
;*  SUBROUTINE NAME: GetLVBInfo                     
;*                                                   
;*  DESCRIPTIVE NAME: Return LVB size and default attribute info 
;*                                                   
;*  FUNCTION: GetLVBInfo is called by BVS to determine the size of the 
;*            LVB required for a given display size.  Based on the 
;*            mode and its associated LVB format the allocation size 
;*            of the LVB is returned.           Also a default attribute may 
;*            be returned.                           
;*                                                   
;*  ENTRY POINT: GetLVBInfo                          
;*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 2xx ) 
;*                                                   
;*  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  
;*                     UCHAR  FormatId;            
;*                     UCHAR  AttrCount;           
;*                     USHORT LVBWidth;            
;*                     USHORT LVBHeight;           
;*                     ULONG  LVBSize;             
;*                     USHORT AttrBufSize;         
;*                     UCHAR far *AttrBufAddr;    
;*             ULONG Function ( Call vector table entry = 261 ) 
;*                                                   
;*  EXIT-NORMAL: AX = 0                              
;*               The correct size of the LVB is returned  
;*                                                   
;*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS       
;*                                                   
;*  INTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;*  EXTERNAL REFERENCES:                             
;*    ROUTINES: NONE                                 
;*                                                   
;****************************************************************************/

GetLVBInfo  PROC FAR                                                    ;@P1
        public  GetLVBInfo                                              ;@P1
        Call    RegSave                                                 ;@P1
                                                                        ;@P1
        mov     ax,ERROR_VIO_INVALID_PARMS                              ;@P1
        .if     <[si].vp_parmlength ge vp_li_attrsize>                  ;@P1
            .if     <[si].vp_li_fidatt e bx>                            ;@P1
                .if     <[si].vp_li_width e bx>                         ;@P1
                    mov     ax,es:[di].env_cols                         ;@P1
                .else                                                   ;@P1
                    mov     ax,[si].vp_li_width                         ;@P1
                .endif                                                  ;@P1
                .if     <[si].vp_li_height e bx>                        ;@P1
                    mul     es:[di].env_rows                            ;@P1
                .else                                                   ;@P1
                    mul     [si].vp_li_height                           ;@P1
                .endif                                                  ;@P1
                shl     ax,1       ; 2 bytes per cell * number of cells ;@P1
                .if     <c>                                             ;@P1
                    shl     dx,1                                        ;@P1
                    inc     dx                                          ;@P1
                .else                                                   ;@P1
                    shl     dx,1                                        ;@P1
                .endif                                                  ;@P1
                mov     [si].vp_li_allocl,ax                            ;@P1
                mov     [si].vp_li_alloch,dx                            ;@P1
                xor     ax,ax                                           ;@P1
            .endif                                                      ;@P1
        .endif                                                          ;@P1
        .if     <[si].vp_parmlength ge vp_li_attroffst> near            ;@P1
             mov    cx,[si].vp_li_attrsize                              ;@P1
            .if     <cx e bx> near                                      ;@P1
                mov     cx,es:[di].env_attrbufsiz                       ;@P1
                mov     [si].vp_li_attrsize,cx                          ;@P1
            .else                                                       ;@P1
                .if     <cx ae es:[di].env_attrbufsiz> and              ;@P1
                .if     <[si].vp_parmlength ae vp_li_attrseg+2>         ;@P1
                    mov     bx,[si].vp_li_attroffst                     ;@P1
                    mov     cx,[si].vp_li_attrseg                       ;@P1
                    mov     ds,cx                                       ;@P1
                    mov     cx,es:[di].env_attrbufsiz                   ;@P1
                    add     di,env_attrbuf                              ;@P1
                    .repeat                                             ;@P1
                        mov                      dl,es:[di]             ;@P1
                        mov                      ds:[bx],dl             ;@P1
                        inc                      di                     ;@P1
                        inc                      bx                     ;@P1
                        dec                      cx                     ;@P1
                    .until  <zero cx>                                   ;@P1
                .else                                                   ;@P1
                    mov     ax,ERROR_VIO_INVALID_LENGTH                 ;@P1
                .endif                                                  ;@P1
            .endif                                                      ;@P1
        .endif                                                          ;@P1

        Call    RegRest                                                 ;@P1
        ret     12                                                      ;@P1
GetLVBInfo  ENDP                                                        ;@P1


R2CSEG  ENDS
        END

