;*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    XGAWRITE.ASM -- Common Buffer Write Routines for EGA, VGA, BGA
;/*****************************************************************************
;*
;* SOURCE FILE NAME = XGAWRITE.ASM
;*
;* DESCRIPTIVE NAME = Common Buffer Write Routines for EGA, VGA, BGA
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  This module contains routines that run at ring 2:
;*              Common Buffer Write Routines for EGA, VGA, BGA
;*
;* FUNCTIONS    WriteCellStr, WriteCharStr, WriteCharStrAttr,
;*              WriteNChar, WriteNAttr, WriteNCell
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES   LocateBuffAddr  (in XGAREAD.ASM)
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG        APAR    CHANGE DESCRIPTION
;*   --------  ----------  -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx   xxxxxxx
;*   03/25/89  @P1         D132    TPL, DCR 132 changes
;*   01/29/91  MS00                TPL, Convert IFDEF to IF
;*   01/29/91  MS01                TPL, Rollover MS's runtime check
;*   01/29/91  MS01                for CGA speedup
;*   04/11/91              D1348   NAKADA, Enable DBCS support in Vio-Window
;*   10/03/89  J-KK1003            KKJ, Change Translate.
;*   10/16/89  J-KK1016            KKJ, Background attribute is not effective in Epoch Color.
;*   10/25/89  J-KK1025            KKJ, Make WriteCharStrAttr proc More Reliable.
;*                                      Add Reverse bit Handling and Change Translate proc.
;*   11/01/89  J-KK1101            KKJ, Add Sub_attribute2 for ATLAS 82x25 Mode.
;*   11/29/89  J-KK1129            KKJ, Limit Check for NCELL and NCHAR with DBCS.
;*   01/17/90  J-KK0117            KKJ,     Fix : Attribute Conversion for Epoch Mono
;*   01/18/90  J-KK0118            KKJ, Change Translate for Epoch Color Mode.
;*                                      Blue+Reverse ---> BG Blue Color.
;*   01/19/90  J-KK0119            KKJ, For Epoch Mono Mode, Invisible+Reverse --> Invisible
;****************************************************************************/

        .286c                           ; 286 protect mode instructions

        .xlist
        INCLUDE struc.inc               ; Structure macro
        INCLUDE error2.inc              ; Subsystem error equates
        INCLUDE vdhequ.inc              ; Buffer update equates
        INCLUDE vdhstruc.inc            ; Buffer update data structures
        INCLUDE xgamac.inc              ;@P1
        INCLUDE cga2epo.inc             ;                               ;j-ys717
        .list

        EXTRN   SetBuffAddr:NEAR        ; Determine target/source buffer;@P1
        EXTRN   CheckDBCS:NEAR          ; Check DBCS                    J-KK1129

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

WCSTB   DW      OFFSET R2CSEG:WriteCStrE ; Epoch Format
        DW      OFFSET R2CSEG:WriteCStrC ; Common Format
        DW      OFFSET R2CSEG:WriteCStrA ; Atlas 3 byte Attribute Format
        DW      OFFSET R2CSEG:WriteCStrB ; U.S. Emualtion Format

WNCharT DW      OFFSET R2CSEG:WriteNCharE ; Epoch Format
        DW      OFFSET R2CSEG:WriteNCharC ; Common Format
        DW      OFFSET R2CSEG:WriteNCharA ; Atlas 3 byte Attribute Format
        DW      OFFSET R2CSEG:WriteNCharB ; U.S. Emualtion Format

WNCellT DW      OFFSET R2CSEG:WriteNCellE ; Epoch Format
        DW      OFFSET R2CSEG:WriteNCellC ; Common Format
        DW      OFFSET R2CSEG:WriteNCellA ; Atlas 3 byte Attribute Format
        DW      OFFSET R2CSEG:WriteNCellB ; U.S. Emualtion Format

WNAttrT DW      OFFSET R2CSEG:WriteNAttrE ; Epoch Format
        DW      OFFSET R2CSEG:WriteNAttrC ; Common Format
        DW      OFFSET R2CSEG:WriteNAttrA ; Atlas 3 byte Attribute Format
        DW      OFFSET R2CSEG:WriteNAttrB ; U.S. Emualtion Format


        EXTRN   WriteCStrE:NEAR         ;Epoch Format
        EXTRN   WriteCStrC:NEAR         ;Common Format
        EXTRN   WriteNCharE:NEAR        ;Epoch Format
        EXTRN   WriteNCharC:NEAR        ;Common Format
        EXTRN   WriteNCellE:NEAR        ;Epoch Format
        EXTRN   WriteNCellC:NEAR        ;Common Format
        EXTRN   WriteNAttrE:NEAR        ;Epoch Format
        EXTRN   WriteNAttrC:NEAR        ;Common Format

        EXTRN   WriteCStrA:NEAR         ;Atlas 3 byte Attribute Format
        EXTRN   WriteCStrB:NEAR         ;U.S. Emualtion Format
        EXTRN   WriteNCharA:NEAR        ;Atlas 3 byte Attribute Format
        EXTRN   WriteNCharB:NEAR        ;U.S. Emualtion Format
        EXTRN   WriteNCellA:NEAR        ;Atlas 3 byte Attribute Format
        EXTRN   WriteNCellB:NEAR        ;U.S. Emualtion Format
        EXTRN   WriteNAttrA:NEAR        ;Atlas 3 byte Attribute Format
        EXTRN   WriteNAttrB:NEAR        ;U.S. Emualtion Format

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* 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 XGABUFUP.ASM)      *
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.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)               *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************

        PUBLIC  WriteCellStr
WriteCellStr PROC NEAR

        mov     bx, 1                   ; Move by buffer byte count
        call    SetBuffAddr             ; On exit: BX = sel, AX = off;@P1
        .if     <nc>                    ; Continue?
            shr     cx, 1               ; Adjust for word move
            lds     si, [si].AppDataAddr ; Setup source address
            mov     es, bx              ; Setup LVB selector
            mov     bx, [bp].Sub_Format ; Setup Format Index           ;J-KK0828
            mov     di, ax              ; Setup LVB offset

            mov     [bp].Sub_index,WCELL ; save function index
            mov     [bp].Sub_offset,di  ; save offset for write op
            mov     [bp].Sub_length,cx  ; save length for write op

            call    cs:WCSTB[bx]        ; Dispatch to handler
            sub     ax, ax              ; Clear return code

        .endif                          ; 
        ret                             ; 

WriteCellStr ENDP

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* 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 XGABUFUP.ASM)      *
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.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 XGAREAD.ASM)                *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************

        PUBLIC  WriteCharStr
WriteCharStr PROC NEAR

        sub     bx, bx                  ; Move done in terms of cells
        call    SetBuffAddr             ; On exit: BX = sel, AX = off;@P1
        .if     <nc>                    ; Continue?
            lds     si, [si].AppDataAddr ; Setup source address
            mov     es, bx              ; Setup LVB selector
            mov     bx, [bp].Sub_Format ; Setup Format Index           ;J-KK0828
            mov     di, ax              ; Setup LVB offset

            mov     [bp].Sub_index,WCHAR ; save function index
            mov     [bp].Sub_offset,di  ; save offset for write op
            mov     [bp].Sub_length,cx  ; save length for write op

            call    cs:WCSTB[bx]        ; Dispatch to handler
            sub     ax, ax              ; Clear return code

        .endif                          ; 
        ret                             ; 

WriteCharStr ENDP

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* 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 XGABUFUP.ASM)      *
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.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 XGAREAD.ASM)                *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************

        PUBLIC  WriteCharStrAttr
WriteCharStrAttr PROC NEAR

        sub     bx, bx                  ; Operation in terms of cells
        call    SetBuffAddr             ; On exit: BX = sel, AX = off
        .if     <nc>                    ; Continue?
            push    ax                  ; 

            lds     si, [si].AppCellAddr ; Setup address to attribute

            test    [bp].Sub_Flags, CGAAttr ; CGA Translation          ;J-KK0828
            .if     < z > and           ; Not From WrtTTY              ;J-KK1025
            .if     < [bp].Sub_attrnum le 1 > ; Attr# <= 1             ;J-KK1025
                xor     ah, ah          ;                              ;J-KK1025
                lodsb                   ; Get attribute                ;J-KK1025
                mov     word ptr [bp].Sub_attribute,ax ; Store Attribute ;j-ys717
            .else                       ; Attr is COMMON or 3 bytes.   ;J-KK1025
                lodsw                   ; Get attribute 0 and 1         ;j-ys717
                mov     word ptr [bp].Sub_attribute,ax ; Store Attribute ;j-ys717
                xor     ah, ah          ;                              ;J-KK1101
                lodsb                   ; Get attribute 2              ;J-KK1101
                mov     word ptr [bp].Sub_attribute2,ax ; Store Attr2  ;J-KK1101
            .endif                      ;                              ;J-KK1025



            pop     ax                  ; 
            lds     si, [bp].ParmBuf    ; Setup parameter buffer addr
            lds     si, [si].AppDataAddr ; Setup source address
            mov     es, bx              ; Setup LVB selector
            mov     bx, [bp].Sub_Format ; Setup Format Index           ;J-KK0828
            mov     di, ax              ; Setup LVB offset

            mov     [bp].Sub_index,WCHARA ; save function index
            mov     [bp].Sub_offset,di  ; save offset for write op
            mov     [bp].Sub_length,cx  ; save length for write op

            call    cs:WCSTB[bx]        ; Dispatch to handler
            sub     ax, ax              ; Clear return code


        .endif                          ; 
        ret                             ; 

WriteCharStrAttr ENDP

;******************************************************************************
;*  Attribute Translation.                                      J-KK1003      *
;*    Input  : AX - Common Attr0 and 1                                        *
;*             AH - 7 : BG Hint           AL - 7 : Underline          J-KK0118*
;*                  6 : BG Red                 6 : Reverse                    *
;*                  5 : BG Green               5 : Blink                      *
;*                  4 : BG Blue                4 :            FG Red          *
;*                  3 : FG Hint                3 : V-Grid                     *
;*                  2 : FG Red                 2 : H-Grid                     *
;*                  1 : FG Green               1 :            FG Green        *
;*                  0 : FG Blue                0 :            FG Blue         *
;*                                                                            *
;*    Output : AL - Epoch Attr                                                *
;******************************************************************************
Translate proc  near                    ;j-ys717
        PUBLIC  Translate               ;j-ys717
        push    bx                      ;j-ys717
        push    ds                      ;j-ys717
        push    _data                   ;j-ys717
        pop     ds                      ;j-ys717

        .if     < [bp].Sub_colors e 4 > ; Epoch Color                   J-KK1003

            .if     < bit ah and 40h >  ; Reverse ?                     J-KK0118
                .if     < bit al nand 07h > ; FG Color Off              J-KK0118
                    mov     bl, ah      ;                               J-KK0118
                    mov     bh, ah      ;                               J-KK0118
                    shr     bh, 2       ; Get Red Bit                   J-KK0118
                    and     bx, 0403h   ; Get Red, Green & Blue         J-KK0118
                    or      bl, bh      ;                               J-KK0118
                    mov     al, bl      ; Change Attr                   J-KK0118
                .endif                  ;                               J-KK0118
                mov     bx, offset cga2epoch ;                          J-KK0118
                xlat                    ; Get Color                     J-KK0118
                or      al, 04h         ; Force Reverse                 J-KK0118

            .else                       ; Not Reverse
                and     al, 07h         ; Only ForeGround Attr          J-KK1025
                mov     bx, offset cga2epoch ;                              J-KK1003
                xlat                    ; Get Color                     J-KK1003
            .endif                      ;                               J-KK0118

        .else                           ; Epoch Mono                    J-KK1003

            .if     < bit al nand 77h > or ; Invisible ?                J-KK0117
            .if     < bit ah and 40h > and  ; Reverse ?                 J-KK0119
            .if     < bit ah nand 13h > ; FG Color Off                  J-KK0119
                mov     al, 0cch        ;                               J-KK0117
            .else                       ;                               J-KK0117
                and     al, 08h         ; Only Mask For Intensity       J-KK0117
                .if     < bit ah and 20h > ; Blink                      J-KK0117
                    or      al, 80h     ; Set                           J-KK0117
                .endif                  ;                               J-KK0117
                .if     < bit ah and 80h > ; UnderScore                 J-KK0117
                    or      al, 40h     ; Set                           J-KK0117
                .endif                  ;                               J-KK0117
                .if     < bit ah and 40h > ; Reverse                    J-KK0117
                    or      al, 04h     ; Set                           J-KK0117
                .endif                  ;                               J-KK0117
            .endif                      ;                               J-KK0117


        .endif                          ;                               J-KK1003

        .if     < bit ah and 08h >      ; V-Grid                        J-KK1003
            or      al, 10h             ; Set                           J-KK1003
        .endif                          ;                               J-KK1003
        .if     < bit ah and 04h >      ; H-Grid                        J-KK1003
            or      al, 20h             ; Set                           J-KK1003
        .endif                          ;                               J-KK1003



        pop     ds                      ;j-ys717
        pop     bx                      ;j-ys717
        ret                             ;j-ys717
Translate endp                          ;j-ys717

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* 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 XGABUFUP.ASM)      *
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.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 XGAREAD.ASM)                *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************

        PUBLIC  WriteNChar
WriteNChar PROC NEAR

        sub     bx, bx                  ; Operation in terms of cells
        call    SetBuffAddr             ; On exit: BX = sel, AX = off
        .if     <nc>                    ; Continue?
            lds     si, [si].AppDataAddr ; Setup source address
            mov     es, bx              ; Setup LVB selector
            mov     bx, [bp].Sub_Format ; Setup Format Index           ;J-KK0828
            mov     di, ax              ; Setup LVB offset
            lodsb                       ; Get source character

            mov     [bp].Sub_offset,di  ; save offset for write op

            call    CheckDBCS           ; DBCS Char ?                   J-KK1129
            .if     c                   ;                               J-KK1129
                mov     dx, [bp].Sub_Buffsize ; Limit Check             J-KK1129
                sub     dx, di          ;                               J-KK1129
                shr     dx, 2           ;                               J-KK1129
                .if     < [bp].Sub_attrnum g 1 > ;                      J-KK1129
                    shr     dx, 1       ;                               J-KK1129
                .endif                  ; DX - Double Cell Count        J-KK1129
                .if     < zero dx >     ;                               J-KK1129
                    jmp     WriteNChar_Exit ;                           J-KK1129
                .endif                  ;                               J-KK1129
                .if     < cx g dx >     ;                               J-KK1129
                    mov     cx, dx      ;                               J-KK1129
                .else                   ;                               J-KK1129
                    mov     dx, cx      ;                               J-KK1129
                .endif                  ;                               J-KK1129
                shl     dx, 1           ; Adjust word offset length     J-KK1129
                mov     [bp].Sub_length, dx ;   for DBCS chars          J-KK1129
                stc                     ;                               J-KK1129
            .else                       ;                               J-KK1129
                mov     [bp].Sub_length,cx ; save length for write op
            .endif                      ;                               J-KK1129

            call    cs:WNCharT[bx]      ; Dispatch to handler
WriteNChar_Exit:                        ;                               J-KK1129
            sub     ax, ax              ; Clear return code

        .endif                          ; 
        ret                             ; 

WriteNChar ENDP

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* 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 XGABUFUP.ASM)      *
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.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 XGAREAD.ASM)               *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************

        PUBLIC  WriteNAttr
WriteNAttr PROC NEAR

        sub     bx, bx                  ; Operation in terms of cells
        call    SetBuffAddr             ; On exit: BX = sel, AX = off
        .if     <nc>                    ; Continue?
            lds     si, [si].AppDataAddr ; Setup source address
            mov     es, bx              ; Setup LVB selector
            mov     bx, [bp].Sub_Format ; Setup Format Index           ;J-KK0828
            mov     di, ax              ; Setup LVB offset
            lodsb                       ; Get source attribute

            mov     [bp].Sub_offset,di  ; save offset for write op
            mov     [bp].Sub_length,cx  ; save length for write op

            call    cs:WNAttrT[bx]      ; Dispatch to handler
            sub     ax, ax              ; Clear return code

        .endif                          ; 
        ret                             ; 

WriteNAttr ENDP

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* 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 XGABUFUP.ASM)      *
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.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 XGAREAD.ASM)                *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************

        PUBLIC  WriteNCell
WriteNCell PROC NEAR

        sub     bx, bx                  ; Operation in terms of cells
        call    SetBuffAddr             ; On exit: BX = sel, AX = off
        .if     <nc> near               ; Continue?
            lds     si, [si].AppDataAddr ; Setup source address
            mov     es, bx              ; Setup LVB selector
            mov     bx, [bp].Sub_Format ; Setup Format Index           ;J-KK0828
            mov     di, ax              ; Setup LVB offset
            lodsw                       ; Get source character

            push    ax                  ; Get Attr0/1                  ;J-KK1003
            .if     < [bp].Sub_attrnum le 1 > ; Attr# <= 1             ;J-KK1101
                xor     ah, ah          ;                              ;J-KK1101
                mov     al, ds:[si-1]   ; Attr0                        ;J-KK1101
                mov     [bp].Sub_attribute,ax ; Store Attribute        ;J-KK1101
            .else                       ;                              ;J-KK1101
                mov     ax, ds:[si-1]   ; Attr0/1                      ;J-KK1003
                mov     [bp].Sub_attribute,ax ; Store Attribute        ;J-KK1003
                xor     ah, ah          ;                              ;J-KK1101
                mov     al, ds:[si+1]   ; Attr2                        ;J-KK1101
                mov     [bp].Sub_attribute2,ax ; Store Attribute       ;J-KK1101
            .endif                      ;                              ;J-KK1101
            pop     ax                  ;                              ;J-KK1003

            mov     [bp].Sub_offset,di  ; save offset for write op
            mov     [bp].Sub_length,cx  ; save length for write op

            .if     < bx e EPOCH_Format > and ; Epoch Extra Hankaku ?   J-KK1129
            .if     < bit AH and dbcsE2 > and ;                         J-KK1129
            .if     < bit AH nand dbcsE1 > ;                            J-KK1129
                clc                     ;                               J-KK1129
            .elseif < bx e ATLAS3_Format > and ; ATLAS Extra Hankaku ?  J-KK1129
            .if     < <byte ptr ds:[si+1]> e TypeF> ;                   J-KK1129
                clc                     ;                               J-KK1129
            .else                       ;                               J-KK1129
                call    CheckDBCS       ; DBCS Char ?                   J-KK1129
                .if     c               ;                               J-KK1129
                    mov     dx, [bp].Sub_Buffsize ; Limit Check         J-KK1129
                    sub     dx, di      ;                               J-KK1129
                    shr     dx, 2       ;                               J-KK1129
                    .if     < [bp].Sub_attrnum g 1 > ;                  J-KK1129
                        shr     dx, 1   ;                               J-KK1129
                    .endif              ; DX - Double Cell Count        J-KK1129
                    .if     < zero dx > ;                               J-KK1129
                        jmp     WriteNCell_Exit ;                       J-KK1129
                    .endif              ;                               J-KK1129
                    .if     < cx g dx > ;                               J-KK1129
                        mov     cx, dx  ;                               J-KK1129
                    .else               ;                               J-KK1129
                        mov     dx, cx  ;                               J-KK1129
                    .endif              ;                               J-KK1129
                    shl     dx, 1       ; Adjust word offset length     J-KK1129
                    mov     [bp].Sub_length, dx ;   for DBCS chars      J-KK1129
                    stc                 ;                               J-KK1129
                .endif                  ;                               J-KK1129
            .endif                      ;                               J-KK1129

            call    cs:WNCellT[bx]      ; Dispatch to handler
WriteNCell_Exit:                        ;                               J-KK1129
            sub     ax, ax              ; Clear return code

        .endif                          ; 
        ret                             ; 

WriteNCell ENDP

R2CSEG  ENDS
        END
