;*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   ATLS3PVB.ASM -- PVB Write Routines for ATLAS 3 bytes format

;/*****************************************************************************
;*
;* SOURCE FILE NAME = ATLS3PVB.ASM
;*
;* DESCRIPTIVE NAME = Regen Buffer Update Routine
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION
;*
;* FUNCTIONS
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES  NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
;*   --------  ---------- -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
;*   09/12/89  j-ys912                fix for P0014 sct$12cc. (The 2nd attribute of cell with
;*                                which the scrolled area is filled was ignored.)
;*   09/25/89  J-KK0925           KKJ, ROM Font -> RAM Font
;*   10/02/89  j-ys102            Atlas 82 Mono mode support.
;*   10/16/89  J-KK1016           KKJ, Re-adjust the end offset value.
;*   10/17/89  J-KK1017           KKJ, Add Set_StartEndRow for Xvio Redraw.
;*   10/19/89  J-KK1019           KKJ, Re-adjust the end offset value for Redraw at WrtNAttr
;*   10/23/89  j-ys1023            Sub_buffsize -> Subs_PVBEND for PVB screen size.  MS-XVio.
;*   10/31/89  J-KK1031           KKJ, Fixed     for Exception Handling
;*                                     Delete FONTCALL.
;*   11/01/89  J-KK1101           KKJ, Add Extra Hankaku Handling
;*   08/09/91  J-TS080991         VIO write over XVIO PS destroy screen. PTR JS01621
;****************************************************************************/

        .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:     UpdateRegenA                                    *
;*                                                                      *
;* 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: UpdateRegenOneLineA                             *
;*                                                                      *
;* EXTERNAL REFERENCES: ShowCursor, HideCursor, SetupAPAWrite,          *
;*                      Set_StartEndRow                                 *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateRegenA proc near
        public  UpdateRegenA

        .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     [bp].Sub_Option, 0  ; clear blink option

            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

            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

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

                call    UpdateRegenOneLineA ; call one line update function

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

                sub     dx, cx          ; dec total length
                jz      UpdateRegenLoopExitA    ; 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     UpdateRegenLoopA        ; goto next line

UpdateRegenLoopExitA:
            mov     al, 2               ; 4 bytes Cell
;J-TS080991 shr     di, 1               ; adjust ptr
            call    Set_StartEndRow     ; 

            call    ShowCursor          ; show cursor

        .endif
        ret
UpdateRegenA endp

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

        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     byte ptr es:shadow[di-1], EXTRA_ATTRHigh+CHANGE_BITHigh ; reset flag
            sub     [bp].APA_from, 4    ; adjust APA update area
            inc     [bp].APA_cnt
        .endif                          ; 

        mov     bl, [si+3]              ; Source header is DBCS 2nd ?
        and     bl, dbcsA1+dbcsA2       ; 
        .if     <bl eq dbcsA1+dbcsA2>   ; 
            mov     al, 20h             ; Yes, then write SBCS space
            mov     dl, [si+2]          ; 
            mov     dh, EXTRA_ATTRHigh  ; 
        .else
            mov     al, [si]            ; No, get character code from LVB
            mov     dx, [si+2]          ; 
        .endif
        mov     ah, [si+1]              ; Get attribute

OneLineLoopA:

        .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     byte ptr es:shadow[di+7], EXTRA_ATTRHigh+CHANGE_BITHigh ; reset flag
                inc     [bp].APA_cnt    ; adjust APA update area
            .endif                      ; 

            mov     bl, [si+3]          ; Source tail is DBCS 1st ?
            and     bl, dbcsA1+dbcsA2   ; 
            .if     <bl eq dbcsA1>      ; 
                mov     al, 20h         ; Yes, then write SBCS space
                mov     dh, EXTRA_ATTRHigh
            .endif

        .endif

        .if     <bit <byte ptr [bp].Sub_Option> and BLINK_STATE> ;Blink State On
            and     ah, not ATLAS_BLINK ; Reset Blink in Attr0
        .endif

        .if     <[bp].Sub_colors e 1>
            call    Atlas3MonoToColor   ; convert attribute
        .endif

        .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, 4                       ; set pointer to next source
        add     di, 4                       ; set pointer to next target

        dec     cx                          ; check loop end
        jz      OneLineLoopExitA

        mov     ax, [si]                    ; get next char/attr0
        mov     dx, [si+2]                  ; get next attr1/attr2
        jmp     OneLineLoopA

OneLineLoopExitA:
        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

UpdateRegenOneLineA endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     Atlas3MonoToColor                               *
;*                                                                      *
;* DESCRIPTIVE NAME:    Convert atlas 3 byte mono mode attribute to     *
;*                      color                                           *
;*                                                                      *
;* INPUT:                                                               *
;* AX     = char/attr0  of common format                                *
;* DX     = attr1/attr2 of common format                                *
;*                                                                      *
;* OUTPUT:                                                              *
;* AX     = char/attr0  of atlas3 format                                *
;* DX     = attr1/attr2 of atlas3 format                                *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
Atlas3MonoToColor   proc    near
        public  Atlas3MonoToColor

        ; intensity attribute

        .if     <bit ah and 08h>
            mov     ah, 07h                     ; White H-Int
        .else
            mov     ah, 02h                     ; Green
        .endif

        ; reverse attribute

        .if     <bit dl and 08h>
            ror     ah, 4
        .endif

        ret
Atlas3MonoToColor   endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateAttrA                                     *
;*                                                                      *
;* 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: UpdateRegenA                                    *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateAttrA proc near
        public  UpdateAttrA

        call    UpdateRegenA

        ret
UpdateAttrA endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS3CFillR                                    *
;*                                                                      *
;* 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                                             *
;* CX     --->  Length Bytes                                            *
;* Flag   --->  CLD or STD                                              *
;*                                                                      *
;* INTERNAL REFERENCES: Atlas3MonoToColor, FillWithSBCS                 *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
ATLAS3CFillR proc
        public  ATLAS3CFillR

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

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

        .if     <[bp].Sub_colors e 1>
            call    Atlas3MonoToColor       ; convert attribute
        .endif

        call    FillWithSBCS                ; call update routine

        ret

ATLAS3CFillR endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     WriteAttra                                      *
;*                                                                      *
;* DESCRIPTIVE NAME:    Update PVB for only Attribute                   *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* DS:SI  --->  LVB Address                                             *
;* ES:DI  --->  PVB Address                                             *
;* CX     --->  Length Bytes                                            *
;*                                                                      *
;* INTERNAL REFERENCES: UpdateRegenA                                    *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
WriteAttrA PROC NEAR
        public  WriteAttrA

        call    UpdateRegenA

        ret

WriteAttrA ENDP

R2CSEG  ENDS
        END
