;*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   WDHWRITE.ASM -- Buffer Write Routines for Windowable sessions

;/*****************************************************************************
;*
;* SOURCE FILE NAME = WDHWRITE.ASM
;*
;* DESCRIPTIVE NAME = BUFFERUPDATE write routines
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  Buffer Write Routines for Windowable sessions
;*
;* FUNCTIONS    WriteCellStr, WriteCharStr, WriteCharStrAttr,
;*              WriteNChar, WriteNAttr, WriteNCell
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES  LocateBuffAddr           (in WDHREAD.ASM)
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*   09/14/94  @95837             WKB, pmwinp.inc -> pmwinx.inc
;****************************************************************************/

        .286c                                     ; 286 protect mode instructions

        .xlist
        include pmwinx.inc                        ; @95837
        include pmaviop.inc

        INCLUDE struc.inc                         ; Structure macro
        INCLUDE error2.inc                        ; Subsystem error equates
        INCLUDE vdhstruc.inc                      ; Buffer update data structures
        INCLUDE vdhequ.inc                        ; Buffer update equates
        .list

        EXTRN   LocateBuffAddr:NEAR               ; Determine target/source buffer

R2CSEG  SEGMENT WORD    PUBLIC 'CODE'
        ASSUME  CS:R2CSEG,DS:NOTHING,ES:NOTHING

;/****************************************************************************
;*
;* SUBROUTINE NAME:     WriteCellStr
;*
;* DESCRIPTIVE NAME:    Video device handler write cells
;*
;* FUNCTION:    Process write cells sub-function.
;*              The cells are written to the LVB and/or PVB
;*              starting at the specified row, column location.
;*              Line wrap occurs if the end of a line is reached.
;*              Write function is terminated if the end of PVB or
;*              LVB is reached.  The number of the char/attr cells
;*              written is returned in the RepeatFactor field of
;*              the paramter block.
;*
;* ENTRY POINT: WriteCellStr
;*   LINKAGE:   Near Call from BUFFERUPDATE routine
;*
;* INPUT:
;*
;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer            (see WDHBUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see WDHBUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                                      (target data buffer - LVB, PVB)
;*   DWORD  Application data address  (source data buffer)
;*   DWORD  Application data2 address (not used in this call)
;*   WORD   Index (7)
;*   WORD   Starting row                               (target row)
;*   WORD   Starting column                            (target column)
;*   WORD   Secondary row                              (not used in this call)
;*   WORD   Secondary column                           (not used in this call)
;*   WORD   RepeatFactor                               (input and output length)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:      LVB and/or PVB = new attributes
;*              RepeatFactor = sum of char/attr pairs written
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = Error from LocateBuffAddr
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: LocateBuffAddr            (in VDHREAD.ASM)
;*
;****************************************************************************/

        PUBLIC  WriteCellStr
WriteCellStr PROC NEAR

        mov     bx, 1                             ; Set indicator for word move
        call    LocateBuffAddr                    ; On exit: BX = sel, AX = off
        .if     <nc>                              ; Continue?
            shr     cx, 1                         ; Adjust for word move
            lds     si, [si].AppDataAddr          ; Setup source address
            mov     es, bx                        ; Setup destination selector
            mov     di, ax                        ; Setup destination offset
            rep     movsw                         ; Copy cell from DS:SI to ES:DI
            sub     ax, ax                        ; Clear return code
        .endif                                    ; 
        ret                                       ; 

WriteCellStr ENDP

;/****************************************************************************
;*
;* SUBROUTINE NAME:     WriteCharStr
;*
;* DESCRIPTIVE NAME:    Video device handler write characters
;*
;* FUNCTION:    Process write characters sub-function.
;*              The characters are read from a user supplied
;*              buffer which to be placed starting a the
;*              specified row, column location within the PVB
;*              and/or LVB.  Line wrap occurs if the end of a
;*              line is reached.  Write function is terminated
;*              if the end of PVB or LVB is reached.  The number
;*              of characters written is returned in the
;*              RepeatFacter field of the parameter block.
;*
;* ENTRY POINT: WriteCharStr
;*   LINKAGE:   Near Call from BUFFERUPDATE routine
;*
;* INPUT:
;*
;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer            (see WDHBUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see WDHBUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                                      (target data buffer - LVB, PVB)
;*   DWORD  Application data address  (source data buffer)
;*   DWORD  Application data2 address (not used in this call)
;*   WORD   Index (8)
;*   WORD   Starting row                               (target row)
;*   WORD   Starting column                            (target column)
;*   WORD   Secondary row                              (not used in this call)
;*   WORD   Secondary column                           (not used in this call)
;*   WORD   RepeatFactor                               (input and output length)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:      PVB and/or LVB = new characters
;*              RepeatFactor = number of characters written
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = Error from LocateBuffAddr
;*
;* EFFECTS:     AX, BX, DI, SI, DS, ES
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: LocateBuffAddr           (in WDHREAD.ASM)
;*
;****************************************************************************/

        PUBLIC  WriteCharStr
WriteCharStr PROC NEAR

        sub     bx, bx                            ; Set indicator for byte move
        call    LocateBuffAddr                    ; On exit: BX = sel, AX = off
        .if     <nc>                              ; Continue?
            lds     si, [si].AppDataAddr          ; Setup source address
            mov     di, ax                        ; Setup destination offset

            cmp     [bp].Retrace,4
            mov     es, bx                        ; Setup destination selector
            .if     <eq>                          ;4-byte cells
                .repeat                           ; Copy char from DS:SI to ES:DI
                    movsb
                    add     di,3                  ;Skip over the attribute
                .loop
            .else                                 ;2-byte cells
                .repeat                           ; Copy char from DS:SI to ES:DI
                    movsb
                    inc     di
                .loop
            .endif
            sub     ax, ax                        ; Clear return code
        .endif                                    ; 
        ret                                       ; 

WriteCharStr ENDP

;/****************************************************************************
;*
;* SUBROUTINE NAME:     WriteCharStrAttr
;*
;* DESCRIPTIVE NAME:    Video device handler write characters
;*                      with a constant attribute
;*
;* FUNCTION:    Process write characters, attribute sub-function.
;*              The characters and attribute are read from user
;*              supplied buffers which will be placed starting
;*              at the specified row, column location within the
;*              PVB and/or LVB.  Line wrap occurs if the end of
;*              a line is reached.  Write function is terminated
;*              if the end of PVB or LVB is reached.  The number
;*              of char/attr pairs written is returned in the
;*              RepeatFacter field of the parameter block.
;*
;* ENTRY POINT: WriteCharStrAttr
;*   LINKAGE:   Near Call from BUFFERUPDATE routine
;*
;* INPUT:
;*
;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer            (see WDHBUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see WDHBUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                                      (target data buffer - LVB, PVB)
;*   DWORD  Application data address  (source data buffer)
;*   DWORD  Application data2 address (source attribue buffer)
;*   WORD   Index (9)
;*   WORD   Starting row                               (target row)
;*   WORD   Starting column                            (target column)
;*   WORD   Secondary row                              (not used in this call)
;*   WORD   Secondary column                           (not used in this call)
;*   WORD   RepeatFactor                               (input and output length)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:      PVB and/or LVB = new characters
;*              RepeatFactor = sum of char/attr pairs written
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = Error from LocateBuffAddr
;*
;* EFFECTS:     AX, BX, DI, SI, DS, ES
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: LocateBuffAddr           (in WDHREAD.ASM)
;*
;****************************************************************************/

        PUBLIC  WriteCharStrAttr
WriteCharStrAttr PROC NEAR

        sub     bx, bx                            ; Setup for byte read
        call    LocateBuffAddr                    ; On exit: BX = sel, AX = off
        .if     <nc>                              ; Continue?
            mov     di, ax                        ; Setup destination offset
            lds     si, [si].AppCellAddr          ; Setup address to attribute
            lodsb                                 ; Get attribute
            mov     ah,al

            cmp     [bp].Retrace,4
            mov     es, bx                        ; Setup destination selector
            .if     <eq>                          ;4-byte cells
                mov     dx,ax
                lodsw
                lds     si, [bp].ParmBuf          ; Setup parameter buffer addr
                lds     si, [si].AppDataAddr      ; Setup source address
                .repeat                           ; Copy attr from AL:DX to ES:DI
                    xchg    ax,dx
                    lodsb
                    stosw                         ;Move first word of cell
                    xchg    ax,dx
                    stosw                         ;Move last word of cell
                .loop
            .else                                 ;2-byte cells
                lds     si, [bp].ParmBuf          ; Setup parameter buffer addr
                lds     si, [si].AppDataAddr      ; Setup source address
                .repeat                           ; Copy byte with attr to ES:DI
                    lodsb
                    stosw
                .loop
            .endif
            sub     ax, ax                        ; Clear return code
        .endif                                    ; 
        ret                                       ; 

WriteCharStrAttr ENDP

;/****************************************************************************
;*
;* SUBROUTINE NAME:     WriteNChar
;*
;* DESCRIPTIVE NAME:    Video device handler repeat characters
;*
;* FUNCTION:    Process write character sub-function.
;*              The characters are written to either PVB or LVB
;*              starting at the specified row, column location.
;*              Line wrap ocurrs if the end of a line is reached.
;*              Write function is terminated if the end of PVB or
;*              LVB is reached.  The number of characters written
;*              is returned in the RepeatFacter field of the
;*              parameter block.
;*
;* ENTRY POINT: WriteNChar
;*   LINKAGE:   Near Call from BUFFERUPDATE routine
;*
;* INPUT:
;*
;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer            (see WDHBUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see WDHBUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                                      (target data buffer - LVB, PVB)
;*   DWORD  Application data address  (source character buffer)
;*   DWORD  Application data2 address (not used in this call)
;*   WORD   Index (10)
;*   WORD   Starting row                               (target row)
;*   WORD   Starting column                            (target column)
;*   WORD   Secondary row                              (not used in this call)
;*   WORD   Secondary column                           (not used in this call)
;*   WORD   RepeatFactor                               (input and output length)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:      PVB or LVB = new characters
;*              RepeatFactor = number of characters written
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  None
;*
;* EFFECTS:     AX, BX, DI, SI, DS, ES
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: LocateBuffAddr           (in WDHREAD.ASM)
;*
;****************************************************************************/

        PUBLIC  WriteNChar
WriteNChar PROC NEAR

        sub     bx, bx                            ; Setup indicator for byte move
        call    LocateBuffAddr                    ; On exit: BX = sel, AX = off
        .if     <nc>                              ; Continue?
            lds     si, [si].AppDataAddr          ; Setup source address
            mov     di, ax                        ; Setup destination offset
            lodsb                                 ; Get source character

            mov     dx,[bp].Retrace
            dec     dx                            ;Compute attribute size

            mov     es, bx                        ; Setup destination selector
            .repeat                               ; Copy char from AL to ES:DI
                stosb
                add     di,dx                     ;Skip over the attribute
            .loop
            sub     ax, ax                        ; Clear return code
        .endif
        ret

WriteNChar ENDP

;/****************************************************************************
;*
;* SUBROUTINE NAME:     WriteNAttr
;*
;* DESCRIPTIVE NAME:    Video device handler repeat attributes
;*
;* FUNCTION:    Process repeat write attributes sub-function.
;*              The attributes are written to either PVB or LVB
;*              starting at the specified row, column location.
;*              Line wrap occurs if the end of a line is reached.
;*              Write function is terminated if the end of PVB or
;*              LVB is reached.  The number of the attributes
;*              written is returned in the RepeatFactor field
;*              of the paramter block.
;*
;* ENTRY POINT: WriteNAttr
;*   LINKAGE:   Near Call from BUFFERUPDATE routine
;*
;* INPUT:
;*
;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer            (see WDHBUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see WDHBUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                                      (target data buffer - LVB, PVB)
;*   DWORD  Application data address  (source attribute buffer)
;*   DWORD  Application data2 address (not used in this call)
;*   WORD   Index (11)
;*   WORD   Starting row                               (target row)
;*   WORD   Starting column                            (target column)
;*   WORD   Secondary row                              (not used in this call)
;*   WORD   Secondary column                           (not used in this call)
;*   WORD   RepeatFactor                               (input and output length)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:      LVB and/or PVB = new attributes
;*              RepeatFactor = number of attributes written
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = Error from LocateBuffAddr
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: LocateBuffAddr            (in WDHREAD.ASM)
;*
;****************************************************************************/

        PUBLIC  WriteNAttr
WriteNAttr PROC NEAR

        sub     bx, bx                            ; Set indicator for byte move
        call    LocateBuffAddr                    ; On exit: BX = sel, AX = off
        .if     <nc>                              ; Continue?
            lds     si, [si].AppDataAddr          ; Setup source address
            mov     di, ax                        ; Setup destination offset
            lodsb                                 ; Get source attribute

            cmp     [bp].Retrace,4
            mov     es, bx                        ; Setup destination selector
            .if     <eq>                          ;4-byte cells
                mov     dl,al
                lodsw
                .repeat                           ; Copy attr from AL:DX to ES:DI
                    inc     di
                    xchg    ax,dx
                    stosb                         ;Move first byte of attribute
                    xchg    ax,dx
                    stosw                         ;Move last word of attribute
                .loop
            .else                                 ;2-byte cells
                .repeat                           ; Copy attr from AL to ES:DI
                    inc     di
                    stosb
                .loop
            .endif
            sub     ax, ax                        ; Clear return code
        .endif
        ret

WriteNAttr ENDP

;/****************************************************************************
;*
;* SUBROUTINE NAME:     WriteNCell
;*
;* DESCRIPTIVE NAME:    Video device handler repeat cells
;*
;* FUNCTION:    Process write cells sub-function.
;*              The cells are written to either PVB or LVB
;*              starting at the specified row, column location.
;*              Line wrap ocurrs if the end of a line is reached.
;*              Write function is terminated if the end of PVB
;*              or LVB is reached.  The number of cells written
;*              is returned in the RepeatFacter field of the
;*              parameter block.
;*
;* ENTRY POINT: WriteNCell
;*   LINKAGE:   Near Call from BUFFERUPDATE routine
;*
;* INPUT:
;*
;* SS:BP  --->  Stack frame                        (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer            (see WDHBUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see WDHBUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                                      (target data buffer - LVB, PVB)
;*   DWORD  Application data address  (source cell buffer)
;*   DWORD  Application data2 address (not used in this call)
;*   WORD   Index (12)
;*   WORD   Starting row                               (target row)
;*   WORD   Starting column                            (target column)
;*   WORD   Secondary row                              (not used in this call)
;*   WORD   Secondary column                           (not used in this call)
;*   WORD   RepeatFactor                               (input and output length)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:      PVB or LVB = new characters
;*              RepeatFactor = sum of char/attr pairs written
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = Error from LocateBuffAddr
;*
;* EFFECTS:     AX, BX, DI, SI, DS, ES
;*
;* INTERNAL REFERENCES: None
;*
;* EXTERNAL REFERENCES: LocateBuffAddr           (in WDHREAD.ASM)
;*
;****************************************************************************/

        PUBLIC  WriteNCell
WriteNCell PROC NEAR

        sub     bx, bx                            ; Set indicator for byte move
        call    LocateBuffAddr                    ; On exit: BX = sel, AX = off
        .if     <nc>                              ; Continue?
            lds     si, [si].AppDataAddr          ; Setup source address
            mov     di, ax                        ; Setup destination offset
            lodsw                                 ; Get source character

            cmp     [bp].Retrace,4
            mov     es, bx                        ; Setup destination selector
            .if     <eq>                          ;4-byte cells
                mov     dx,ax
                lodsw                             ;Get second word of cell
                .repeat
                    xchg    ax,dx
                    stosw                         ;Move first word of cell
                    xchg    ax,dx
                    stosw                         ;Move second word of cell
                .loop
            .else                                 ;2-byte cells
                rep     stosw                     ; Copy cell from DS:SI to ES:DI
            .endif
            sub     ax, ax                        ; Clear return code
        .endif
        ret

WriteNCell ENDP

R2CSEG  ENDS
        END
