;*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    60,132
        TITLE   VDHRING3.ASM -- Video Device Handler Ring 3 Routines

;/*****************************************************************************
;*
;* SOURCE FILE NAME = VDHRING3.ASM
;*
;* DESCRIPTIVE NAME = Video Device Handler Ring 3 Routines
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  This module contains ring 3 routines which can be
;*              execute a considerable amount faster in assembly as
;*              opposed to C.  This primarily consists of data transfer
;*              to and from the physical display buffer.
;*
;* FUNCTIONS    _Transfer, _AccessFont, _int3
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES  NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*   04/14/89  @S4        B701111 STJ, Handle Transfer count of 0 as if it were
;*                                64K,
;*   04/26/89  @C17       B701338 CJJ, Don't map to real font buffer if getting
;*                        B701338 specified font  (B701352 also)
;*   05/03/89  @S8        B701127 STJ, Performance optimizations
;*   07/06/90  @T71       B714347 TPL, Allow Shell to make AVIO calls, Hursley
;*                                DCR 25177
;****************************************************************************/

        .286p

;-----------------------------------------------------------------------
;       Include files
;-----------------------------------------------------------------------

        include struc.inc               ; Structured assembly macros
        include vdhctl.inc              ; Conditional assembly control
        include vdh.inc                 ; Definitions
        include vdhdata.inc             ; Global data

        EXTRN   DOSUNLOCKSEG:FAR                                        ;@TL9

;-----------------------------------------------------------------------
;       Local variables
;-----------------------------------------------------------------------
;STJFMT,,16

CallTableOFF    equ     WORD PTR [bp+6]
CallTableSEL    equ     WORD PTR [bp+8]

SourcePtr       equ     DWORD PTR [bp+6]
DestPtr         equ     DWORD PTR [bp+10]
SourceSIZE      equ     WORD PTR [bp+14]
Mode            equ     WORD PTR [bp+16]

ROMFontPtr      equ     DWORD PTR [bp+6]
VideoFontPtr    equ     DWORD PTR [bp+10]
BoxHeight       equ     WORD PTR [bp+14]
BoxWidth        equ     WORD PTR [bp+16]
BaseFontPtr     equ     DWORD PTR [bp+18]
BaseFontLow     equ     WORD PTR [bp+18]
BaseFontHigh    equ     WORD PTR [bp+20]
Direction       equ     <WORD PTR [bp+22]>
ModeColor       equ     <WORD PTR [bp+24]>

;STJFMT,

        IFDEF   FONT_SUPPORT            ; Loadable fonts? ;@S4

            EXTRN   _CharFontBegin:FAR
            EXTRN   CHARFONTEND:FAR

        ENDIF                           ; IFDEF FONT_SUPPORT

R2CSEG  SEGMENT BYTE  PUBLIC  'CODE'
        ASSUME  CS: R2CSEG, DS: DGROUP, SS: DGROUP, ES: DGROUP

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME:  GetLimit                                 J-KKJ   */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Get Segment Limit Value                          */
;/*                                                                     */
;/*  FUNCTION:  Get Segment Limit Value                                 */
;/*                                                                     */
;/*  ENTRY POINT:  GetLimit                                             */
;/*    LINKAGE:   CALL NEAR                                             */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD  Selector                                          */
;/*                                                                     */
;/*  EXIT-NORMAL: AX - Limit Value                                      */
;/*                    0 - Error                                        */
;/*                                                                     */
;/*  EFFECTS: AX - Limit Value                                          */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
;
;;      Limit = Call GetLimit ( Segment )
;;      Return  Limit Value
;

_GetLimit PROC  near
        PUBLIC  _GetLimit

        push    bp
        mov     bp, sp
        push    bx

        mov     ax, 0                   ; Error Set
        mov     bx, ss:[bp+4]           ; Get Selector J-KK129
        lsl     ax, bx

        pop     bx
        pop     bp
        ret
_GetLimit ENDP

        IFNDEF  VDH8514A

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: _Transfer                                         */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Transfer data to/from physical display buffer    */
;/*                                                                     */
;/*  FUNCTION: _Transfer is called by routines performing save/restore  */
;/*            operations on the physical display buffer.               */
;/*                                                                     */
;/*  ENTRY POINT: _Transfer                                             */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             DWORD SourceAddressPTR (far pointer to source buffer)   */
;/*             DWORD DestAddressPTR (far pointer to destination buffer)*/
;/*             WORD  Length ( Size of transfer )                       */
;/*             WORD  Direction (Normal transfer or reverse transfer)   */
;/*                                                                     */
;/*  EXIT-NORMAL: Data is transfered                                    */
;/*                                                                     */
;/*  EFFECTS: Pointer destination buffer is altered to reflect current  */
;/*           placement in buffer.                                      */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/

_Transfer   PROC    FAR
            PUBLIC  _Transfer

            push    bp
            mov     bp, sp
            push    ds
            push    dx                                                  ;@TL9

            lds     si, SourcePtr
            lds     si, DWORD PTR ds:[si] ; ds:si points to PVB section

            les     di, DestPtr
            les     di, DWORD PTR es:[di] ; es:di points to Huge area

            mov     cx, SourceSIZE      ; Number of bytes to transfer

            mov     ax, 0FFFFh          ; Segment size - 1
            sub     ax, di              ; ax = amount left -1

            sub     bx,bx               ;Assume everything will fit ;@S4
            .if     <nonzero di>        ;Not at start of segment ;@S4
                inc     ax              ; ax = amount left
                mov     bx, cx          ; bx = section size
                sub     bx, ax          ; bx = Amount not copied
                .if     < nc >          ; PVBLength > room left in huge segment
                    mov     cx, ax      ; cx = room left in huge segment
                .else
                    xor     bx, bx      ; Everything will fit
                .endif
            .endif

            @SwitchIfReverse
            .if     <bit cx and 1>      ;Odd number of bytes to move ;@S8
                shr     cx,1            ;Compute number of words ;@S8
                rep     movsw           ;Move all full words ;@S8
                movsb                   ;Move remaining byte ;@S8
            .else                       ;@S8
                shr     cx,1            ;Compute number of words ;@S8
                .if     <z>             ;@S8
                    mov     cx,8000h    ;Compensate for CX=0 ==> CX=64K ;@S8
                .endif                  ;@S8
                rep     movsw           ;Move all full words ;@S8
            .endif                      ;@S8
            @SwitchIfReverse

            mov     dx, es              ;                               ;@TL9
            mov     es, cx              ;Clear es before marking        ;@TL9
            push    dx                  ;  segment LRU                  ;@TL9
            call    DOSUNLOCKSEG        ;                               ;@TL9

            .if     <nonzero bx>        ; Segment overflow ;@S4
                push    ds              ; Save current data seg
                mov     ax, SEG _HugeShift
                mov     ds, ax          ; Restore original data seg
;@TL9           mov     ax, es
                add     dx, _HugeShift  ; find next selector            ;@TL9
                pop     ds              ; Restore current data segment
                mov     es, dx          ; es:di = next huge segment     ;@TL9
                mov     cx, bx          ; get leftover amount

                @SwitchIfReverse
                shr     cx,1            ;Compute number of words ;@S8
                rep     movsw           ;Move all full words ;@S8
                .if     <bit bx and 1>  ;Odd number of bytes to move ;@S8
                    movsb               ;Move remaining byte ;@S8
                .endif                  ;@S8
                @SwitchIfReverse

                mov     dx, es          ;                               ;@TL9
                mov     es, cx          ;Clear es before marking        ;@TL9
                push    dx              ;  segment LRU                  ;@TL9
                call    DOSUNLOCKSEG    ;                               ;@TL9
            .endif

            lds     si, DestPtr
            mov     WORD PTR ds:[si], di ; Replace old offset with new
;@TL9       mov     ax, es               ; Replace old selector with new
            mov     WORD PTR ds:[si+2], dx

            pop     dx                                                  ;@TL9
            pop     ds
            pop     bp

            ret
_Transfer   ENDP

        ENDIF                           ; IFNDEF VDH8514A

R2CSEG  ENDS
        END
