;SCCSID = @(#)bvsstate.asm      6.2 91/02/11
        PAGE    58,132
        TITLE   BvsState.Asm -- Base Video Subsystem Video State Routines
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SOURCE FILE NAME:    BvsState.Asm                                   */
;/*                                                                     */
;/* DESCRIPTIVE NAME:    BVS Video State Routines                       */
;/*                                                                     */
;/* COPYRIGHT:   na                                                     */
;/*                                                                     */
;/* STATUS:      na                                                     */
;/*                                                                     */
;/* NOTES:       Executes on level 3                                    */
;/*                                                                     */
;/*    DEPENDENCIES:    None                                            */
;/*                                                                     */
;/*    RESTRICTIONS:    None                                            */
;/*                                                                     */
;/*    PATCH LABEL:      na                                             */
;/*                                                                     */
;/* ENTRY POINTS: BvsGetState, BvsSetState                              */
;/*                                                                     */
;/* EXTERNAL REFERENCES: None                                           */
;/************************ END OF SPECIFICATIONS ************************/

        .xlist
        INCLUDE bvscb.inc               ;BVS Data Structures
        INCLUDE bvsparms.inc            ;BVS Parameter Equates
        INCLUDE bvsextrn.inc            ;BVS external definitions       ;@T52
        INCLUDE error2.inc              ;Error Equates
        INCLUDE struc.inc               ;Structured Macros
        INCLUDE dc1segs.inc                                             ;MDLL
        .list

        .386p                   ;@D549

        extrn   AllVDH:NEAR             ;Common VDH call routine in BVSMAIN
        extrn   GetScrollRect:NEAR      ; update the scroll rect
        extrn   InitConfig:NEAR         ;Initialize a new config ;@S10

BVS3SEG SEGMENT BYTE PUBLIC 'CODE' USE16        ;@D549
        ASSUME  CS:CODE02                                               ;MDLL

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsGetState                                       */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Get Video State Information */
;/*                                                                     */
;/* FUNCTION:  Returns selected video state information.                */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsGetState                                           */
;/*   LINKAGE:  Call BvsGetState from BVSMAIN                           */
;/*                                                                     */
;/* INPUT:  StackFrame and Registers (see BVSMAIN)                      */
;/*     parmn   = Offset of request block                               */
;/*     parmnm1 = Selector of request block                             */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0 ==> Operation completed successfully           */
;/*                                                                     */
;/* EXIT-ERROR:  AX = ERROR_VIO_INVALID_LENGTH                          */
;/*                   ERROR_VIO_INVALID_PARMS                           */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  BVSCBsg, PPBVSCB                              */
;/*   ROUTINES: None                                                    */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES: GetVariableInfo, GetPaletteRegisters, and               */
;/*     and GetColorLookupTable in VDH                                  */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsGetState
;    Preset return code to error_vio_invalid_length
;    If request = Get Palette Regs (IF/ELSEIF ==> Call Table)
;        If valid length
;            Call GetPaletteRegisters in VDH
;            Return the requested registers in the user's data area
;        Endif
;    Elseif request = Get Color Regs
;        If valid length
;            Call GetColorLookupTable in VDH
;            Return the requested registers in the user's data area
;        Endif
;    Elseif request = Get Target Configuration
;        If valid length
;            Return the target configuration in the user's data area
;            Set return code to zero
;        Endif
;    Else
;        Call GetVariableInfo in VDH
;        If request = Get Border Color
;            If valid length
;                Return the border color in the user's data area
;                Set return code to zero
;            Endif
;        Elseif request = Get Blink State
;            If valid length
;                Return the blink state in the user's data area
;                Set return code to zero
;            Endif
;        Elseif request = Get Display Mask
;            If valid length
;                Return the display mask in the user's data area
;                Set return code to zero
;            Endif
;        Elseif request = Get Underline Location
;            If valid length
;                Return the underline location in the user's data area
;                Set return code to zero
;            Endif
;        Elseif request = User defined
;               call VDH GetState
;        Endif
;        Else
;            Set return code to error_vio_invalid_parms
;        Endif
;    Endif
;End BvsGetState

BvsGetState PROC NEAR
        PUBLIC  BvsGetState

        mov     ax,ERROR_VIO_INVALID_LENGTH ;Preset error
        lds     si,dword ptr [bp].p_offset
        mov     cx,[si].sp_rblength     ;Get length of request block
        .if     <cx ae sp_palregs> and  ;At least one parameter
        test    cx,1
        .if     z                       ;Words only
            mov     ax,ERROR_VIO_INVALID_PARMS ;Preset error
            mov     di,[si].sp_reqtype
            .if     <di be 7>           ;If request type is non user defined
                mov     ax,ERROR_VIO_INVALID_LENGTH ;Preset error
                mov     dx,[si].sp_data ;Pre-load the first paramter
                add     di,di
                jmp     CS:GetTbl[di]   ;Return via subroutine ;JOPT
            .else                       ; see if user defined           ;D811
                ;                                                       ;D811
                ; OEM defined functions are defined in the range        ;D811
                ; above 8000h, such requests are passed onto the        ;D811
                ; installed VDH handler.                                ;D811
                ;                                                       ;D811
                .if     <di ge STATE_OEMFUNCTIONS> ; it is OEM defined  ;D811
                    ; parameters into the VDH hander                    ;D811
                    mov     [bp].vp_parmlength, 8                       ;D811
                    mov     [bp].vp_flags, 0                            ;D811
;D811f              mov     ax, [si].sp_OEMoffset  ; low word of data   ;D811
                    mov     [bp].vp_offset,si                           ;D811f
;D811f              mov     ax,[si].sp_OEMselector ; high word of data  ;D811
                    mov     [bp].vp_selector,ds ; Set the data pointer  ;D811f
                    mov     di, fn_GetState                             ;D811
                    Call    AllVDH                                      ;D811
                    ; ax as returned from VDH is this functions return value
                .endif                                                  ;D811
            .endif
        .endif
        ret                             ;Return with error ;JOPT
BvsGetState ENDP

;Table of GetState Subroutines

GetTbl  dw      GetPalReg
        dw      GetBorder
        dw      GetBlink
        dw      GetClut
        dw      GetMask
        dw      GetUnderscore
        dw      GetConfigNum
        dw      GetBottomScroll

GetPalReg PROC  NEAR
        PUBLIC  GetPalReg

     ;;;.if     <cx be 38>              ;@@B
        .if     <cx be 38> and          ;@B74
        .if     <cx ae  8>              ;@B74
            mov     [bp].vp_sp_index,dx ;Set Index of first register
            sub     cx,sp_palregs
            shr     cx,1
            mov     [bp].vp_sp_number,cx ;Set the Number of regs
            add     si,sp_palregs       ;Get offset of registers
            mov     [bp].vp_offset,si
            mov     [bp].vp_selector,ds ;Set the data pointer

            mov     [bp].vp_parmlength,12 ;Set parameter list length
            mov     di,fn_GetPalette
            Call    AllVDH
        .endif                          ;@@B
        ret
GetPalReg ENDP

GetBlink PROC   NEAR
        PUBLIC  GetBlink

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     ax,vp_f_blink       ;@@A
            Call    AllGetVarInfo       ;Get info from the VDH

            .if     <zero ax>
                mov     dx,[bp].vp_blink
                mov     [si].sp_data,dx ;Return the blink state
            .endif
        .endif
        ret
GetBlink ENDP

GetBorder PROC  NEAR
        PUBLIC  GetBorder

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     ax,vp_f_border      ;@@A
            Call    AllGetVarInfo       ;Get info from the VDH

            .if     <zero ax>
                mov     dx,[bp].vp_border
                mov     [si].sp_data,dx ;Return the border color
            .endif
        .endif
        ret
GetBorder ENDP

GetMask PROC    NEAR
        PUBLIC  GetMask

        .if     <cx eq sp_offset>       ;Room for 32-bit mask
            mov     ax,vp_f_dispmask    ;@@A
            Call    AllGetVarInfo       ;Get info from the VDH

            .if     <zero ax>
                mov     dx,[bp].vp_dispmask1
                mov     [si].sp_dispmask1,dx
                mov     dx,[bp].vp_dispmask2
                mov     [si].sp_dispmask2,dx ;Return the display mask
            .endif
        .endif
        ret
GetMask ENDP

GetCLUT PROC    NEAR
        PUBLIC  GetCLUT

        .if     <cx eq 12>              ;@@B
            mov     ax,[si].sp_data
            mov     [bp].vp_sp_index,ax ;Set Index of first register
            mov     ax,[si].sp_palregs
            mov     [bp].vp_sp_number,ax ;Set the Number of regs
            mov     ax,[si].sp_offset
            mov     [bp].vp_offset,ax
            mov     ax,[si].sp_selector
            mov     [bp].vp_selector,ax ;Set the data pointer

            mov     [bp].vp_parmlength,12 ;Set parameter list length
            mov     di,fn_GetCLUT
            Call    AllVDH
        .endif
        ret
GetCLUT ENDP

GetUnderscore PROC NEAR
        PUBLIC  GetUnderscore

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     ax,vp_f_underscore  ;@@A
            Call    AllGetVarInfo       ;Get info from the VDH

            .if     <zero ax>
                mov     dx,[bp].vp_underscore
                mov     [si].sp_data,dx ;Return the underscore scan line
            .endif
        .endif
        ret
GetUnderscore ENDP

GetConfigNum PROC NEAR
        PUBLIC  GetConfigNum

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     es,es:bvsi_bvssel   ;Restore the BVSCB selector     ;@T52
            mov     ax,es:[bx].bvs_confignum
            mov     [si].sp_data,ax     ;Return the current config number
            sub     ax,ax
        .endif
        ret
GetConfigNum ENDP

GetBottomScroll PROC NEAR
        PUBLIC  GetBottomScroll

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     ax,vp_f_scrlrect    ;@@A
            Call    AllGetVarInfo       ;Get info from the VDH

            .if     <zero ax>
                push    ds              ;                             ;J-KK0816
                mov     ds,es:[bvsi_bvssel] ;Get # of rows from       ;J-KK0816
                mov     dx,ds:[bx].bvs_rows ;  the BVSCB              ;J-KK0816
                pop     ds              ;                             ;J-KK0816
                dec     dx              ;                             ;J-KK0816
                sub     dx,[bp].vp_scrlbottom                         ;J-KK0816
                mov     [si].sp_data,dx ;Return the underscore scan line
            .endif
        .endif
        ret
GetBottomScroll ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsSetState                                       */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Set Video State Information */
;/*                                                                     */
;/* FUNCTION:  Sets selected video state information.                   */
;/*                                                                     */
;/* NOTES:  Executes on Level 3.                                        */
;/*                                                                     */
;/* ENTRY POINT:  BvsSetState                                           */
;/*   LINKAGE:  Call BvsSetState from BVSMAIN                           */
;/*                                                                     */
;/* INPUT:  StackFrame and Registers (see BVSMAIN)                      */
;/*     parmn   = Offset of request block                               */
;/*     parmnm1 = Selector of request block                             */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0 ==> Operation completed successfully           */
;/*                                                                     */
;/* EXIT-ERROR:  AX = error code from DOSDEVIOCTL                       */
;/*                   ERROR_VIO_EXTENDED_SG                             */
;/*                   ERROR_VIO_INVALID_LENGTH                          */
;/*                   ERROR_VIO_INVALID_PARMS                           */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  BVSCBsg, PPBVSCB                              */
;/*   ROUTINES: None                                                    */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES: SetVariableInfo, SetPaletteRegisters, and               */
;/*     and SetColorLookupTable in VDH                                  */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsSetState
;    Preset return code to error_vio_invalid_length
;    If request = Set Palette Regs (IF/ELSEIF ==> Call Table)
;        If valid length
;            Call SetPaletteRegisters in VDH
;        Endif
;    Elseif request = Set Border Color
;        If valid length
;            Call SetVariableInfo in VDH to update border color
;        Endif
;    Elseif request = Set Blink State
;        If valid length
;            Call SetVariableInfo in VDH to update blink state
;        Endif
;    Elseif request = Set Color Regs
;        If valid length
;            Call SetColorLookupTable in VDH
;        Endif
;    Elseif request = Set Display Mask
;        If valid length
;            Call SetVariableInfo in VDH to update display mask
;        Endif
;    Elseif request = Set Underline Location
;        If valid length
;            Call SetVariableInfo in VDH to update underline location
;        Endif
;    Elseif request = Set Target Configuration
;        If valid length
;            Set the target configuration in the BVSCB
;            Set return code to zero
;        Endif
;    Elseif request = User defined
;            call VDH SetState
;    Endif
;    Else
;        Set return code to error_vio_invalid_parms
;    Endif
;End BvsSetState

BvsSetState PROC NEAR
        PUBLIC  BvsSetState

        mov     ax,ERROR_VIO_INVALID_LENGTH ;Preset error
        lds     si,dword ptr [bp].p_offset
        mov     cx,[si].sp_rblength     ;Get length of request block
        .if     <cx ae sp_palregs> and  ;At least one parameter
        test    cx,1
        .if     z                       ;Words only
            mov     ax,ERROR_VIO_INVALID_PARMS ;Preset error
            mov     di,[si].sp_reqtype
            .if     <di be 7>           ;If request type is not user defined
                mov     ax,ERROR_VIO_INVALID_LENGTH ;Preset error
                mov     dx,[si].sp_data ;Pre-load the first paramter
                add     di,di
                jmp     CS:SetTbl[di]   ;Return via subroutine ;JOPT
            .else                       ; see if user defined           ;D811
                .if     <di ge STATE_OEMFUNCTIONS> ; it is OEM defined  ;D811
                  ; parameters into the VDH hander                      ;D811
                    mov     [bp].vp_parmlength, 8                       ;D811
                    mov     [bp].vp_flags, 0                            ;D811
;D811f              mov     ax, sp_offset                               ;D811
                    mov     [bp].vp_offset,si                           ;D811f
;D811f              mov     ax, sp_selector                             ;D811
                    mov     [bp].vp_selector,ds ;Set the data pointer   ;D811f
                    mov     di, fn_SetState                             ;D811
                    Call    AllVDH                                      ;D811
                    ; ax as returned from VDH is this functions return value
                .endif
            .endif
        .endif
        ret                             ;Return with error ;JOPT
BvsSetState ENDP

;Table of SetState Subroutines

SetTbl  dw      SetPalReg
        dw      SetBorder
        dw      SetBlink
        dw      SetClut
        dw      SetMask
        dw      SetUnderscore
        dw      SetConfigNum
        dw      SetBottomScroll

SetPalReg PROC  NEAR
        PUBLIC  SetPalReg

     ;;;.if     <cx be 38> and          ;@@B
        .if     <cx be 38> and          ;@B74
        .if     <cx ae  8>              ;@B74
            mov     [bp].vp_sp_index,dx ;Set Index of first register
            sub     cx,sp_palregs
            shr     cx,1
            mov     [bp].vp_sp_number,cx ;Set the Number of regs
            add     si,sp_palregs       ;Get offset of registers
            mov     [bp].vp_offset,si
            mov     [bp].vp_selector,ds ;Set the data pointer

            mov     [bp].vp_parmlength,12 ;Set parameter list length
            mov     di,fn_SetPalette
            Call    AllVDH
        .endif                          ;@@B
        ret
SetPalReg ENDP

SetBlink PROC   NEAR
        PUBLIC  SetBlink

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     [bp].vp_blink,dx    ;Set the blink state

            mov     ax,vp_f_blink
            Call    AllSetVarInfo
        .endif
        ret
SetBlink ENDP

SetBorder PROC  NEAR
        PUBLIC  SetBorder

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     [bp].vp_border,dx   ;Set the border color

            mov     ax,vp_f_border
            Call    AllSetVarInfo
        .endif
        ret
SetBorder ENDP

SetMask PROC    NEAR
        PUBLIC  SetMask

        .if     <cx eq sp_offset>       ;Room for 32-bit mask
            mov     [bp].vp_dispmask1,dx
            mov     ax,[si].sp_dispmask2
            mov     [bp].vp_dispmask2,ax ;Set the display mask

            mov     ax,vp_f_dispmask
            Call    AllSetVarInfo
        .endif
        ret
SetMask ENDP

SetCLUT PROC    NEAR
        PUBLIC  SetCLUT

        .if     <cx eq 12>              ;@@B
            mov     [bp].vp_sp_index,dx ;Set Index of first register
            mov     ax,[si].sp_palregs
            mov     [bp].vp_sp_number,ax ;Set the Number of regs
            mov     ax,[si].sp_offset
            mov     [bp].vp_offset,ax
            mov     ax,[si].sp_selector
            mov     [bp].vp_selector,ax ;Set the data pointer

            mov     [bp].vp_parmlength,12 ;Set parameter list length
            mov     di,fn_SetCLUT
            Call    AllVDH
        .endif
        ret
SetCLUT ENDP

SetUnderscore PROC NEAR
        PUBLIC  SetUnderscore

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     [bp].vp_underscore,dx ;Set the underscore scan line

            mov     ax,vp_f_underscore
            Call    AllSetVarInfo
        .endif
        ret
SetUnderscore ENDP

SetConfigNum PROC NEAR
        PUBLIC  SetConfigNum

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     ds,es:bvsi_bvssel   ;Restore the BVSCB selector     ;@T52
            mov     ax,ERROR_VIO_INVALID_PARMS ;Preset error
            .if     <dx be [bx].bvs_numconfigs> ;Valid config number
                mov     [bx].bvs_confignum,dx ;Save the new number

                .if     <nonzero dx>    ;@S10
;@C40b              push    [bx].bvs_curconfig  ;@C40
                    mov     [bx].bvs_curconfig,dx ;Switch to new config ;@S10
                    Call    InitConfig  ;Initialize the new config ;@S10
;@C40b              pop     [bx].bvs_curconfig  ;@C40
                .endif                  ;@S10

                sub     ax,ax
            .endif
        .endif
        ret
SetConfigNum ENDP

SetBottomScroll PROC NEAR
        PUBLIC  SetBottomScroll

        .if     <cx eq sp_palregs>      ;Exactly one parameter
            mov     [bp].vp_scrlleft,bx ;left most column
            mov     [bp].vp_scrltop,bx  ;top most row
            mov     ds,es:bvsi_bvssel   ;Restore the BVSCB selector     ;@T52
            mov     ax,[bx].bvs_cols    ;number of columns
            dec     ax                  ;right most column (zero indexed)
            mov     [bp].vp_scrlright,ax ;right most column
;J-KK0816   mov     [bp].vp_scrlbottom,dx ;bottom most row
            mov     ax,[bx].bvs_rows    ;number of rows               ;J-KK0816
            sub     ax,dx               ;                             ;J-KK0816
            .if     <be>                ;                             ;J-KK0816
                mov     ax,[bx].bvs_rows;                             ;J-KK0816
            .endif                      ;                             ;J-KK0816
            dec     ax                  ;                             ;J-KK0816
            mov     [bp].vp_scrlbottom,ax                             ;J-KK0816

            mov     ax,vp_f_scrlrect
            Call    AllSetVarInfo
            .if     <zero ax>
                call    GetScrollRect   ; update the scroll rect
                xor     ax,ax           ; return good error code
            .endif
        .endif
        ret
SetBottomScroll ENDP

BVS3SEG ENDS                                                            ;MDLL

CTEXT_TUNE5 SEGMENT BYTE PUBLIC 'CODE' USE16                            ;MDLL
        ASSUME  CS:CODE02                                               ;MDLL

AllGetVarInfo PROC NEAR
        PUBLIC  AllGetVarInfo

        mov     [bp].vp_flags,ax        ;@@A
        mov     [bp].vp_parmlength,vp_scrncols+2
        mov     di,fn_GetVarInfo
        jmp     AllVDH                  ;JOPT
AllGetVarInfo ENDP

AllSetVarInfo PROC NEAR
        PUBLIC  AllSetVarInfo

        mov     [bp].vp_flags,ax        ;Set the flags

        mov     [bp].vp_parmlength,vp_scrncols+2 ;Set parameter list length
        mov     di,fn_SetVarInfo
        jmp     AllVDH                  ;JOPT
AllSetVarInfo ENDP

CTEXT_TUNE5 ENDS                                                        ;MDLL
        END

;@@B = 12/29/88 CJJ,TLB  Added checking for valid parameter packet length P3347
;@@A =  1/11/89 CJJ,     Set flag for specific request during GetState P3343
;JOPT = 03/29/89 STJ, Replace CALL/RET with jumps through subroutines
;@S10 = 05/11/89 STJ, Retain separate ENVB/LVB for each config, B701174
;@D549 = 11/02/89 CJJ, Seltable changes due to rangeless sessions, DCR 549
;D811 = 11/30/89 MS,  DCR 811
;@C40 = 12/07/89 CJJ, Save and restore curconfig, B710378
;@T52 = 01/24/90 TPL, DCR 704 work
;J-KK0816 = 02/12/90 KKJ, DCR 388 (non scrollable size), B711354
;@B74 = 06/21/90 WKB, Check length (cb) field for validity, B713929
;D811f= 01/28/91 TPL, Rollover MS's DCR 811 fixes for OEM GetState and SetState
;@C40b= 01/28/91 TPL, Rollover JeffPar's fix to remove PUSH/POP around
                      SetConfigNum which apparently breaks MON.EXE
;MDLL = 01/10/94 BJN, Page Tune segments for Merged DLL.
