;*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   EPOCHPVB.ASM -- PVB Write Routines for EPOCH

;/*****************************************************************************
;*
;* SOURCE FILE NAME = EPOCHPVB.ASM
;*
;* DESCRIPTIVE NAME = Regen Buffer Update Routine
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION
;*
;* FUNCTIONS    WriteCellStrE, WriteCharStrE, WriteCharStrAttrE,
;*              WriteNCharE, WriteNAttrE, WriteNCellE
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES  NONE
;*
;* EXTERNAL FUNCTIONS   LocateBuffAddr  (in XGAREAD.ASM)
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*             J-KK0815           KKJ, Changed the Attribute Mapping Logic for EPOCH Mono Mode.
;*             J-KK0825           KKJ, Deleted Unnecessary Code.
;*             J-KK0904           KKJ, Changed the attribute for EPOCH Mono and Color Mode.
;*             J-KK0914           KKJ, Changed the attribute for EPOCH Color Mode.
;*   09/25/89  J-KK0925           KKJ, ROM Font -> RAM Font
;*   10/03/89  J-KK1003           KKJ, Invisible Attribute in Epoch Mono Mode.
;*   10/06/89  J-KK1006           KKJ, Invisible Attribute in Epoch Mono Mode. (PTR0095)
;*   10/17/89  J-KK1017           KKJ, Add Set_StartEndRow for Xvio Redraw
;*   10/23/89  j-ys1023           for MS-Xvio support.
;*   10/24/89  J-KK1024           KKJ, Moved EPOCH_CFillR proc in
;*   10/27/89  J-KK1027           KKJ, Changed Attribute Mapping for Epoch Mono Mode
;*   10/31/89  J-KK1031           KKJ, Delete FONTCALL.
;*   11/01/89  j-ys111            for MS-Xvio support.
;*   11/02/89  j-ys1102           Extension Hankaku support.
;*   11/06/89  j-ys1106           for MS-Xvio support.
;*   11/15/89  j-ys1115           MS-XVIO,     in WrtNattr (P0149 SCT$12CC) fix.
;*   11/16/89  j-ys1116           MS-XVIO, Avoid Trap-D in the edge. ( P0150 SCT$12CC fix)
;*   01/10/90  J-KK0110           KKJ, Add Real Mode Handling
;*   04/24/90  @ys0424            YS, In real init, write length may be incresed in tailbound.
;*             J-TS100391         TSO, Fix Buf - JS01739
;*             J-TS011492         TSO, Fix     - JS02411
;****************************************************************************/

        .286c                           ; 286 protect mode instructions

        .xlist
        INCLUDE struc.inc               ; Structure macro
        INCLUDE vdhequ.inc              ; Buffer update equates
        INCLUDE vdhstruc.inc            ; Buffer update data structures
        include vgaemu.inc              ; VGA text emulation video buffer
        .list

_DATA   SEGMENT WORD PUBLIC 'DATA'
;************************************************************************
;*  Global data                                                         *
;************************************************************************
        extrn   VideoBuffSel : word

_DATA   ENDS

INSTSEG SEGMENT PARA PUBLIC 'DATA'
;************************************************************************
;*  Per process instance data                                           *
;************************************************************************
INSTSEG ENDS

        EXTRN   Set_StartEndRow:NEAR    ; StartRow and EnsRow          J-KK1017
        extrn   SetupAPAWrite : far     ; setup APA write mode
        extrn   ShowCursor    : near    ; show cursor
        extrn   HideCursor    : near    ; hide cursor
        extrn   ShadowToAPA   : near    ; Update APA based on shadow buf
        extrn   FillWithSBCS  : near    ; fill shadow & APA with SBCS char

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

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateRegenE                                    *
;*                                                                      *
;* DESCRIPTIVE NAME:    Call a Update Regen (PVB) routine               *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  LVB Address                     (see XGAWRITE.ASM)      *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: UpdateRegenOneLineE                             *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateRegenE proc near
        public  UpdateRegenE

        .if     <[bp].PVB_Sel ne 0> and ; PVB Update ?
        .if     <[bp].Sub_length gt 0>  ; one or more character update?

            call    HideCursor          ; hide cursor

            call    SetupAPAWrite       ; setup APA write mode
            mov     [bp].APAPrevColor, -1   ; reset preset color

            mov     ds, [bp].LVB_Sel    ; setup LVB/Shadow PVB pointer
            mov     si, [bp].Sub_offset ; ds:si = LVB top
            mov     ax, _DATA           ; es:di = Shadow PVB top
            mov     es, ax              ; 
            mov     es, es:VideoBuffSel ; 
            mov     di, [bp].PVBOff     ; PVB buffer is 2 bytes/cell
            shl     di, 1               ; Shadow buffer is 4 bytes/cell

            shl     [bp].Sub_PVBend, 1  ; adjust PVB buffer end
            .if     <[bp].Sub_index eq WCELL> and ; this call is from WriteCellStr ;J-TS100391
            .if     <bit [bp].Sub_Option nand CA_Request>               ;J-TS100391
                shr     [bp].FirstRow, 1  ; convet from byte to cell (word)
                shr     [bp].RowLength, 1 ; 
            .endif

            mov     dx, [bp].Sub_length ; setup total cell count

            .if     <dx g [bp].FirstRow> ; Update region is included in a line?
                mov     cx, [bp].FirstRow ; No, set first row length
            .else
                mov     cx, dx          ; Yes, set total length
            .endif

UpdateRegenLoopE:
                push    cx                  ; save current line counter
                push    dx                  ; & total counter

                call    UpdateRegenOneLineE ; call one line update function

                pop     dx                  ; restore current line counter
                pop     cx                  ; & total counter

                sub     dx, cx          ; dec total length
                jz      UpdateRegenLoopExitE    ; end ? then exit the loop

                .if     <dx gt [bp].RowLength>  ; set next line length
                    mov     cx, [bp].RowLength  ; full line
                .else
                    mov     cx, dx              ; last line
                .endif
                add     di, [BP].PVBSkip        ; skip PVB pointer to next line
                add     di, [BP].PVBSkip        ; 2 times PVBSkip is 2 byte/cell
                jmp     UpdateRegenLoopE        ; goto next line

UpdateRegenLoopExitE:
            mov     al, 1               ; 2 bytes Cell
            shr     di, 1               ; adjust ptr
            call    Set_StartEndRow     ; 

            call    ShowCursor          ; show cursor

        .endif
        ret

UpdateRegenE endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateRegenOneLineE                             *
;*                                                                      *
;* DESCRIPTIVE NAME:    Update shadow buffer & call APA update routine  *
;*                      For EPOCH mode.                                 *
;*                                                                      *
;* INPUT:                                                               *
;* CX           Cell Count                                              *
;* DS:SI  --->  LVB Address                                             *
;* ES:DI  --->  Shadow Buffer Address                                   *
;*                                                                      *
;* INTERNAL REFERENCES: EpochToAtlas3                                   *
;*                                                                      *
;* EXTERNAL REFERENCES: ShadowToAPA                                     *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateRegenOneLineE proc    near
        public  UpdateRegenOneLineE

        mov     [bp].APA_from, di       ; save shadow top pointer & char cnt
        mov     [bp].APA_cnt, cx        ; for latter use (update APA image)

        .if     <di ge 4> and           ; First character check
        mov     bl, es:shadow[di+3]     ; Target header is DBCS 2nd ?
        and     bl, dbcsA1+dbcsA2       ; 
        .if     <bl eq dbcsA1+dbcsA2>   ; Overwrite DBCS 1st
            mov     byte ptr es:shadow[di-4], 20h                   ; set space
            mov     word ptr es:shadow[di-2], EXTRA_ATTR+CHANGE_BIT ; reset flag
            sub     [bp].APA_from, 4    ; adjust APA update area
            inc     [bp].APA_cnt
        .endif                          ; 

        mov     ax, [si]                ; get one character from LVB

        mov     bl, [si+1]              ; Source header is DBCS 2nd ?
        and     bl, dbcsE1+dbcsE2       ; 

        .if     <bl eq dbcsE1+dbcsE2>   ; 
            mov     al, 20h             ; Yes, then write SBCS space
            and     ah, not (dbcsE1+dbcsE2)
        .endif

OneLineLoopE:

        .if     <cx eq 1>               ; Last character check

            .if     <di lt [bp].Sub_PVBend> and ; 
            mov     bl, es:shadow[di+3] ; Target tail is DBCS 1st ?
            and     bl, dbcsA1+dbcsA2   ; 
            .if     <bl eq dbcsA1>      ; Overwrite DBCS 2nd
                mov     byte ptr es:shadow[di+4], 20h           ; set space
                mov     word ptr es:shadow[di+6], EXTRA_ATTR+CHANGE_BIT ; reset flag
                inc     [bp].APA_cnt    ; adjust APA update area
            .endif                      ; 

            mov     bl, ah              ; Source tail is DBCS 1st ?
            and     bl, dbcsE1+dbcsE2   ; 
            .if     <bl eq dbcsE1>      ; 
                mov     al, 20h         ; Yes, then write SBCS space
                and     ah, not dbcsE1
            .endif

        .endif

        call    EpochToAtlas3           ; convert attribute

        .if     <ax ne <word ptr es:shadow[di  ]>> or ; displayed char
        .if     <dx ne <word ptr es:shadow[di+2]>>    ; is changed ?
            or      dx, CHANGE_BIT                    ; set change flag
            mov     word ptr es:shadow[di], ax        ; Copy char/attr0
            mov     word ptr es:shadow[di+2], dx      ; Store Extra Attr1/2
        .endif

        add     si, 2                       ; set pointer to next source
        add     di, 4                       ; set pointer to next target

        dec     cx                          ; check loop end
        jz      OneLineLoopExitE

        mov     ax, [si]                    ; get next char/attr0
        jmp     OneLineLoopE

OneLineLoopExitE:
        push    si                  ; save source & target pointer
        push    di
        push    ds
        push    es

        call    ShadowToAPA         ; Update APA based on shadow buf

        pop     es                  ; restore source & target pointer
        pop     ds
        pop     di
        pop     si

        ret

UpdateRegenOneLineE endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     EpochtoAtlas3                                   *
;*                                                                      *
;* DESCRIPTIVE NAME:    Convert Epoch attribute to Atlas attribute      *
;*                                                                      *
;* INPUT:                                                               *
;* AX     = char/attr of epoch format                                   *
;*                                                                      *
;* OUTPUT:                                                              *
;* AX     = char/attr0  of atlas3 format                                *
;* DX     = attr1/attr2 of atlas3 format                                *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
EpochToAtlas3   proc    near
        public  EpochToAtlas3

        push    bx                      ; save work register

        mov     bh, 0                   ; preset attr0/attr1/attr2
        mov     dx, EXTRA_ATTR

        .if     <[bp].Sub_colors eq 1>  ; Mono mode ?

;;   Attribute Mapping  10/27/89
;;
;;               Color Attr.     Actual Palette     Default Color
;;   Normal FG :    2                 4              Green
;;   Normal BG :    0                 0              Black
;;   H-Int  FG :    F                 F              White
;;   H-Int  BG :    8                 1              Black = Normal BG
;;
;;   Therefore, 1st Color Attribute is as follows,
;;
;;        Normal         : 02h
;;        Hi-Int         : 8Fh
;;        Normal Reverse : 20h
;;        Hi-Int Reverse : F0h

            mov     bl, ah
            and     bl,0cch
            .if     <bl ne 0cch>        ; not invisible attribute ?

                ; underscore attribute

                .if     <bit ah and 040h>
                    or      dl, A_UNDERLINE_BIT
                .endif

                ; high intencity attribute

                .if     <bit ah and 008h>
                    mov     bh, 08fh
                .else
                    mov     bh, 002h
                .endif

            .endif

        .else                           ; Color mode

            ; color attribute

            .if     <bit ah nand 080h>  ; blue on ?
                or      bh, 001h
            .endif
            .if     <bit ah nand 040h>  ; green on ?
                or      bh, 002h
            .endif
            .if     <bit ah nand 008h>  ; red on ?
                or      bh, 004h
            .endif

        .endif

        ; reverse attribute

        .if     <bit ah and 004h>
            shl     bh, 4
        .endif

        ; grid attribute

        mov     bl, ah
        shr     bl, 4                   ; cut off grid attribute
        or      dl, bl                  ; paste into atlas3 attribute

        ; DBCS/SBCS & character set

        .if     <bit ah and 001h>       ; DBCS bit ?
            or      dh, dbcsA1
            .if     <bit ah and 002h>   ; DBCS 2nd byte ?
                or      dh, dbcsA2
            .endif
        .else                           ; SBCS
            .if     <bit ah and 002h>   ; Extra SBCS character set ?
                or      dh, TypeF
            .endif
        .endif

        mov     ah, bh                  ; set attr0
        pop     bx                      ; restore work register
        ret

EpochToAtlas3   endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateAttrE                                     *
;*                                                                      *
;* DESCRIPTIVE NAME:    Call a Update Regen (PVB) routine for Attribute *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  LVB Address                     (see XGAWRITE.ASM)      *
;*                                                                      *
;* INTERNAL REFERENCES: UpdateRegenE                                    *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateAttrE proc near
        public  UpdateAttrE

        call    UpdateRegenE

        ret
UpdateAttrE endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     EPOCH_CFillR                                    *
;*                                                                      *
;* DESCRIPTIVE NAME:    Update PVB for Filling Cell at Scrolling        *
;*                      This is called per line.                        *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  PVB Address  ( B0000:0000 : DI Points To Attr1/2 )      *
;* CX     --->  Length Bytes                                            *
;* Flag   --->  CLD or STD                                              *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
EPOCH_CFillR proc                       ;j-ys706
        public  EPOCH_CFillR

        ; get PVB format cell to fill in ax:char/attr0 & dx:attr1/attr2

        mov     ax, [bp].FillCellLow
        call    EpochToAtlas3               ; convert attribute
        and     dx, not (dbcsA2H+dbcsA1H)   ; clear DBCS bit

        call    FillWithSBCS                ; call update routine

        ret

EPOCH_CFillR endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     Real_UpLeftR                                    *
;*                                                                      *
;* DESCRIPTIVE NAME:    Video device handler Scroll Up/Left             *
;*                      Move a one line.                                *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* DS:SI  --->  Source Buffer Address           (see XGASCROL.ASM)      *
;* ES:DI  --->  PVB Address                     (see XGASCROL.ASM)      *
;* CX     --->  Words (Cell) to be moved        (see XGASCROL.ASM)      *
;* Flag   --->  CLD                             (see XGASCROL.ASM)      *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
Real_UpLeftR proc
        public  Real_UpLeftR
        ret
Real_UpLeftR endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     Real_DnRightR                                   *
;*                                                                      *
;* DESCRIPTIVE NAME:    Video device handler Scroll Down/Right          *
;*                      Move a one line.                                *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* DS:SI  --->  Source Buffer Address           (see XGASCROL.ASM)      *
;* ES:DI  --->  LVB Address                     (see XGASCROL.ASM)      *
;* CX     --->  Words (Cell) to be moved        (see XGASCROL.ASM)      *
;* Flag   --->  STD                             (see XGASCROL.ASM)      *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
Real_DnRightR proc
        public  Real_DnRightR
        ret
Real_DnRightR endp

;; For MS-XVIO
;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateCARegenE                  j-ys1106        *
;*                                                                      *
;* DESCRIPTIVE NAME:    Call a Update Regen (PVB) routine for CA        *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  LVB Address                     (see XGAWRITE.ASM)      *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: writeregen0                                     *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateCARegenE proc near
        public  UpdateCARegenE

        call    UpdateRegenE

        ret

UpdateCARegenE endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateCAAttrE                           j-ys111 *
;*                                                                      *
;* DESCRIPTIVE NAME:    Call a Update Regen (PVB) routine for Attribute *
;*                           for CA                                     *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  LVB Address                     (see XGAWRITE.ASM)      *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: writeregen                                      *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateCAAttrE proc near
        public  UpdateCAAttrE

        call    UpdateRegenE

        ret

UpdateCAAttrE endp

EPOCH_LVBrecttoPVB proc                 ;j-ys1026
public  EPOCH_LVBrecttoPVB              ;j-ys1026
                                                                        ;J-TS100391
        call    HideCursor                  ; hide cursor               ;J-TS100391
                                                                        ;J-TS100391
        call    SetupAPAWrite               ; setup APA write mode      ;J-TS100391
        mov     [bp].APAPrevColor, -1       ; reset preset color        ;J-TS100391
                                                                        ;J-TS100391
        mov     ds, [bp].LVB_SEL            ; setup selectors           ;J-TS100391
        mov     ax, _DATA                                               ;J-TS100391
        mov     es, ax                                                  ;J-TS100391
        mov     es, es:VideoBuffSel
                                                                        ;J-TS100391
        mov     si,[bp].LVBFillOff          ; setup ofsets              ;J-TS100391
        mov     di,[bp].PVBFillOff                                      ;J-TS100391
                                                                        ;J-TS100391
        mov     dx,[bp].RowsToFill          ; set row loop counter      ;J-TS100391
                                                                        ;J-TS100391
EPOCHLPLoop:                                                            ;J-TS100391
        mov     cx,[bp].LVBFillCount        ; set column counter        ;J-TS100391
        shr     cx, 1                                                   ;J-TS100391
                                                                        ;J-TS100391
        mov     bx, [bp].LVBFillCount                                   ;J-TS100391
        add     bx, si                                                  ;J-TS100391
        .if     <bx b [bp].Sub_Buffsize> and ; last char is DBCS 1st ?  ;J-TS100391
        mov     al, byte ptr ds:[bx+1-2]                                ;J-TS011492
        and     al, dbcsE1+dbcsE2                                       ;J-TS100391
        .if     <al e dbcsE1>                                           ;J-TS100391
            inc     cx                      ; include DBCS 2nd          ;J-TS100391
            or      [bp].Sub_Option, f_end_adjust ; set adjust flag     ;J-TS100391
        .endif                                                          ;J-TS100391
                                                                        ;J-TS100391
        .if     <si ge 2> and               ; first char is DBCS 2nd ?  ;J-TS100391
        mov     al, byte ptr ds:[si+1]                                  ;J-TS100391
        and     al, dbcsE1+dbcsE2                                       ;J-TS100391
        .if     <al e dbcsE1+dbcsE2>                                    ;J-TS100391
            sub     si, 2                   ; include DBCS 1st          ;J-TS100391
            sub     di, 4                                               ;J-TS100391
            inc     cx                                                  ;J-TS100391
        .endif                                                          ;J-TS100391
                                                                        ;J-TS100391
        push    dx                                                      ;J-TS100391
        call    UpdateRegenOneLineE         ; update one line           ;J-TS100391
        pop     dx                                                      ;J-TS100391
                                                                        ;J-TS100391
        add     si, [bp].LVBFillSkip        ; skip to next line         ;J-TS100391
        add     di, [bp].PVBFillSkip                                    ;J-TS100391
                                                                        ;J-TS100391
        .if     <bit [bp].Sub_Option and f_end_adjust>                  ;J-TS100391
            sub     si, 2                   ; adjust ptrs               ;J-TS100391
            sub     di, 4                   ;                           ;J-TS100391
            and     [bp].Sub_Option, not f_end_adjust ; clear adjust flag   ;J-TS100391
        .endif                                                          ;J-TS100391
                                                                        ;J-TS100391
        dec     dx                                                      ;J-TS100391
        jnz     EPOCHLPLoop                                             ;J-TS100391
                                                                        ;J-TS100391
        call    ShowCursor                  ; show cursor               ;J-TS100391
                                                                        ;J-TS100391
        ret                             ;j-ys1026
EPOCH_LVBrecttoPVB endp                 ;j-ys1026

EPOCH_CArecttoPVB proc                  ;j-ys111
public  EPOCH_CArecttoPVB               ;j-ys111
        ret                             ;j-ys111
EPOCH_CArecttoPVB endp                  ;j-ys111

R2CSEG  ENDS
        END
