;*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
;*   01/29/91  MS00               TPL, Convert IFDEF to IF
;*   01/29/91  MS07               TPL, Debug logic added
;*   02/01/94  Changeteam 76508   Fix for "expand" mode on Thinkpad 350 FS
;****************************************************************************/

;/*
;**        Include files
;*/

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

        .386p                                                           ;@T71

;/*
;**        Local variables
;*/

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]>

IF FONT_SUPPORT                         ; Loadable fonts? ;@S4          ;MS00

        EXTRN   _CharFontBegin:FAR
        EXTRN   CHARFONTEND:FAR

ENDIF   ;FONT_SUPPORT                                                   ;MS00

R2CSEG  SEGMENT BYTE  PUBLIC  'CODE' USE16                              ;@T71
        ASSUME  CS: R2CSEG, DS: DGROUP, SS: DGROUP, ES: DGROUP

IFE VDH8514A                            ; IF NOT VDH8514A               ;MS00

;/****************************************************************************
;*
;*  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
;*
;****************************************************************************/

_Transfer   PROC    FAR
            PUBLIC  _Transfer

            push    bp
            mov     bp, sp
            push    ds

            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 3>      ;Odd number of bytes to move ;@S8,@T71
                push    cx                                              ;@T71
                shr     cx,2            ;Compute number of dwords ;@S8  ;@T71
                rep     movsd           ;Move all full dwords ;@S8      ;@T71
                pop     cx                                              ;@T71
                and     cx,3                                            ;@T71
                rep     movsb           ;Move remaining byte ;@S8       ;@T71
            .else                       ;@S8
                shr     cx,2            ;Compute number of dwords ;@S8  ;@T71
                .if     <z>             ;@S8
                    mov     cx,4000h    ;Compensate for CX=0 ==> CX=64K ;@S8,@T71
                .endif                  ;@S8
                rep     movsd           ;Move all full words ;@S8       ;@T71
            .endif                      ;@S8
            @SwitchIfReverse

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

                @SwitchIfReverse
                shr     cx,2            ;Compute number of dwords ;@S8  ;@T71
                rep     movsd           ;Move all full dwords ;@S8      ;@T71
                .if     <bit bx and 3>  ;Odd number of bytes to move ;@S8,@T71
                    rep     movsb       ;Move remaining byte ;@S8       ;@T71
                .endif                  ;@S8
                @SwitchIfReverse
            .endif

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

            pop     ds
            pop     bp

            ret
_Transfer   ENDP

ENDIF   ;NOT VDH8514A                                                   ;MS00

IF FONT_SUPPORT                         ; Loadable fonts? ;@S4          ;MS00

;/****************************************************************************
;*
;*  SUBROUTINE NAME: _AccessFont
;*
;*  DESCRIPTIVE NAME: Load the specified font into the font buffer
;*
;*  FUNCTION: _AccessFont is called by SetHWMode to load a ROM font,
;*            and by SetCurrentFont to load a user specified font.
;*
;*  ENTRY POINT: _AccessFont
;*    LINKAGE:   CALL FAR
;*
;*  INPUT: (Passed on stack)
;*             DWORD  FontData ( far pointer to Font to load )
;*             DWORD  VideoFontBuffer (far pointer to font buffer )
;*             WORD   BoxHeight (vertical resolution/character rows )
;*             WORD   BoxWidth  (horizontal resolution/character cols)
;*            DWORD   BaseFontPtr(8*X font corresponding to 9*X font)
;*
;*  EXIT-NORMAL: Specified video text font is loaded.
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;****************************************************************************/

_AccessFont PROC    FAR
            PUBLIC  _AccessFont

            push    bp
            mov     bp, sp
            push    ds
            push    es
            push    di
            push    si

            .if     < Direction ne GET_ROMCP > ;@C17
                call    _CharFontBegin  ;  Map font buffer at A0000
            .endif                      ;@C17

            lds     si, ROMFontPtr      ; ds:si = ROM font to be loaded
            mov     dx, BoxHeight       ; 8, 14, or 16

            mov     ax,BaseFontLow
            or      ax,BaseFontHigh
            .if     <nz>                ;Base Font Ptr specified
                mov     ax, SEG BldFont
                mov     es, ax
                mov     di, OFFSET BldFont ;es:di = font construction buffer

                mov     cx, dx          ; BoxHeight 14, 16
                xchg    cl, ch          ; BoxHeight * 256
                shr     cx, 2           ; calculate number of dwords    ;@T71

                push    ds              ; save 9*X ROM font address
                push    si

;/*
;**        Copy the corresponding 8*X font to the bldfont buffer
;*/

                lds     si, BaseFontPtr ; ds:si = 8*X ROM font buffer
                rep     movsd           ; move the 8*X font             ;@T71

                pop     si
                pop     ds              ; ds:si = 9*X ROM font buffer

;/*
;**        Copy the 9*X font to the font buffer
;*/

                lodsb                   ; get a code point value
                .repeat
                    mul     dl          ; calculate the offset
                    mov     di, OFFSET BldFont ;es:di = font constr buffer
                    add     di, ax      ; set the destination offset
                    mov     cx, dx      ; set up the move count (bytes)
                    rep     movsb       ; Refresh one character of the font
                    lodsb               ; get the next code point value
                    and     al, al      ; see if zero
                .until  z

                push    es
                pop     ds
                mov     si, OFFSET BldFont ;ds:si = font construction buffer
            .endif

            les     di, VideoFontPtr    ; es:di = Font buffer in PVB
                                        ; ds:si = font to be loaded

            mov     ax, 256             ; For all 256 characters

            .if     < Direction eq SET >

                cmp     dx,16                                           ;76508
                jne     short no_tall_font                              ;76508
            .repeat                                                     ;76508
                push    ax                                              ;76508
                mov     cx,dx           ; cx = scan count               ;76508
                dec     cx              ; do one less                   ;76508
                rep     movsb                                           ;76508
                lodsb                                                   ;76508
                stosb                                                   ;76508
                stosb                                                   ;76508
                stosb                                                   ;76508
                stosb                                                   ;76508
                add     di,32-3                                         ;76508
                sub     di,dx                                           ;76508
                pop     ax                                              ;76508
                dec     ax                                              ;76508
            .until z                                                    ;76508
                jmp     short AF_Done                                   ;76508
no_tall_font:                                                           ;76508


                .repeat
                    mov     cx, dx
                    rep     movsb       ; Refresh one character of the font
                    add     di, 32
                    sub     di, dx
                    dec     ax
                .until  z
            .else                       ; PTM 2895
                .if     < Direction eq GET >
                    .repeat
                        mov     cx, dx
                        rep     movsb   ; Refresh one character of the font
                        add     si, 32  ; skip extra bytes in PVB
                        sub     si, dx
                        dec     ax
                    .until  z
                .else                   ; GET_ROMCP
                    .repeat
                        mov     cx, dx
                        rep     movsb   ; Refresh one character of the font
                        dec     ax
                    .until  z
                .endif
            .endif

AF_Done:                                                                ;@76508

            .if     < Direction ne GET_ROMCP > ;@C17
                push    ModeColor
                call    CHARFONTEND     ; Done loading font
            .endif                      ;@C17

            pop     si
            pop     di
            pop     es
            pop     ds
            pop     bp

            ret
_AccessFont ENDP

ENDIF   ;FONT_SUPPORT                   ;@S4                            ;MS00

IF DEBUG                                                        ;MS07 - BEGIN
;/****************************************************************************
;*
;*  SUBROUTINE NAME: int3
;*
;*  DESCRIPTIVE NAME: callable int3 for debugging C modules
;*
;*  FUNCTION: Execute an INT 3 instruction to enter kernel
;*            debugger, then return to the caller.
;*
;*  ENTRY POINT: int3
;*    LINKAGE:   CALL FAR
;*
;*  INPUT: NONE
;*
;*  EXIT-NORMAL: no state changes
;*
;*  INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;*  EXTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;****************************************************************************/

PUBLIC       _int3
_int3  PROC  FAR

        int     3
        ret

_int3  ENDP

ENDIF   ;DEBUG                                                  ;MS07 - END

R2CSEG  ENDS
        END

