;*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   ATLS_PVB.ASM -- PVB Write Routines for ATLAS U.S. Format

;/*****************************************************************************
;*
;* SOURCE FILE NAME = ATLS_PVB.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/01/89  J-KK0901           KKJ, Performance Up and Support Mono Mode
;*   10/04/89  J-KK1004           KKJ, P0081 Mono Mode Attribute Incorrect.
;*   10/05/89  J-KK1005           KKJ, [bp].Sub_AttrState -> .Sub_Option
;*   10/17/89  J-KK1017           KKJ, Add Set_StartEndRow for Xvio Redraw.
;*   10/31/89  J-KK1031           KKJ,     - All DBCS Chars have 9Dh as 3rd attr.
;*                                     Delete FONTCALL.
;*             j-ys1023,1026,          111 for MS-Xvio support.
;*   11/13/89  J-KK1113           KKJ,     - Not Redrawn in Mono Mode.
;*   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.
;*   11/17/89  J-KK1117           KKJ, P0158 SCT$12CC - NAttr     in Mono mode
;*   12/15/89  J-KK1215           KKJ, Performance Up and Fix Trap-D
;*   01/10/90  J-KK0110           KKJ, Add Real Mode Handling
;*   02/05/90  J-KK0205           KKJ, Fix     - End offset must be adjusted.
;*   02/21/90  J-KKB12            KKJ, Fix     - Fill Cell with MSB On.
;*             J-TS100391         TSO, Fix     - JS01739
;*             J-TS102291         TSO, PTR JS01738 During VioPopUp, Screen group ID is forced
;*                                     to No.3 with no notification.
;*             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 vdh.inc                 ; Definitions
INCL_DOSINFOSEG     equ     1           ;                               ;J-TS102291
        include os2.inc                 ; InfoSeg definition            ;J-TS102291
        include vgaemu.inc              ; VGA text emulation video buffer
        .list

_DATA   SEGMENT WORD PUBLIC 'DATA'
;************************************************************************
;*  Global data                                                         *
;************************************************************************
        extrn   VideoBuffSel : word
        extrn   XGAExist     : word
        extrn   HardwareScroll  : word
        extrn   PrevLineComp    : word
        extrn   MaxLineComp     : word

_DATA   ENDS

        extrn   DOSGETINFOSEG      : far    ; Dos call
        extrn   DOSFREESEG         : far    ; Dos call
        extrn   FNTGETIMAGEADDR    : far    ; get DBCS font image
        extrn   FNTGETACTIVEBUFFER : far    ; get SBCS font buffer
        extrn   SetupAPAWrite      : far    ; setup APA write mode
        extrn   SetupAPAMove       : far    ; setup APA move mode
        extrn   SetAPAColor        : far    ; set APA write color
        extrn   SetClsColor        : far    ; set APA clear color
        extrn   SetGridColor       : far    ; set grid color
        extrn   ShowCursor         : near   ; show cursor
        extrn   HideCursor         : near   ; hide cursor
        extrn   SetAPAStart        : far    ; set APA display start address
        extrn   _InitPointer       : near   ; inform font data to mouse pointer

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

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     UpdateRegenB                                    *
;*                                                                      *
;* DESCRIPTIVE NAME:    Call a Update Regen (PVB) routine               *
;*                      For DBCS VGA mode.                              *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  LVB Address                     (see XGAWRITE.ASM)      *
;*                                                                      *
;* INTERNAL REFERENCES: UpdateRegenOneLineB, Set_StartEndRow            *
;*                                                                      *
;* EXTERNAL REFERENCES: ShowCursor, HideCursor, SetupAPAWrite           *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
UpdateRegenB    proc near
        public  UpdateRegenB

        .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

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

                call    UpdateRegenOneLineB ; call one line update function

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

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

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

            call    ShowCursor          ; show cursor

        .endif
        ret
UpdateRegenB endp

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

        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     bl, [si+TOEXT+1]        ; Source header is DBCS 2nd ?
        and     bl, dbcsA1+dbcsA2       ; 
        .if     <bl eq dbcsA1+dbcsA2>   ; 
            mov     al, 20h             ; Yes, then write SBCS space
            mov     dx, EXTRA_ATTR      ; 
        .else
            mov     al, [si]            ; No, get character code from LVB
            mov     dx, [si+TOEXT]      ; 
        .endif
        mov     ah, [si+1]              ; Get attribute

OneLineLoopB:

        .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, [si+TOEXT+1]    ; Source tail is DBCS 1st ?
            and     bl, dbcsA1+dbcsA2   ; 
            .if     <bl eq dbcsA1>      ; 
                mov     al, 20h         ; Yes, then write SBCS space
                mov     dx, EXTRA_ATTR  ; 
            .endif

        .endif
                                            ; check blink/hi-int bit
        .if     <bit ah and ATLAS_BLINK> and ; MSB(Blink/H-Int) Bit On
        .if     <bit <byte ptr [bp].Sub_Option> and BLINK_STATE> ;Blink State On
            and     ah, not ATLAS_BLINK     ; Reset Blink in Attr0
            mov     dl, ATLAS_BLINK         ; Set Blink in PVB
        .endif

        .if     <[bp].Sub_colors eq 0>  ; Mono mode ?
            call    MonoToColor         ; convert attribute
            or      dx, bx
        .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, 2                       ; set pointer to next source
        add     di, 4                       ; set pointer to next target

        dec     cx                          ; check loop end
        jz      OneLineLoopExitB

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

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

UpdateRegenOneLineB endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ShadowToAPA                                     *
;*                                                                      *
;* DESCRIPTIVE NAME:    Update APA according to shadow buffer.          *
;*                                                                      *
;* INPUT:                                                               *
;* [bp].APA_from --->  Shadow Buffer Address                            *
;* [bp].APA_cnt        Cell Count                                       *
;*                                                                      *
;* INTERNAL REFERENCES: FontGetSBCS, FontGetDBCS                        *
;*                                                                      *
;* EXTERNAL REFERENCES: SetAPAColor                                     *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
ShadowToAPA proc    near
        public  ShadowToAPA

        mov     ax, _DATA                   ; Get text emulation video buffer
        mov     ds, ax                      ; Get PVB selector from stack
        mov     ds, ds:VideoBuffSel
                                            ; Get PVB selector from stack
        mov     bx, [bp].APA_from           ; set source pointer ds:bx
        mov     es, [bp].PVB_Sel            ; Get PVB selector from stack
        mov     ax, bx                      ; set target pointer es:di
        shr     ax, 2                       ; di = (si / 4) / LVB_WIDTH
        mov     dh, byte ptr [bp].Sub_cols  ;        * FONT_HEIGHT * APA_WIDTH
        div     dh                          ;    + (si / 4) % LVB_WIDTH
        mov     di, ax                      ;    + APAStart
        shr     di, 8
        mov     dx, APA_WIDTH*FONT_HEIGHT
        xor     ah, ah
        mul     dx
        add     di, ax
        add     di, ds:VGA_APAStart
        mov     dx, [bp].APA_cnt            ; set loop counter

ShadowLoop:

        .if     <bit <byte ptr ds:shadow[bx+3]> and dbcsA1> near ; DBCS ?

            .if     <bit <word ptr ds:shadow[bx+2]> and CHANGE_BIT> or
            .if     <bit <word ptr ds:shadow[bx+6]> and CHANGE_BIT> near ; changed ?

                and     word ptr ds:shadow[bx+2], not CHANGE_BIT ; clear change
                and     word ptr ds:shadow[bx+6], not CHANGE_BIT ; bit

                mov     al, ds:shadow[bx+1] ; get APA write color (left  harf)
                xor     ah, ah
                mov     cl, ds:shadow[bx+5] ; get APA write color (right harf)
                xor     ch, ch

                .if     <ax eq cx> near     ; left & right are same attribute ?
                    .if     <ax ne [bp].APAPrevColor>   ; color is changed ?
                        mov     [bp].APAPrevColor, ax   ; set APA write color (left harf)
                        call    SetAPAColor
                    .endif

                    push    ds                  ; push shadow buffer selector

                    mov     al, ds:shadow[bx+4] ; get DBCS font
                    mov     ah, ds:shadow[bx]
                    call    FontGetDBCS

                    xor     ax, ax          ; move font image from font buf to APA
                    stosw                   ; clear first line
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    movsw
                    add     di, APA_WIDTH-2
                    stosw                   ; clear last line

                    sub     di, APA_WIDTH*(FONT_HEIGHT-1)   ; resotre & inc APA ptr
                    pop     ds              ; pop shadow buffer selector
                                            ; underline ?
                    .if     <bit <byte ptr ds:shadow[bx+2]> and A_UNDERLINE_BIT>
                        mov     byte ptr es:[di+APA_WIDTH*(FONT_HEIGHT-1)-2], 0ffh
                    .endif
                    .if     <bit <byte ptr ds:shadow[bx+6]> and A_UNDERLINE_BIT>
                        mov     byte ptr es:[di+APA_WIDTH*(FONT_HEIGHT-1)-1], 0ffh
                    .endif
                                            ; Horz/Vert grid ?
                    .if     <bit <byte ptr ds:shadow[bx+2]> and A_HORZ_BIT+A_VERT_BIT>
                        push    di
                        sub     di, 2
                        mov     al, ds:shadow[bx+2]
                        call    DrawGrid    ; draw horz & vert grid
                        pop     di
                    .endif
                    .if     <bit <byte ptr ds:shadow[bx+6]> and A_HORZ_BIT+A_VERT_BIT>
                        push    di
                        dec     di
                        mov     al, ds:shadow[bx+6]
                        call    DrawGrid    ; draw horz & vert grid
                        pop     di
                    .endif

                .else near
                    .if     <ax ne [bp].APAPrevColor>   ; color is changed ?
                        mov     [bp].APAPrevColor, ax   ; set APA write color (left harf)
                        call    SetAPAColor
                    .endif

                    push    ds                  ; push shadow buffer selector

                    push    word ptr ds:shadow[bx+2]    ; save attr1/2 word for latter use

                    mov     al, ds:shadow[bx+4] ; get DBCS font
                    mov     ah, ds:shadow[bx]
                    call    FontGetDBCS

                    xor     al, al          ; move font image from font buf to APA
                    stosb                   ; clear first line (left harf)
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    add     di, APA_WIDTH-1 ; clear last line
                    stosb

                    sub     di, APA_WIDTH*(FONT_HEIGHT-1)   ; resotre & inc APA ptr
                    sub     si, (FONT_HEIGHT-3)*2            ; restore font pointer

                    pop     ax              ; get attr1/2 word
                                            ; underline ?
                    .if     <bit al and A_UNDERLINE_BIT>
                        mov     byte ptr es:[di+APA_WIDTH*(FONT_HEIGHT-1)-1], 0ffh
                    .endif
                                            ; Horz/Vert grid ?
                    .if     <bit al and A_HORZ_BIT+A_VERT_BIT>
                        push    di
                        dec     di
                        call    DrawGrid    ; draw horz & vert grid
                        pop     di
                    .endif

                    .if     <cx ne [bp].APAPrevColor>   ; color is changed ?
                        mov     [bp].APAPrevColor, cx   ; set APA write color (right harf)
                        mov     ax, cx
                        call    SetAPAColor
                    .endif

                    xor     al, al          ; move font image from font buf to APA
                    stosb                   ; clear first line (right harf)
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    movsb
                    inc     si
                    add     di, APA_WIDTH-1
                    stosb                   ; clear last line
                    add     di, APA_WIDTH-1
                    stosb

                    sub     di, APA_WIDTH*(FONT_HEIGHT-1)   ; resotre & inc APA ptr
                    pop     ds              ; pop shadow buffer selector
                                            ; underline ?
                    .if     <bit <byte ptr ds:shadow[bx+6]> and A_UNDERLINE_BIT>
                        mov     byte ptr es:[di+APA_WIDTH*(FONT_HEIGHT-1)-1], 0ffh
                    .endif
                                            ; Horz/Vert grid ?
                    .if     <bit <byte ptr ds:shadow[bx+6]> and A_HORZ_BIT+A_VERT_BIT>
                        push    di
                        dec     di
                        mov     al, ds:shadow[bx+6]
                        call    DrawGrid    ; draw horz & vert grid
                        pop     di
                    .endif

                .endif

                add     bx, 8               ; increase shadow buf ptr

            .else                           ; char is not changed

                add     bx, 8               ; skip to next char
                add     di, 2

            .endif

            sub     dx, 2                   ; dec loop counter

        .else near                          ; SBCS

            .if     <bit <word ptr ds:shadow[bx+2]> and CHANGE_BIT> near ; changed ?

                and     word ptr ds:shadow[bx+2], not CHANGE_BIT ; clear change

                mov     al, ds:shadow[bx+1] ; set APA write color
                xor     ah, ah

                .if     <ax ne [bp].APAPrevColor>   ; color is changed ?
                    mov     [bp].APAPrevColor, ax
                    call    SetAPAColor
                .endif

                push    ds                  ; push shadow buffer selector

                mov     al, ds:shadow[bx]   ; get SBCS font
                mov     ah, ds:shadow[bx+3]
                call    FontGetSBCS

                movsb                       ; move font image from font buf to APA
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb
                add     di, APA_WIDTH-1
                movsb

                sub     di, APA_WIDTH*(FONT_HEIGHT-1)   ; resotre & inc APA ptr

                pop     ds                  ; pop shadow buffer selector

                                            ; underline ?
                .if     <bit <byte ptr ds:shadow[bx+2]> and A_UNDERLINE_BIT>
                    mov     byte ptr es:[di+APA_WIDTH*(FONT_HEIGHT-1)-1], 0ffh
                .endif
                                            ; Horz/Vert grid ?
                .if     <bit <byte ptr ds:shadow[bx+2]> and A_HORZ_BIT+A_VERT_BIT>
                    push    di
                    dec     di
                    mov     al, ds:shadow[bx+2]
                    call    DrawGrid        ; draw horz & vert grid
                    pop     di
                .endif

                add     bx, 4               ; increase shadow buf ptr

            .else                           ; char is changed

                add     bx, 4               ; skip to next char
                inc     di

            .endif

            dec     dx                      ; dec loop counter

        .endif

        jz      ShadowExit                  ; check loop end
        jmp     ShadowLoop

ShadowExit:
        ret
ShadowToAPA endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     DrawGrid                                        *
;*                                                                      *
;* DESCRIPTIVE NAME:    Draw vertical & horizontal grid lines.          *
;*                                                                      *
;* INPUT:                                                               *
;* AL          Grid attribute                                           *
;* ES:DI --->  APA Address                                              *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: SetGridColor                                    *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
DrawGrid    proc    near
        public  DrawGrid

        push    ax                          ; save grid flag

        push    ds                          ; get grid color
        mov     ax, _DATA
        mov     ds, ax
        mov     ds, ds:VideoBuffSel
        mov     al, ds:VGA_GridColor
        pop     ds

        call    SetGridColor                ; set grid color

        pop     ax                          ; restore grid flag

        .if     <bit al and A_HORZ_BIT>     ; horizontal grid ?
            mov     byte ptr es:[di], 0ffh
        .endif

        .if     <bit al and A_VERT_BIT> near ; vertical grid ?
            mov     al, 80h
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
            mov     ah, es:[di]
            stosb
            add     di, APA_WIDTH-1
        .endif
        mov     [bp].APAPrevColor, -1       ; reset draw color
        ret
DrawGrid    endp

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

        call    UpdateRegenB

        ret
UpdateAttrB endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_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 ***************************
ATLAS_UpLeftR   proc
        public  ATLAS_UpLeftR


        mov     ax, [bp].Sub_cols               ; calc max right end
        dec     ax

        push    ds                              ; get hardware scroll flag
        mov     bx, _DATA
        mov     ds, bx
        mov     bx, ds:HardwareScroll
        pop     ds

        .if     <bx                ne PROTECT_HS_OFF > and
        .if     <[bp].leftscroll   eq 0              > and
        .if     <[bp].rightscroll  eq ax             > and
        .if     <[bp].leftdest     eq 0              > and
        .if     <[bp].rightdest    eq ax             > and
        .if     <[bp].topdest      eq 0              > and
        .if     <[bp].bottomscroll eq SCREEN_HEIGHT-2>
            call    ATLAS_UpLeftRHard
        .else
            call    ATLAS_UpLeftRSoft
        .endif
        ret

ATLAS_UpLeftR   endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_UpLeftRHard                               *
;*                                                                      *
;* DESCRIPTIVE NAME:    Video device handler Scroll Up/Left             *
;*                      Move a one line by hardware.                    *
;*                                                                      *
;* 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 ***************************
ATLAS_UpLeftRHard   proc
        public  ATLAS_UpLeftRHard

        call    HideCursor                  ; hide cursor

        ; scroll shadow buffer

        mov     si, [bp].PVBMoveSrcOff      ; setup shadow buffer src/dst ptrs
        mov     di, [bp].PVBMoveDestOff

        mov     ax,[bp].PVBMoveCount        ; get move bytes
        shr     ax, 1
        mul     [bp].RowsToMove             ; setup row loop counter
        mov     cx, ax

        mov     ax, _DATA                   ; setup shadow buf selector
        mov     ds, ax
        mov     es, ds:VideoBuffSel
        mov     ds, ds:VideoBuffSel

        add     si, shadow                  ; adjust src/dst ptrs
        add     di, shadow
        rep     movsw                       ; Move Cells

        ; scroll APA

        call    SetupAPAMove                ; setup APA move mode

        mov     ax, _DATA                   ; setup DATA selector
        mov     ds, ax
        mov     ds, ds:VideoBuffSel

        mov     bx, ds:VGA_APAStart         ; get APA start address

        mov     ax, [bp].topscroll          ; modify APA top address
        sub     ax, [bp].topdest
        mov     dx, APA_WIDTH*FONT_HEIGHT
        mul     dx
        add     ds:VGA_APAStart, ax
                                            ; move system reserved line
        mov     ds, [bp].PVB_SEL            ; setup APA selector
        mov     es, [bp].PVB_SEL
        mov     si, APA_WIDTH*FONT_HEIGHT*(SCREEN_HEIGHT-1) ; setup src/dst ptrs
        add     si, bx
        mov     di, si
        add     di, ax
        push    si                          ; save current reserved line addr

        mov     cx, APA_WIDTH*FONT_HEIGHT   ;set move count

        rep     movsb                       ; move system reserved line

        mov     ax, _DATA                   ; set hardware APA start address
        mov     ds, ax
        mov     ds, ds:VideoBuffSel
        mov     ax, ds:VGA_APAStart
        call    SetAPAStart
                                            ; clear lines
        call    SetupAPAWrite               ; setup APA write mode

        xor     al, al
        call    SetClsColor                 ; set clear color

        pop     di                          ; setup target ptr
        mov     cx, APA_WIDTH*FONT_HEIGHT/2 ; setup clear counter

        mov     ax, 0ffffh
        rep     stosw                       ; clear status line

        call    ShowCursor                  ; show cursor

        ret

ATLAS_UpLeftRHard   endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_UpLeftRSoft                               *
;*                                                                      *
;* DESCRIPTIVE NAME:    Video device handler Scroll Up/Left             *
;*                      Move a one line by software.                    *
;*                                                                      *
;* 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 ***************************
ATLAS_UpLeftRSoft   proc
        public  ATLAS_UpLeftRSoft

        call    HideCursor                  ; hide cursor

        call    SetupAPAWrite               ; setup APA write mode

        shl     [bp].Sub_PVBend, 1          ; adjust PVB buffer end

        mov     ax, _DATA                   ; setup DATA segment
        mov     ds, ax
        mov     ds, ds:VideoBuffSel

        mov     ax, [bp].APAMoveSrcOff      ; setup exchange offset
        add     ax, ds:VGA_APAStart
        mov     [bp].MoveSrcOff, ax
        mov     ax, [bp].APAMoveDestOff
        add     ax, ds:VGA_APAStart
        mov     [bp].MoveDestOff, ax

        mov     si, [bp].PVBMoveSrcOff      ; setup shadow buffer src/dst ptrs
        mov     di, [bp].PVBMoveDestOff

        mov     dx, [bp].RowsToMove         ; setup row loop counter

UpLeftLoop:
        mov     ax, _DATA                   ; setup shadow buf selector
        mov     ds, ax
        mov     es, ds:VideoBuffSel
        mov     ds, ds:VideoBuffSel

        mov     [bp].MoveFlag, 0            ; clear dirty flag

        ; scroll shadow buffer first

        .if     <si ge 4> and               ; 
        mov     al, ds:shadow[si+3]         ; Source head is DBCS 2nd ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1+dbcsA2>       ; Overwrite DBCS
            mov     byte ptr ds:shadow[si-4], 20h        ; Fill Blank to first
            mov     byte ptr ds:shadow[si  ], 20h        ; Fill Blank to second
            mov     word ptr ds:shadow[si-2], EXTRA_ATTR ; reset flag
            mov     word ptr ds:shadow[si+2], EXTRA_ATTR ; reset flag

            mov     ah, byte ptr ds:shadow[si-3]         ; get back colors
            mov     al, byte ptr ds:shadow[si+1]
            and     ah, 0f0h                             ; mix two colors
            shr     al, 4
            or      al, ah
            mov     [bp].ColSrcHead, al                  ; save colors
            or      [bp].MoveFlag, SRC_HEAD              ; set dirty flag
        .endif                              ; 

        .if     <di ge 4> and               ; 
        mov     al, ds:shadow[di+3]         ; Target head is DBCS 2nd ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1+dbcsA2>       ; Overwrite DBCS 1st
            mov     byte ptr ds:shadow[di-4], 20h        ; set space
            mov     word ptr ds:shadow[di-2], EXTRA_ATTR ; reset flag

            mov     al, byte ptr ds:shadow[di-3]         ; get back color
            shr     al, 4
            mov     [bp].ColDstHead, al                  ; save color
            or      [bp].MoveFlag, DST_HEAD              ; set dirty flag
        .endif                              ; 

        mov     cx,[bp].PVBMoveCount        ; get move bytes
        shr     cx,1                        ; convert bytes to words
        add     si, shadow                  ; adjust src/dst ptrs
        add     di, shadow
        rep     movsw                       ; Move Cells
        sub     si, shadow                  ; restore src/dst ptrs
        sub     di, shadow

        .if     <si lt [bp].Sub_PVBend> and
        mov     al, ds:shadow[si+3]         ; Source tail is DBCS 1st ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1+dbcsA2>       ; Overwrite DBCS
            mov     byte ptr ds:shadow[si-4], 20h        ; Fill Blank to first
            mov     byte ptr ds:shadow[si  ], 20h        ; Fill Blank to second
            mov     word ptr ds:shadow[si-2], EXTRA_ATTR ; reset flag
            mov     word ptr ds:shadow[si+2], EXTRA_ATTR ; reset flag
            mov     byte ptr ds:shadow[di-4], 20h        ;Change Copied Byte to Space
            mov     word ptr ds:shadow[di-2], EXTRA_ATTR ;reset flag

            mov     ah, byte ptr ds:shadow[si-3]         ; get back colors
            mov     al, byte ptr ds:shadow[si+1]
            and     ah, 0f0h                             ; mix two colors
            shr     al, 4
            or      al, ah
            mov     [bp].ColSrcTail, al                  ; save colors
            mov     al, byte ptr ds:shadow[di-3]         ; get dest back color
            shr     al, 4
            mov     [bp].ColDstTail, al                  ; save dest color
            or      [bp].MoveFlag, SRC_TAIL              ; set dirty flag
        .endif                              ; 

        .if     <di lt [bp].Sub_PVBend> and
        mov     al, ds:shadow[di+3]         ; Target tail is DBCS 1st ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1+dbcsA2>       ; Overwrite DBCS 2nd
            mov     byte ptr ds:shadow[di  ], 20h        ; set space
            mov     word ptr ds:shadow[di+2], EXTRA_ATTR ; reset flag

            mov     al, byte ptr ds:shadow[di+1]         ; get back color
            shr     al, 4
            mov     [bp].ColDstTail, al                  ; save color
            or      [bp].MoveFlag, DST_TAIL              ; set dirty flag
        .endif                              ; 

        add     si, [bp].PVBMoveSkip        ; skip PVB src/dst ptrs to next line
        add     di, [bp].PVBMoveSkip        ; 

        xchg    si, [bp].MoveSrcOff         ; exchange src/dst ptr
        xchg    di, [bp].MoveDestOff        ; from PVB to APA

        ; scroll APA next

        ; process DBCS edges for APA

        mov     ax, [bp].PVB_SEL            ; setup APA selector
        mov     ds, ax
        mov     es, ax

        mov     ah, 0ffh                    ; preset clear byte

        .if     <bit [bp].MoveFlag and SRC_HEAD> ; clear source head edge DBCS ?

            ; clear source head - 1 char

            mov     al, [bp].ColSrcHead     ; set clear color
            shr     al, 4
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
            dec     si
ULSrcHeadLoop1:
            mov     ds:[si], ah             ; clear char box
            add     si, APA_WIDTH
            loop    ULSrcHeadLoop1
            sub     si, FONT_HEIGHT*APA_WIDTH-1

            ; clear source head char

            mov     al, [bp].ColSrcHead     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
ULSrcHeadLoop2:
            mov     ds:[si], ah             ; clear char box
            add     si, APA_WIDTH
            loop    ULSrcHeadLoop2
            sub     si, FONT_HEIGHT*APA_WIDTH
        .endif

        .if     <bit [bp].MoveFlag and DST_HEAD> ; clear dest   head edge DBCS ?

            ; clear destination head - 1 char

            mov     al, [bp].ColDstHead     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
            dec     di
ULDstHeadLoop:
            mov     ds:[di], ah             ; clear char box
            add     di, APA_WIDTH
            loop    ULDstHeadLoop
            sub     di, FONT_HEIGHT*APA_WIDTH-1
        .endif

        ; move APA contents

        call    SetupAPAMove                ; setup APA move mode

        mov     bx, FONT_HEIGHT
UpLeftAPALoop:
        mov     cx, [bp].APAMoveCount       ; move one line
        rep     movsb
        add     si,[bp].APAMoveSkip         ; skip to next line
        add     di,[bp].APAMoveSkip

        dec     bx                          ; loop
        jnz     UpLeftAPALoop

        sub     si, FONT_HEIGHT*APA_WIDTH   ; restore src/dst ptrs
        sub     di, FONT_HEIGHT*APA_WIDTH
        add     si, [bp].APAMoveCount       ; skip APA src/dst ptrs to the end
        add     di, [bp].APAMoveCount       ; 

        call    SetupAPAWrite               ; setup APA write mode

        .if     <bit [bp].MoveFlag and SRC_TAIL> ; clear source tail edge DBCS ?

            ; clear source tail char

            mov     al, [bp].ColSrcTail     ; set clear color
            shr     al, 4
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
            dec     si
ULSrcTailLoop1:
            mov     ds:[si], ah             ; clear char box
            add     si, APA_WIDTH
            loop    ULSrcTailLoop1
            sub     si, FONT_HEIGHT*APA_WIDTH-1

            ; clear source tail + 1 char

            mov     al, [bp].ColSrcTail     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
ULSrcTailLoop2:
            mov     ds:[si], ah             ; clear char box
            add     si, APA_WIDTH
            loop    ULSrcTailLoop2
            sub     si, FONT_HEIGHT*APA_WIDTH

            ; clear destination tail char

            mov     al, [bp].ColDstTail     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
            dec     di
ULSrcTailLoop3:
            mov     ds:[di], ah             ; clear char box
            add     di, APA_WIDTH
            loop    ULSrcTailLoop3
            sub     di, FONT_HEIGHT*APA_WIDTH-1
        .endif

        .if     <bit [bp].MoveFlag and DST_TAIL> ; clear dest   tail edge DBCS ?

            ; clear destination tail + 1 char

            mov     al, [bp].ColDstTail     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
ULDstTailLoop:
            mov     ds:[di], ah             ; clear char box
            add     di, APA_WIDTH
            loop    ULDstTailLoop
            sub     di, FONT_HEIGHT*APA_WIDTH
        .endif

        add     si, [bp].APAMoveSkip        ; skip APA src/dst ptrs to next row
        add     si, (FONT_HEIGHT-1)*APA_WIDTH
        add     di, [bp].APAMoveSkip
        add     di, (FONT_HEIGHT-1)*APA_WIDTH

        xchg    si, [bp].MoveSrcOff         ; exchange src/dst ptr
        xchg    di, [bp].MoveDestOff        ; from APA to PVB

        dec     dx                          ; dec loop counter
        jz      UpLeftExit
        jmp     UpLeftLoop                  ; continue to loop

UpLeftExit:
        call    ShowCursor                  ; show cursor

        ret

ATLAS_UpLeftRSoft   endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_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 ***************************
ATLAS_DnRightR  proc
        public  ATLAS_DnRightR

        mov     ax, [bp].Sub_cols               ; calc max right end
        dec     ax

        push    ds                              ; get hardware scroll flag
        mov     bx, _DATA
        mov     ds, bx
        mov     bx, ds:HardwareScroll
        pop     ds

        .if     <bx                ne PROTECT_HS_OFF > and
        .if     <[bp].leftscroll   eq 0              > and
        .if     <[bp].rightscroll  eq ax             > and
        .if     <[bp].leftdest     eq 0              > and
        .if     <[bp].rightdest    eq ax             > and
        .if     <[bp].bottomdest   eq SCREEN_HEIGHT-2> and
        .if     <[bp].topscroll    eq 0              >
            call    ATLAS_DnRightRHard
        .else
            call    ATLAS_DnRightRSoft
        .endif
        ret

ATLAS_DnRightR  endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_DnRightRHard                              *
;*                                                                      *
;* DESCRIPTIVE NAME:    Video device handler Scroll Down/Right          *
;*                      Move a one line by hardware.                    *
;*                                                                      *
;* 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 ***************************
ATLAS_DnRightRHard   proc
        public  ATLAS_DnRightRHard

        call    HideCursor                  ; hide cursor

        ; scroll shadow buffer

        mov     si, [bp].PVBMoveSrcOff      ; setup shadow buffer src/dst ptrs
        mov     di, [bp].PVBMoveDestOff

        mov     ax,[bp].PVBMoveCount        ; get move bytes
        shr     ax, 1
        mul     [bp].RowsToMove             ; setup row loop counter
        mov     cx, ax

        mov     ax, _DATA                   ; setup shadow buf selector
        mov     ds, ax
        mov     es, ds:VideoBuffSel
        mov     ds, ds:VideoBuffSel

        add     si, shadow+2                ; adjust src/dst ptrs
        add     di, shadow+2
        rep     movsw                       ; Move Cells

        ; scroll APA

        call    SetupAPAMove                ; setup APA move mode

        mov     ax, _DATA                   ; setup DATA selector
        mov     ds, ax
        mov     ds, ds:VideoBuffSel

        mov     bx, ds:VGA_APAStart         ; get APA start address

        mov     ax, [bp].topdest            ; modify APA top address
        sub     ax, [bp].topscroll
        mov     dx, APA_WIDTH*FONT_HEIGHT
        mul     dx
        sub     ds:VGA_APAStart, ax

        push    ax                          ; set hardware APA start address
        push    bx
        mov     ax, ds:VGA_APAStart
        call    SetAPAStart
        pop     bx
        pop     ax
                                            ; move system reserved line
        mov     ds, [bp].PVB_SEL            ; setup APA selector
        mov     es, [bp].PVB_SEL
        mov     si, APA_WIDTH*FONT_HEIGHT*SCREEN_HEIGHT-1   ; setup src/dst ptrs
        add     si, bx
        mov     di, si
        sub     di, ax

        mov     cx, APA_WIDTH*FONT_HEIGHT   ;set move count

        rep     movsb                       ; move system reserved line

        call    ShowCursor                  ; show cursor

        ret

ATLAS_DnRightRHard  endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_DnRightRSoft                              *
;*                                                                      *
;* DESCRIPTIVE NAME:    Video device handler Scroll Down/Right          *
;*                      Move a one line by software.                    *
;*                                                                      *
;* 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 ***************************
ATLAS_DnRightRSoft  proc
        public  ATLAS_DnRightRSoft

        call    HideCursor                  ; hide cursor

        call    SetupAPAWrite               ; setup APA write mode

        shl     [bp].Sub_PVBend, 1          ; adjust PVB buffer end

        mov     ax, _DATA                   ; setup DATA segment
        mov     ds, ax
        mov     ds, ds:VideoBuffSel

        mov     ax, [bp].APAMoveSrcOff      ; setup exchange offset
        add     ax, ds:VGA_APAStart
        mov     [bp].MoveSrcOff, ax
        mov     ax, [bp].APAMoveDestOff
        add     ax, ds:VGA_APAStart
        mov     [bp].MoveDestOff, ax

        mov     si, [bp].PVBMoveSrcOff      ; setup shadow buffer src/dst ptrs
        mov     di, [bp].PVBMoveDestOff

        mov     dx, [bp].RowsToMove         ; setup row loop counter

DnRightLoop:
        mov     ax, _DATA                   ; setup shadow buf selector
        mov     ds, ax
        mov     es, ds:VideoBuffSel
        mov     ds, ds:VideoBuffSel

        mov     [bp].MoveFlag, 0            ; clear dirty flag

        ; scroll shadow buffer first

        .if     <si lt [bp].Sub_PVBend> and ; 
        mov     al, ds:shadow[si+3]         ; Source head is DBCS 1st ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1>              ; Overwrite DBCS
            mov     byte ptr ds:shadow[si  ], 20h        ; Fill Blank to first
            mov     byte ptr ds:shadow[si+4], 20h        ; Fill Blank to second
            mov     word ptr ds:shadow[si+2], EXTRA_ATTR ; reset flag
            mov     word ptr ds:shadow[si+6], EXTRA_ATTR ; reset flag

            mov     ah, byte ptr ds:shadow[si+1]         ; get back colors
            mov     al, byte ptr ds:shadow[si+5]
            and     ah, 0f0h                             ; mix two colors
            shr     al, 4
            or      al, ah
            mov     [bp].ColSrcHead, al                  ; save colors
            or      [bp].MoveFlag, SRC_HEAD              ; set dirty flag
        .endif                              ; 

        .if     <di lt [bp].Sub_PVBend> and ; 
        mov     al, ds:shadow[di+3]         ; Target head is DBCS 1st ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1>              ; Overwrite DBCS 2nd
            mov     byte ptr ds:shadow[di+4], 20h        ; set space
            mov     word ptr ds:shadow[di+6], EXTRA_ATTR ; reset flag

            mov     al, byte ptr ds:shadow[di+5]         ; get back color
            shr     al, 4
            mov     [bp].ColDstHead, al                  ; save color
            or      [bp].MoveFlag, DST_HEAD              ; set dirty flag
        .endif                              ; 

        mov     cx,[bp].PVBMoveCount        ; get move bytes
        shr     cx,1                        ; convert bytes to words
        add     si, shadow+2                ; adjust src/dst ptrs
        add     di, shadow+2
        rep     movsw                       ; Move Cells
        sub     si, shadow+2                ; restore src/dst ptrs
        sub     di, shadow+2

        .if     <si ge 0> and
        mov     al, ds:shadow[si+3]         ; Source tail is DBCS 2nd ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1>              ; Overwrite DBCS
            mov     byte ptr ds:shadow[si  ], 20h        ; Fill Blank to first
            mov     byte ptr ds:shadow[si+4], 20h        ; Fill Blank to second
            mov     word ptr ds:shadow[si+2], EXTRA_ATTR ; reset flag
            mov     word ptr ds:shadow[si+6], EXTRA_ATTR ; reset flag
            mov     byte ptr ds:shadow[di+4], 20h        ;Change Copied Byte to Space
            mov     word ptr ds:shadow[di+6], EXTRA_ATTR ;reset flag

            mov     ah, byte ptr ds:shadow[si+1]         ; get back colors
            mov     al, byte ptr ds:shadow[si+5]
            and     ah, 0f0h                             ; mix two colors
            shr     al, 4
            or      al, ah
            mov     [bp].ColSrcTail, al                  ; save colors
            mov     al, byte ptr ds:shadow[di+1]         ; get dest back color
            shr     al, 4
            mov     [bp].ColDstTail, al                  ; save dest color
            or      [bp].MoveFlag, SRC_TAIL              ; set dirty flag
        .endif                              ; 

        .if     <di ge 0> and
        mov     al, ds:shadow[di+3]         ; Target tail is DBCS 2nd ?
        and     al, dbcsA1+dbcsA2           ; 
        .if     <al eq dbcsA1>              ; Overwrite DBCS 1st
            mov     byte ptr ds:shadow[di  ], 20h        ; set space
            mov     word ptr ds:shadow[di+2], EXTRA_ATTR ; reset flag

            mov     al, byte ptr ds:shadow[di+1]         ; get back color
            shr     al, 4
            mov     [bp].ColDstTail, al                  ; save color
            or      [bp].MoveFlag, DST_TAIL              ; set dirty flag
        .endif                              ; 

        sub     si, [bp].PVBMoveSkip        ; skip PVB src/dst ptrs to next line
        sub     di, [bp].PVBMoveSkip        ; 

        xchg    si, [bp].MoveSrcOff         ; exchange src/dst ptr
        xchg    di, [bp].MoveDestOff        ; from PVB to APA

        ; scroll APA next

        ; process DBCS edges for APA

        mov     bx, ds:VGA_APAStart         ; get APA start address
        mov     ax, [bp].PVB_SEL            ; setup APA selector
        mov     ds, ax
        mov     es, ax

        mov     ah, 0ffh                    ; preset clear byte

        .if     <bit [bp].MoveFlag and SRC_HEAD> ; clear source head edge DBCS ?

            ; clear source head char

            mov     al, [bp].ColSrcHead     ; set clear color
            shr     al, 4
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
DRSrcHeadLoop1:
            mov     ds:[si], ah             ; clear char box
            sub     si, APA_WIDTH
            loop    DRSrcHeadLoop1
            add     si, FONT_HEIGHT*APA_WIDTH+1

            ; clear source head + 1 char

            mov     al, [bp].ColSrcHead     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
DRSrcHeadLoop2:
            mov     ds:[si], ah             ; clear char box
            sub     si, APA_WIDTH
            loop    DRSrcHeadLoop2
            add     si, FONT_HEIGHT*APA_WIDTH-1
        .endif

        .if     <bit [bp].MoveFlag and DST_HEAD> ; clear dest   head edge DBCS ?

            ; clear destination head + 1 char

            mov     al, [bp].ColDstHead     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
            inc     di
DRDstHeadLoop:
            mov     ds:[di], ah             ; clear char box
            sub     di, APA_WIDTH
            loop    DRDstHeadLoop
            add     di, FONT_HEIGHT*APA_WIDTH-1
        .endif

        ; move APA contents

        call    SetupAPAMove                ; setup APA move mode

        mov     bx, FONT_HEIGHT
DnRightAPALoop:
        mov     cx, [bp].APAMoveCount       ; move one line
        rep     movsb
        sub     si,[bp].APAMoveSkip         ; skip to next line
        sub     di,[bp].APAMoveSkip

        dec     bx                          ; loop
        jnz     DnRightAPALoop

        add     si, FONT_HEIGHT*APA_WIDTH   ; restore src/dst ptrs
        add     di, FONT_HEIGHT*APA_WIDTH
        sub     si, [bp].APAMoveCount       ; skip APA src/dst ptrs to the end
        sub     di, [bp].APAMoveCount       ; 

        call    SetupAPAWrite               ; setup APA write mode

        .if     <bit [bp].MoveFlag and SRC_TAIL> ; clear source tail edge DBCS ?

            ; clear source tail - 1 char

            mov     al, [bp].ColSrcTail     ; set clear color
            shr     al, 4
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
DRSrcTailLoop1:
            mov     ds:[si], ah             ; clear char box
            sub     si, APA_WIDTH
            loop    DRSrcTailLoop1
            add     si, FONT_HEIGHT*APA_WIDTH+1

            ; clear source tail char

            mov     al, [bp].ColSrcTail     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
DRSrcTailLoop2:
            mov     ds:[si], ah             ; clear char box
            sub     si, APA_WIDTH
            loop    DRSrcTailLoop2
            add     si, FONT_HEIGHT*APA_WIDTH-1

            ; clear destination tail char

            mov     al, [bp].ColDstTail     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
            inc     di
DRSrcTailLoop3:
            mov     ds:[di], ah             ; clear char box
            sub     di, APA_WIDTH
            loop    DRSrcTailLoop3
            add     di, FONT_HEIGHT*APA_WIDTH-1
        .endif

        .if     <bit [bp].MoveFlag and DST_TAIL> ; clear dest   tail edge DBCS ?

            ; clear destination tail - 1 char

            mov     al, [bp].ColDstTail     ; set clear color
            call    SetClsColor
            mov     cx, FONT_HEIGHT         ; set loop counter
DRDstTailLoop:
            mov     ds:[di], ah             ; clear char box
            sub     di, APA_WIDTH
            loop    DRDstTailLoop
            add     di, FONT_HEIGHT*APA_WIDTH
        .endif

        sub     si, [bp].APAMoveSkip        ; skip APA src/dst ptrs to next row
        sub     si, (FONT_HEIGHT-1)*APA_WIDTH
        sub     di, [bp].APAMoveSkip
        sub     di, (FONT_HEIGHT-1)*APA_WIDTH

        xchg    si, [bp].MoveSrcOff         ; exchange src/dst ptr
        xchg    di, [bp].MoveDestOff        ; from APA to PVB

        dec     dx                          ; dec loop counter
        jz      DnRightExit
        jmp     DnRightLoop                 ; continue to loop

DnRightExit:
        call    ShowCursor                  ; show cursor

        ret

ATLAS_DnRightRSoft  endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_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: MonoToColor, FillWithSBCS                       *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
ATLAS_CFillR proc
        public  ATLAS_CFillR

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

        mov     ax,[bp].FillCellLow
        .if     <[bp].Sub_colors ne 0>      ; Color or Black&White
            mov     dx, EXTRA_ATTR          ; Clear
        .else                               ; Mono Mode
            call    MonoToColor
            mov     dx, bx
        .endif

        call    FillWithSBCS                ; call shadow & APA update routine

        ret

ATLAS_CFillR endp

;;---------------------------------------------------------------------------
;; Conversion Routine.                                              J-KK0901
;; MONO Attribute ---> Atlas Color Attribute
;;  Input  : AX - Char/Attr
;;  Output : AX - Char/Attr and BX - Attr1/2
;;---------------------------------------------------------------------------
MonoToColor proc near
        public  MonoToColor

        xor     bh, bh
        mov     bl, ah
        .if     < bl a 7fh >            ; Blink ?
            sub     bl, 80h
            shl     bx, 1
            add     bx, offset MonoToColor_Table
            mov     ah, byte ptr cs:[bx]
            mov     bl, byte ptr cs:[bx+1]
            .if     <bit <byte ptr [bp].Sub_Option> and BLINK_STATE> ;Blink State On
                or      bl, ATLAS_BLINK ; Set blink in attr1
            .else
                or      ah, 80h         ; Set high intensity bit
            .endif
        .else
            shl     bx, 1
            add     bx, offset MonoToColor_Table
            mov     ah, byte ptr cs:[bx]
            mov     bl, byte ptr cs:[bx+1]
        .endif
        mov     bh, EXTRA_ATTR shr 8

        ret
MonoToColor endp

MonoToColor_Table:
        db      0,0                     ;0      Non Display
        db      07h,40h                 ;1      UnderLine
        db      07h,0                   ;2      Normal
        db      07h,0                   ;3      Normal
        db      07h,0                   ;4      Normal
        db      07h,0                   ;5      Normal
        db      07h,0                   ;6      Normal
        db      07h,0                   ;7      Normal
        db      0,0                     ;8      Non Display
        db      0fh,40h                 ;9      H-Int and Under
        db      0fh,0                   ;a      H-Int
        db      0fh,0                   ;b      H-Int
        db      0fh,0                   ;c      H-Int
        db      0fh,0                   ;d      H-Int
        db      0fh,0                   ;e      H-Int
        db      0fh,0                   ;f      H-Int

        db      070h,0                  ;10     Normal
        db      077h,40h                ;11     Under
        db      077h,0                  ;12     Normal
        db      077h,0                  ;13     Normal
        db      077h,0                  ;14     Normal
        db      077h,0                  ;15     Normal
        db      077h,0                  ;16     Normal
        db      077h,0                  ;17     Normal
        db      070h,0                  ;18     H-Int
        db      07fh,00h                ;19     H-Int & Under          J-KK1004
        db      07fh,0                  ;1a     H-Int
        db      07fh,0                  ;1b     H-Int
        db      07fh,0                  ;1c     H-Int
        db      07fh,0                  ;1d     H-Int
        db      07fh,0                  ;1e     H-Int
        db      07fh,0                  ;1f     H-Int

        db      070h,0                  ;20     Normal
        db      077h,40h                ;21     Under
        db      077h,0                  ;22     Normal
        db      077h,0                  ;23     Normal
        db      077h,0                  ;24     Normal
        db      077h,0                  ;25     Normal
        db      077h,0                  ;26     Normal
        db      077h,0                  ;27     Normal
        db      070h,0                  ;28     H-Int
        db      07fh,00h                ;29     H-Int & Under          J-KK1004
        db      07fh,0                  ;2a     H-Int
        db      07fh,0                  ;2b     H-Int
        db      07fh,0                  ;2c     H-Int
        db      07fh,0                  ;2d     H-Int
        db      07fh,0                  ;2e     H-Int
        db      07fh,0                  ;2f     H-Int

        db      070h,0                  ;30     Normal
        db      077h,40h                ;31     Under
        db      077h,0                  ;32     Normal
        db      077h,0                  ;33     Normal
        db      077h,0                  ;34     Normal
        db      077h,0                  ;35     Normal
        db      077h,0                  ;36     Normal
        db      077h,0                  ;37     Normal
        db      070h,0                  ;38     H-Int
        db      07fh,00h                ;39     H-Int & Under          J-KK1004
        db      07fh,0                  ;3a     H-Int
        db      07fh,0                  ;3b     H-Int
        db      07fh,0                  ;3c     H-Int
        db      07fh,0                  ;3d     H-Int
        db      07fh,0                  ;3e     H-Int
        db      07fh,0                  ;3f     H-Int

        db      070h,0                  ;40     Normal
        db      077h,40h                ;41     Under
        db      077h,0                  ;42     Normal
        db      077h,0                  ;43     Normal
        db      077h,0                  ;44     Normal
        db      077h,0                  ;45     Normal
        db      077h,0                  ;46     Normal
        db      077h,0                  ;47     Normal
        db      070h,0                  ;48     H-Int
        db      07fh,00h                ;49     H-Int & Under          J-KK1004
        db      07fh,0                  ;4a     H-Int
        db      07fh,0                  ;4b     H-Int
        db      07fh,0                  ;4c     H-Int
        db      07fh,0                  ;4d     H-Int
        db      07fh,0                  ;4e     H-Int
        db      07fh,0                  ;4f     H-Int

        db      070h,0                  ;50     Normal
        db      077h,40h                ;51     Under
        db      077h,0                  ;52     Normal
        db      077h,0                  ;53     Normal
        db      077h,0                  ;54     Normal
        db      077h,0                  ;55     Normal
        db      077h,0                  ;56     Normal
        db      077h,0                  ;57     Normal
        db      070h,0                  ;58     H-Int
        db      07fh,00h                ;59     H-Int & Under          J-KK1004
        db      07fh,0                  ;5a     H-Int
        db      07fh,0                  ;5b     H-Int
        db      07fh,0                  ;5c     H-Int
        db      07fh,0                  ;5d     H-Int
        db      07fh,0                  ;5e     H-Int
        db      07fh,0                  ;5f     H-Int

        db      070h,0                  ;60     Normal
        db      077h,40h                ;61     Under
        db      077h,0                  ;62     Normal
        db      077h,0                  ;63     Normal
        db      077h,0                  ;64     Normal
        db      077h,0                  ;65     Normal
        db      077h,0                  ;66     Normal
        db      077h,0                  ;67     Normal
        db      070h,0                  ;68     H-Int
        db      07fh,00h                ;69     H-Int & Under          J-KK1004
        db      07fh,0                  ;6a     H-Int
        db      07fh,0                  ;6b     H-Int
        db      07fh,0                  ;6c     H-Int
        db      07fh,0                  ;6d     H-Int
        db      07fh,0                  ;6e     H-Int
        db      07fh,0                  ;6f     H-Int

        db      070h,0                  ;70     Reverse
        db      77h,40h                 ;71     Under
        db      77h,0                   ;72     Normal
        db      77h,0                   ;73     Normal
        db      77h,0                   ;74     Normal
        db      77h,0                   ;75     Normal
        db      77h,0                   ;76     Normal
        db      77h,0                   ;77     Normal
        db      070h,0                  ;78     Reverse
        db      07fh,00h                ;79     H-Int & Under          J-KK1004
        db      07fh,0                  ;7a     H-Int
        db      07fh,0                  ;7b     H-Int
        db      07fh,0                  ;7c     H-Int
        db      07fh,0                  ;7d     H-Int
        db      07fh,0                  ;7e     H-Int
        db      07fh,0                  ;7f     H-Int

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     FillWithSBCS                                    *
;*                                                                      *
;* DESCRIPTIVE NAME:    Update Shadow & APA with SBCS character &       *
;*                      ATLAS 3byte attributes.                         *
;* INPUT:                                                               *
;* AX     = char/attr0                                                  *
;* DX     = attr1/attr2                                                 *
;*                                                                      *
;* INTERNAL REFERENCES: FontGetSBCS                                     *
;*                                                                      *
;* EXTERNAL REFERENCES: ShowCursor, HideCursor, SetupAPAWrite,          *
;*                      SetAPAColor                                     *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
FillWithSBCS proc
        public  FillWithSBCS

        call    HideCursor                  ; hide cursor

        ; setup shadow buffer & APA access

        mov     cx, _DATA                   ; setup shadow buffer segment
        mov     ds, cx
        mov     ds, ds:VideoBuffSel
        mov     si, [bp].PVBFillOff         ; setup offset
        add     si, shadow

        mov     es, [bp].PVB_SEL            ; setup target APA selector
        mov     di, ds:VGA_APAStart         ; 
        add     di, [bp].APAFillOff         ; setup target APA offset

        push    ax
        push    dx
        push    si
        push    di

        call    SetupAPAWrite               ; setup APA write mode

        ; process fill area edge DBCS

        mov     bx, [bp].RowsToFill         ; setup row loop counter

FillEdgeLoop0:
        mov     al, ds:[si+3]
        and     al, dbcsA1+dbcsA2
        .if     <al eq dbcsA1+dbcsA2>       ; line head is DBCS 2nd ?
            mov     byte ptr ds:[si-4], ' ' ; Fill Blank to first
            mov     word ptr ds:[si-2], EXTRA_ATTR  ; reset flag
            mov     al, ds:[si-3]           ; clear APA
            dec     di
            call    SetAPAColor
            xor     al, al
            mov     cx, FONT_HEIGHT
FillEdgeLoop1:
            stosb
            add     di, APA_WIDTH-1
            loop    FillEdgeLoop1
            sub     di, APA_WIDTH*FONT_HEIGHT-1
        .endif

        mov     cx, [bp].PVBFillCount       ; skip to line end
        add     si, cx
        push    di
        shr     cx, 2
        add     di, cx

        mov     al, ds:[si-1]
        and     al, dbcsA1+dbcsA2
        .if     <al eq dbcsA1>              ; line tail is DBCS 1st ?
            mov     byte ptr ds:[si  ], ' ' ; Fill Blank to second
            mov     word ptr ds:[si+2], EXTRA_ATTR  ; reset flag
            mov     al, ds:[si+1]           ; clear APA
            call    SetAPAColor
            xor     al, al
            mov     cx, FONT_HEIGHT
FillEdgeLoop2:
            stosb
            add     di, APA_WIDTH-1
            loop    FillEdgeLoop2
            sub     di, APA_WIDTH*FONT_HEIGHT
        .endif

        add     si, [bp].PVBFillSkip        ; skip to next row
        pop     di
        add     di, APA_WIDTH*FONT_HEIGHT

        dec     bx                          ; dec row loop counter
        jnz     FillEdgeLoop0

        pop     di
        pop     si
        pop     dx
        pop     ax

        ; fill PVB (shadow buffer) with AX:DX

        mov     bx, [bp].RowsToFill         ; setup row loop counter

FillLoop1:
        mov     cx, [bp].PVBFillCount       ; setup column counter
        shr     cx, 2                       ; convert from byte to cell

FillLoop2:
        mov     ds:[si  ], ax               ; fill one cell
        mov     ds:[si+2], dx
        add     si, 4
        loop    FillLoop2                   ; continue to loop

        add     si, [bp].PVBFillSkip        ; skip to next row
        dec     bx                          ; dec row loop counter
        jnz     FillLoop1                   ; continue to loop

        ; First, fill with font image & underline

        push    dx                          ; save attr1/attr2

        ; get font image to fill in APA

        push    ax                          ; save char/attr0
        mov     ah, dh                      ; get SBCS font
        call    FontGetSBCS
        pop     ax                          ; restore char/attr0

        pop     dx                          ; restore attr1/attr2
        push    dx                          ; save attr1/attr2

        .if     <bit dl and A_UNDERLINE_BIT> ; prepare underline processing
            mov     bh, 0ffh
        .else
            mov     bh, ds:[si+FONT_HEIGHT-1]
        .endif

        ; setup APA write

        mov     al, ah                      ; set APA write color
        call    SetAPAColor

        mov     dx, [bp].RowsToFill         ; setup row counter

        ; process font image

FillLoop3:
        push    si                          ; save font top ptr
        mov     bl, FONT_HEIGHT-1           ; setup font height loop counter

FillLoop4:
        mov     cx, [bp].APAFillCount       ; setup one line counter

        lodsb                               ; get one line font
        rep     stosb                       ; store one line font

        add     di, [bp].APAFillSkip        ; skip to next line
        dec     bl                          ; dec font hight loop counter
        jnz     FillLoop4                   ; continue to loop

        ; process underline

        mov     cx, [bp].APAFillCount       ; setup one line counter
        mov     al, bh                      ; get lowermost line
        rep     stosb                       ; store it
        add     di, [bp].APAFillSkip        ; skip to next line

        pop     si                          ; restore font top ptr
        dec     dx                          ; dec row counter
        jnz     FillLoop3                   ; continue to loop

        pop     bx                          ; restore attr1/attr2
        mov     bh, bl                      ; save attr1 to bh

        ; Second, draw horizontal & vertical grid

        .if     <bit bh and A_VERT_BIT+A_HORZ_BIT>  ; grid on ?

            mov     ax, _DATA               ; setup global data segment
            mov     ds, ax
            mov     ds, ds:VideoBuffSel

            mov     di, [bp].APAFillOff     ; setup target APA offset
            add     di, ds:VGA_APAStart

            mov     al, ds:VGA_GridColor    ; set grid color
            call    SetGridColor

            mov     dx, [bp].RowsToFill     ; setup row counter

FillLoop5:

            ; process horizontal grid

            .if     <bit bh and A_HORZ_BIT> ; horizontal grid on ?
                push    di                  ; save APA pointer
                mov     al, 0ffh            ; setup grid pattern
                mov     cx, [bp].APAFillCount ; setup one line counter
                rep     stosb               ; store horizontal grid
                pop     di                  ; restore APA pointer
            .endif

            ; process vertical grid

            .if     <bit bh and A_VERT_BIT> ; vertical grid on ?

                mov     al, 080h            ; setup grid pattern
                mov     bl, FONT_HEIGHT     ; setup font height loop counter

FillLoop6:
                mov     cx, [bp].APAFillCount ; setup one line counter

FillLoop7:
                mov     ah, es:[di]         ; get current image into comp reg.
                stosb                       ; draw grid
                loop    FillLoop7

                add     di, [bp].APAFillSkip ; skip to next line
                dec     bl                  ; dec font hight loop counter
                jnz     FillLoop6           ; continue to loop
            .else
                add     di, FONT_HEIGHT*APA_WIDTH ; skip to next line
            .endif

            dec     dx                      ; dec row counter
            jnz     FillLoop5               ; continue to loop
        .endif

        call    ShowCursor                  ; show cursor

        ret

FillWithSBCS endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;*   Store the start and end offset of the updated buffer      J-KK1017 *
;*                                                                      *
;*   Input   :  [bp].Sub_cols     - Cols                                *
;*              [bp].Sub_offset   - Start Offset                        *
;*              DI                - End Offset + 2 or 4        J-KK0205 *
;*              AL = 1 or 2       - 1: 2 bytes cell or 2: 4 bytes cell  *
;*                                                                      *
;*   Output  :  [bp].XVS_StartRow                                       *
;*              [bp].XVS_EndRow                                         *
;********************** END OF SPECIFICATIONS ***************************
Set_StartEndRow proc near
        public  Set_StartEndRow

        push    cx                      ; 
        push    dx                      ; 
        push    di                      ;                               J-KK0205
        xor     ah, ah                  ;                               J-KK0205
        sub     di, ax                  ; Adjust End Offset             J-KK0205
        sub     di, ax                  ;                               J-KK0205

        mov     cl, al                  ; 
        mov     ax, [bp].Sub_cols       ; 
        shl     ax, cl                  ; X2 or X4
        mov     cx, ax                  ; 

        mov     ax, [bp].Sub_offset     ; 
        xor     dx, dx                  ; 
        div     cx                      ; 
        mov     [bp].XVS_StartRow, ax   ; 
        mov     ax, di                  ; 
        xor     dx, dx                  ; 
        div     cx                      ; 
        mov     [bp].XVS_EndRow, ax     ; 

        pop     di                      ;                               J-KK0205
        pop     dx                      ; 
        pop     cx                      ; 
        ret
Set_StartEndRow endp


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

        call    UpdateRegenB

        ret
UpdateCARegenB endp

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

        call    UpdateRegenB

        ret
UpdateCAAttrB endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     ATLAS_LVBrecttoPVB                              *
;*                                                                      *
;* DESCRIPTIVE NAME:    Call a Update Regen (PVB) routine from LVB      *
;*                      For DBCS VGA mode.                              *
;*                                                                      *
;* INPUT:                                                               *
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)      *
;* ES:DI  --->  LVB Address                     (see XGAWRITE.ASM)      *
;*                                                                      *
;* INTERNAL REFERENCES: ShowCursor, HideCursor, SetupAPAWrite           *
;*                                                                      *
;* EXTERNAL REFERENCES: UpdateRegenOneLineB                             *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
ATLAS_LVBrecttoPVB proc
public  ATLAS_LVBrecttoPVB

        call    HideCursor                  ; hide cursor

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

        mov     ds, [bp].LVB_SEL            ; setup selectors
        mov     ax, _DATA
        mov     es, ax
        mov     es, es:VideoBuffSel

        mov     si,[bp].LVBFillOff          ; setup ofsets
        mov     di,[bp].PVBFillOff

        shl     [bp].Sub_PVBend, 1          ; adjust PVB buffer end

        mov     dx,[bp].RowsToFill          ; set row loop counter

ATLASLPLoop:
        mov     cx,[bp].LVBFillCount        ; set column counter
        shr     cx, 1                                                   ;J-TS100391

        mov     bx, [bp].LVBFillCount
        add     bx, si
        .if     <bit [bp].Sub_option and f_restfromlvb>                 ;J-TS113092
            .if     <bx b [bp].Sub_Buffsize> and ; last char is DBCS 1st ?
;J-TS011492        mov     al, byte ptr ds:[bx+1+TOEXT]
            mov     al, byte ptr ds:[bx+1+TOEXT-2]                      ;J-TS011492
            and     al, dbcsA1+dbcsA2
            .if     <al e dbcsA1>
                inc     cx                  ; include DBCS 2nd
                or      [bp].Sub_Option, f_end_adjust ; set adjust flag
            .endif

            .if     <si ge 2> and           ; first char is DBCS 2nd ?
            mov     al, byte ptr ds:[si+1+TOEXT]
            and     al, dbcsA1+dbcsA2
            .if     <al e dbcsA1+dbcsA2>
                sub     si, 2               ; include DBCS 1st
                sub     di, 4
                inc     cx
            .endif
        .endif                                                          ;J-TS113092

        push    dx                                                      ;J-TS100391
        call    UpdateRegenOneLineB         ; update one line
        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_restfromlvb> and             ;J-TS113092
        .if     <bit [bp].Sub_Option and f_end_adjust>
            sub     si, 2                   ; adjust ptrs
            sub     di, 4                   ; 
            and     [bp].Sub_Option, not f_end_adjust ; clear adjust flag
        .endif

        dec     dx                                                      ;J-TS100391
        jnz     ATLASLPLoop                                             ;J-TS100391

        call    ShowCursor                  ; show cursor

        ret

ATLAS_LVBrecttoPVB endp

ATLAS_CArecttoPVB   proc
        public  ATLAS_CArecttoPVB
        ret
ATLAS_CArecttoPVB   endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     FontGetSBCS                                     *
;*                                                                      *
;* DESCRIPTIVE NAME:    Get font image buffer address of SBCS.          *
;*                                                                      *
;* INPUT:                                                               *
;* AL           Character Code                                          *
;* AH           SBCS character set (attr2 of ATLAS 3byte format)        *
;*                                                                      *
;* OUTPUT                                                               *
;* DS:SI  --->  Font Image buffer                                       *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
FontGetSBCS proc    near
        public  FontGetSBCS

        mov     si, _DATA                   ; set font buffer selector
        mov     ds, si                      ; calc font buffer offset
        mov     ds, ds:VideoBuffSel

        and     ah, SBCS_TYPE_MASK          ; get SBCS font type
        .if     <ah eq TypeF>               ; extra SBCS
            mov     si, VGA_ExtensionFont.VGA_FontImage
        .else                               ; base SBCS
            mov     si, VGA_BaseFont.VGA_FontImage
        .endif
        xor     ah, ah                      ; CharCode
        add     si, ax                      ; offset = image + CharCode * 1
        shl     ax, 1                       ; CharCode * 2
        add     si, ax                      ; offset = image + CharCode * 3
        shl     ax, 3                       ; CharCode * 16
        add     si, ax                      ; offset = image + CharCode * 19
        ret
FontGetSBCS endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     FontGetDBCS                                     *
;*                                                                      *
;* DESCRIPTIVE NAME:    Get font image buffer address of DBCS.          *
;*                                                                      *
;* INPUT:                                                               *
;* AX           Character Code                                          *
;*                                                                      *
;* OUTPUT                                                               *
;* DS:SI  --->  Font Image buffer                                       *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: _FONTGET                                        *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
FontGetDBCS proc    near
        public  FontGetDBCS

        pusha                               ; save all registers
        push    es

        mov     [bp].DBCSGetStrucLen, 6     ; setup structure
        push    ax                          ; push character code
        push    ss                          ; push font buffer pointer address
        lea     si, [bp].DBCSGetStrucLen
        push    si
        call    FNTGETIMAGEADDR             ; get font image

        pop     es                          ; restore all registers
        popa

        lds     si, [bp].DBCSFont           ; get font address
        ret
FontGetDBCS endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     CLEARSHADOWAPA                                  *
;*                                                                      *
;* DESCRIPTIVE NAME:    Clear shadow buffer & APA.                      *
;*                                                                      *
;* INPUT:  None                                                         *
;* OUTPUT: None                                                         *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: SetupAPAWrite                                   *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
CLEARSHADOWAPA  proc    near
        public  CLEARSHADOWAPA

        push    bp
        mov     bp, sp
        pusha

        ; clear APA

        call    SetupAPAWrite               ; setup APA write mode

        mov     es, [bp+4]                  ; setup APA pointer
        xor     di, di
        mov     al, 0                       ; set write color black
        call    SetClsColor
        mov     cx, 8000h                   ; set loop counter
        mov     ax, 0ffffh
        rep     stosw                       ; clear APA

        ; clear shadow buffer

        mov     ax, _DATA                   ; setup shadow buffer pointer
        mov     es, ax
        mov     es, es:VideoBuffSel
        mov     di, shadow
        mov     cx, SHADOW_LENGTH/4         ; set loop counter

ClearShadowAPALoop:
        mov     word ptr es:[di], 0720h     ; clear char/attr0
        add     di, 2
        mov     word ptr es:[di], EXTRA_ATTR+CHANGE_BIT ; clear attr1/attr2
        add     di, 2
        loop    ClearShadowAPALoop

        popa
        pop     bp
        ret     2

CLEARSHADOWAPA  endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     INITAPA                                         *
;*                                                                      *
;* DESCRIPTIVE NAME:    Re-initialize APA start address                 *
;*                                                                      *
;* INPUT:  None                                                         *
;* OUTPUT: None                                                         *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: SetAPAStart                                     *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
INITAPA proc    near
        public  INITAPA

        push    ds
        mov     ax, _DATA
        mov     ds, ax

        mov     ax, FONT_HEIGHT*SCREEN_HEIGHT-1
        mov     ds:PrevLineComp, ax
        mov     ds:MaxLineComp, ax

        mov     ds, ds:VideoBuffSel

        xor     ax, ax
        mov     ds:VGA_APAStart, ax

        call    SetAPAStart

        pop     ds
        ret
INITAPA endp

R2CSEG  ENDS
        END
