;       SCCSID = @(#)bvscursr.asm       6.1 90/11/16
;SCCSID = @(#)bvscursr.asm      6.4 90/02/12
        PAGE    58,132
        TITLE   BvsCursr.Asm -- Base Video Subsystem Cursor 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:    BvsCursr.Asm                                   */
;/*                                                                     */
;/* DESCRIPTIVE NAME:    BVS Cursor Routines                            */
;/*                                                                     */
;/* COPYRIGHT:   na                                                     */
;/*                                                                     */
;/* STATUS:      na                                                     */
;/*                                                                     */
;/* NOTES:       Executes on level 3                                    */
;/*                                                                     */
;/*    DEPENDENCIES:    None                                            */
;/*                                                                     */
;/*    RESTRICTIONS:    None                                            */
;/*                                                                     */
;/*    PATCH LABEL:      na                                             */
;/*                                                                     */
;/* ENTRY POINTS: BvsGetCurPos,BvsSetCurPos,BvsGetCurType,BvsSetCurType */
;/*                                                                     */
;/* 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   VIOGETMODE:FAR          ;Get current video mode

        extrn   AllVDH:NEAR             ;Common VDH call routine in BVSMAIN

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

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsGetCurPos                                      */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Get Cursor Position         */
;/*                                                                     */
;/* FUNCTION:  Returns the cursor position for the Base Video Subsystem */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsGetCurPos                                          */
;/*   LINKAGE:  Call BvsGetCurPos from BVSMAIN                          */
;/*                                                                     */
;/* INPUT:  StackFrame and Registers (see BVSMAIN)                      */
;/*     parmn   = Offset of column                                      */
;/*     parmnm1 = Selector of row                                       */
;/*     parmnm2 = Offset of row                                         */
;/*     parmnm3 = Selector of row                                       */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*               Row and Column to user area                           */
;/*                                                                     */
;/* EXIT-ERROR: None                                                    */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  BVSCBsg                                       */
;/*   ROUTINES:  None                                                   */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES: GetCursorInfo in VDH                                    */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsGetCurPos
;    Call GetCursorInfo in VDH
;    Return the cursor position in the user's data area
;End BvsGetCurPos

BvsGetCurPos PROC NEAR
        PUBLIC  BvsGetCurPos

        Call    SyncCursor              ;Synchronize Cursor data

        .if     <zero ax>
            les     di,dword ptr [bp].c_rowoff
            mov     ax,[bp].vp_c_row
            stosw                       ;Return the current row
            les     di,dword ptr [bp].c_coloff
            mov     ax,[bp].vp_c_col
            stosw                       ;Return the current column
            sub     ax,ax
        .endif
        ret
BvsGetCurPos ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsGetCurType                                     */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Get Cursor Type             */
;/*                                                                     */
;/* FUNCTION:  Returns the Start Line, End Line, Width, and Attribute   */
;/*            of the cursor for the Base Video Subsystem               */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsGetCurType                                         */
;/*   LINKAGE:  Call BvsGetCurType from BVSMAIN                         */
;/*                                                                     */
;/* INPUT:  StackFrame and Registers (see BVSMAIN)                      */
;/*     parmn   = Offset of cursor data block                           */
;/*     parmnm1 = Selector of cursor data block                         */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*               Start Line, End Line, Width, and Attr copied          */
;/*                     to user's cursor data block                     */
;/*                                                                     */
;/* EXIT-ERROR: None                                                    */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  BVSCBsg                                       */
;/*   ROUTINES:  None                                                   */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES: GetCursorInfo in VDH                                    */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsGetCurType
;    Call GetCursorInfo in VDH
;    Return the cursor position in the user's data area
;End BvsGetCurType

BvsGetCurType PROC NEAR
        PUBLIC  BvsGetCurType

        mov     [bp].vp_parmlength,16   ;Set parameter list length
        mov     [bp].vp_flags,vp_f_curtype ;@@S1
        mov     di,fn_GetCursor
        Call    AllVDH

        .if     <zero ax>
            lds     si,dword ptr [bp].p_offset
            mov     cx,[bp].vp_c_startline
            mov     [si].cursor_start,cx
            mov     cx,[bp].vp_c_endline
            mov     [si].cursor_end,cx
            mov     cx,[bp].vp_c_width
            mov     [si].cursor_width,cx
            mov     cx,[bp].vp_c_attr
            mov     [si].cursor_attr,cx ;Return the cursor data
        .endif
        ret
BvsGetCurType ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsSetCurType                                     */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Set Cursor Type             */
;/*                                                                     */
;/* FUNCTION:  Sets the cursor type for the Base Video Subsystem        */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsSetCurType                                         */
;/*   LINKAGE:  Call BvsSetCurType from BVSMAIN                         */
;/*                                                                     */
;/* INPUT:  StackFrame and Registers (see BVSMAIN)                      */
;/*     parmn   = Offset of cursor data block                           */
;/*     parmnm1 = Selector of cursor data block                         */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*                                                                     */
;/* EXIT-ERROR: Invalid Cursor Starting Line                            */
;/*             Invalid Cursor Width                                    */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  BVSCBsg                                       */
;/*   ROUTINES: None                                                    */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES: SetCursorInfo in VDH                                    */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsSetCurType
;    Call SetCursorInfo in VDH to update cursor type
;End BvsSetCurType

BvsSetCurType PROC NEAR
        PUBLIC  BvsSetCurType

        les     si,dword ptr [bp].p_offset ;@@B
        mov     cx,es:[si].cursor_start ;@@B
        mov     di,es:[si].cursor_end   ;Get requested start/end lines ;@@B

        push    cx                      ;@WPW1, if cx != di, the thickness of
        push    di                      ;the cursor should be at least 2. This
                                        ;is mainly for the Trident cards, in
                                        ;the 80X43 mode.

        .if     <cx l bx> or
        .if     <di l bx>               ;Mode data required for scaling
            push    di                  ;@@S1
            Call    SyncModeCursor
            pop     di                  ;@@S1

            mov     ax,[bx].bvs_grows   ;@@B
            sub     dx,dx               ;Make sure DX is cleared         @T3
            div     [bx].bvs_rows       ;Compute graphic rows per cell ;@@B

            .if     <cx l bx>           ;Start line needs scaling
                push    ax              ;
                neg     cx              ; (~(top scan line) * cell height
                mul     cx              ;    - 1) / 100
                dec     ax              ;                                @T3
                .if     <s>             ;Negative value?                 @T3
                    sub     cx,cx       ;Default to zero                 @T3
                .else                   ;                                @T3
                    mov     cx,100      ;
                    sub     dx,dx       ;Make sure DX is cleared         @T3
                    div     cx          ;
                    mov     cx,ax       ;Scaled line = -(height*line)/100
                .endif                  ;                                @T3
                pop     ax              ;
            .endif                      ;

            .if     <di l bx>           ;End line needs scaling
                neg     di              ; (~(bottom scan line) * cell height
                mul     di              ;    - 1) / 100
                dec     ax              ;                                @T3
                .if     <s>             ;Negative value?                 @T3
                    sub     cx,cx       ;Default to zero                 @T3
                .else                   ;                                @T3
                    mov     di,100      ;
                    sub     dx,dx       ;Make sure DX is cleared         @T3
                    div     di          ;
                    mov     di,ax       ;Scaled line = -(height*line)/100
                .endif                  ;                                @T3
            .endif
        .endif

        pop     ax                      ;@WPW1; if cx != di, and cusor start =
        pop     dx                      ;cursor end, subtract cursor start
        sub     ax, dx                  ;by 1.
        jz      Same_Value
        cmp     cx, di
        jnz     Same_Value
        dec     cx

Same_Value:
        sub     dx, dx                  ;@WPW1;Make sure DX is cleared
        mov     [bp].vp_c_startline,cx
        mov     [bp].vp_c_endline,di    ;Save scaled cursor start/end lines

        mov     ax,es:[si].cursor_width ;@@B
        mov     [bp].vp_c_width,ax      ;Set the cursor width
        mov     ax,es:[si].cursor_attr  ;@@B
        mov     [bp].vp_c_attr,ax       ;Set the cursor attribute

        mov     [bp].vp_parmlength,16   ;Set parameter list length
        mov     byte ptr [bp].vp_flags,vp_f_curtype
        mov     di,fn_SetCursor
        jmp     AllVDH                  ;JOPT
BvsSetCurType ENDP

BVS3SEG ENDS



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

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsSetCurPos                                      */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Set Cursor Position         */
;/*                                                                     */
;/* FUNCTION:  Sets the cursor position to the specified Row and Column */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsSetCurPos                                          */
;/*   LINKAGE:  Call BvsSetCurPos from BVSMAIN                          */
;/*                                                                     */
;/* INPUT:  StackFrame and Registers (see BVSMAIN)                      */
;/*     parmn   = Column                                                */
;/*     parmnm1 = Row                                                   */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*                                                                     */
;/* EXIT-ERROR: Invalid row value                                       */
;/*             Invalid column value                                    */
;/*                                                                     */
;/* INPUT:  Row, Column                                                 */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*                                                                     */
;/* EXIT-ERROR:  None                                                   */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  BVSCBsg                                       */
;/*   ROUTINES: None                                                    */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES: SetCursorInfo in VDH                                    */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Begin BvsSetCurPos
;    Call SetCursorInfo in VDH to update cursor position
;End BvsSetCurPos

BvsSetCurPos PROC NEAR
        PUBLIC  BvsSetCurPos

        mov     ax,[bp].c_row
        mov     cx,[bp].c_col

BvsSetCurPos2 LABEL NEAR
        public  BvsSetCurPos2

        mov     [bp].vp_c_row,ax
        mov     [bp].vp_c_col,cx        ;Set the row and column

        mov     byte ptr [bp].vp_flags,vp_f_curpos
        mov     di,fn_SetCursor

AllSetCurPos LABEL NEAR                 ;JOPT
        public  AllSetCurPos            ;JOPT

        mov     [bp].vp_parmlength,16   ;Set parameter list length
        Call    AllVDH

        .if     <zero ax>
            mov     ax,[bp].vp_c_row
            mov     [bx].bvs_cursorrow,ax ;Get the current row
            mov     ax,[bp].vp_c_col
            mov     [bx].bvs_cursorcol,ax ;Get the current column
            sub     ax,ax
        .endif

        ret
BvsSetCurPos ENDP

SyncModeCursor PROC NEAR                ;Synchronize Mode and Cursor data
        public  SyncModeCursor

        mov     [bp].vp_flags,vp_f_physical ;Force reset of flag
        mov     [bx].bvs_mdlen,size modedata ;Get complete mode data
        mov     [bp].vp_offset,bvs_mdlen
        mov     [bp].vp_selector,ds     ;Set the mode data pointer

        mov     di,fn_GetMode
        Call    AllVDH

SyncCursor LABEL NEAR
        public  SyncCursor

        mov     [bp].vp_flags,vp_f_physical+vp_f_curpos+vp_f_curtype ;@@S1
        mov     di,fn_GetCursor         ;Get Cursor Info from ENVB

        jmp     AllSetCurPos            ;Return via common routine ;JOPT
SyncModeCursor ENDP

CTEXT_TUNE5 ENDS                                                        ;MDLL
        END

;@T3 = 12/13/88 TPL, Clear DX before scale cursor type, P3148
;@@B = 02/21/89 STJ, Call VDH instead of VIO for mode data, HZ00014
;@@S1 = 03/06/89 STJ, Correct the interface to the VDH, B700065
;JOPT = 03/29/89 STJ, Replace CALL/RET with jumps through subroutines
;@D549 = 11/02/89 CJJ, Seltable changes due to rangeless sessions, DCR 549
;@T52 = 01/16/90 TPL, DCR 704 work
;@WPW1 = 11/19/92 WPW, If there should be a thickness for a cusor, make sure
         that (cursor end - cursor start) > 1. This is basically for the
         Trident cards in 80x43 mode.
;MDLL  = 01/10/94 BJN, Page Tune segments for Merged DLL.
