;*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   XGASCROL.ASM -- Common Buffer Scroll Routines for EGA, VGA, BGA

;/*****************************************************************************
;*
;* SOURCE FILE NAME = XGASCROL.ASM
;*
;* DESCRIPTIVE NAME = BUFFERUPDATE scroll routines
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  This module contains routines that run at ring 2 in
;*              order to directly access the hardware.
;*
;* FUNCTIONS    ScrollUp, ScrollDown
;*              ScrollLeft, ScrollRight
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG        APAR    CHANGE DESCRIPTION
;*   --------  ----------  -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx   xxxxxxx
;*   03/25/89  @P1         D132    PL, DCR 132 changes
;*   04/11/91              D1348   NAKADA, Enable DBCS support in Vio-Window
;*   04/19/93  KY02        PJ08380 KAZZ, Deleted the lines which may NOT be
;*                                 required to fix PTR #JS05303 by K. Yokomizo.
;****************************************************************************/

        .286c                           ; 286 protect mode instructions

        .xlist
        INCLUDE struc.inc               ; Structure macro
        INCLUDE error2.inc              ; Subsystem error equates
        INCLUDE vdhstruc.inc            ; Buffer update data structures
        INCLUDE vdhctl.inc              ; Conditional Assemply Control  ;MS01
        INCLUDE vdhequ.inc              ; Buffer update equates
        INCLUDE xgamac.inc                                              ;@P1
IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
        INCLUDE cga2epo.inc                                             ;;EPOCH ;; added for J-FUNC
        INCLUDE pmwinx.inc                                              ;;EPOCH ;; added for J-FUNC
        INCLUDE pmaviop.inc                                             ;;EPOCH ;; added for J-FUNC
        INCLUDE wdhequ.inc                                              ;;EPOCH ;; added for J-FUNC
        extrn   DOSGETSEG:FAR                                           ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
        .list

        EXTRN   SetGenParms:NEAR        ; Set up general buffer update parms @P1
IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        EXTRN   DOSGETSHRSEG:FAR        ; Get shared segment(s)         ;;EPOCH ;; added for J-FUNC
        PUBLIC  BvscbSel                                                ;;EPOCH ;; added for J-FUNC
;@an07  PUBLIC  pBvscbSels              ;@an01                          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
_DATA   SEGMENT WORD PUBLIC 'DATA'                                      ;;EPOCH ;; added for J-FUNC
;@an07 pBvscbSels      DD  0            ; offset:selector pointing at   ;;EPOCH ;; added for J-FUNC
                                        ; a group of Bvscb selectors.   ;;EPOCH ;; added for J-FUNC
BvscbSel DW     255 Dup (0)             ; Selector for BVSCBnn          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
BvsSegLabel DB  '\SHAREMEM\BVS\BVS'     ; BVSCB segment label           ;;EPOCH ;; added for J-FUNC
LNOFF   EQU     $ - BvsSegLabel                                         ;;EPOCH ;; added for J-FUNC
Bvs_CP_ID LABEL WORD                                                    ;;EPOCH ;; added for J-FUNC
        DB      '0'                                                     ;;EPOCH ;; added for J-FUNC
        DB      '0'                                                     ;;EPOCH ;; added for J-FUNC
        DB       0                                                      ;;EPOCH ;; added for J-FUNC
HexDigit DB     '0123456789ABCDEF'      ; Look up Tbl for Hex digit     ;;EPOCH ;; added for J-FUNC
_DATA   ENDS                                                            ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC

IF VDHCGA AND (1 - CGA_ALWAYS_FAST) ; IF VDHCGA AND NOT CGA_ALWAYS_FAST ;@P1

;/*
;** If CGA video memory accesses may need to wait for retrace,
;** these routines are necessary. (See MAKEFILE)
;*/

        extrn   CGA_REP_MOVSW:far                                       ;@P1
        extrn   CGA_REP_STOSW:far                                       ;@P1
        extrn   CGA_REP_MOVSB_INCSI_LOOP:far                            ;@P1
        extrn   CGA_REP_MOVSW_STOSW_LOOP:far                            ;@P1
        extrn   CGA_REP_INCDI_STOSB_LOOP:far                            ;@P1
        extrn   CGA_REP_STOSB_INCDI_LOOP:far                            ;@P1
        extrn   CGA_REP_LODSB_STOSW_LOOP:far                            ;@P1
        extrn   CGA_REP_MOVSB_INCDI_LOOP:far                            ;@P1
        extrn   CGA_REP_MOVSW_ADDSI2_LOOP:far                           ;@P1
ENDIF   ;VDHCGA                                                         ;@P1

IFDEF D1348 ;BufferUpdate with dbcs bits handling
        extrn   MoveUpLeftWrld:near
        extrn   MoveDownRightWrld:near
ENDIF ;D1348

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

;/****************************************************************************
;*
;* SUBROUTINE NAME:     ScrollLeft
;*
;* DESCRIPTIVE NAME:    Video device handler scroll left routine
;*
;* FUNCTION:    Process scroll left sub-function
;*              Scrolls a portion of the PVB, LVB left a specified
;*              number of times and then fill the vacant portion
;*              with the user specified cell.
;*
;* ENTRY POINT: ScrollLeft
;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                     (target buffer - LVB, PVB)
;*   DWORD  Application data address
;*   DWORD  Application data2 address (cell to be used to fill void)
;*   WORD   Index (5)
;*   WORD   Starting row              (top row)
;*   WORD   Starting column           (left column)
;*   WORD   Secondary row             (bottom row)
;*   WORD   Secondary column          (right column)
;*   WORD   RepeatFactor              (# of times to scroll)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = SetForScroll
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/

                PUBLIC  ScrollLeft
ScrollLeft      PROC

        mov     bx,LEFT
        call    SetForScroll
        jc      sclfx

        test    [bp].ScrollFlags,DOMOVE
        jz      sclf10

        push    bx
        call    MoveUpLeft
        pop     bx

sclf10: call    FillRectWithCell
        xor     ax,ax

sclfx:  ret

ScrollLeft      ENDP


;/****************************************************************************
;*
;* SUBROUTINE NAME:     ScrollUp
;*
;* DESCRIPTIVE NAME:    Video device handler scroll up routine
;*
;* FUNCTION:    Process scroll up sub-function
;*              Scrolls a portion of the PVB, LVB up a specified
;*              number of times and then fill the vacant portion
;*              with the user specified cell.
;*
;* ENTRY POINT: ScrollUp
;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                     (target buffer - LVB, PVB)
;*   DWORD  Application data address
;*   DWORD  Application data2 address (cell to be used to fill void)
;*   WORD   Index (3)
;*   WORD   Starting row              (top row)
;*   WORD   Starting column           (left column)
;*   WORD   Secondary row             (bottom row)
;*   WORD   Secondary column          (right column)
;*   WORD   RepeatFactor              (# of times to scroll)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = SetForScroll
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/

                PUBLIC  ScrollUp
ScrollUp        PROC
        mov     bx,UP
        call    SetForScroll
        jc      scupx

        test    [bp].ScrollFlags,DOMOVE
        jz      scup10

        push    bx
        call    MoveUpLeft
        pop     bx

scup10: call    FillRectWithCell
        xor     ax,ax

scupx:  ret

ScrollUp        ENDP


;/****************************************************************************
;*
;* SUBROUTINE NAME:     ScrollRight
;*
;* DESCRIPTIVE NAME:    Video device handler scroll right routine
;*
;* FUNCTION:    Process scroll right sub-function
;*              Scrolls a portion of the PVB, LVB right to a specified
;*              number of times and then fill the vacant portion with
;*              the user specified cell.
;*
;* ENTRY POINT: ScrollRight
;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                     (target buffer - LVB, PVB)
;*   DWORD  Application data address
;*   DWORD  Application data2 address (cell to be used to fill void)
;*   WORD   Index (6)
;*   WORD   Starting row              (top row)
;*   WORD   Starting column           (left column)
;*   WORD   Secondary row             (bottom row)
;*   WORD   Secondary column          (right column)
;*   WORD   RepeatFactor              (# of times to scroll)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = SetForScroll
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/

                PUBLIC  ScrollRight
ScrollRight     PROC

        mov     bx,RIGHT
        call    SetForScroll
        jc      scrtx

        test    [bp].ScrollFlags,DOMOVE
        jz      scrt10

        push    bx
        call    MoveDownRight
        pop     bx

scrt10: call    FillRectWithCell
        xor     ax,ax

scrtx:  ret

ScrollRight     ENDP


;/****************************************************************************
;*
;* SUBROUTINE NAME:     ScrollDown
;*
;* DESCRIPTIVE NAME:    Video device handler scroll down routine
;*
;* FUNCTION:    Process scroll down sub-function
;*              Scrolls a portion of the PVB, LVB down a specified
;*              number of times and then fill the vacant portion
;*              with the user specified cell.
;*
;* ENTRY POINT: ScrollDown
;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                     (target buffer - LVB, PVB)
;*   DWORD  Application data address
;*   DWORD  Application data2 address (cell to be used to fill void)
;*   WORD   Index (4)
;*   WORD   Starting row              (top row)
;*   WORD   Starting column           (left column)
;*   WORD   Secondary row             (bottom row)
;*   WORD   Secondary column          (right column)
;*   WORD   RepeatFactor              (# of times to scroll)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = SetForScroll
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: SetForScroll,
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/

                PUBLIC  ScrollDown
ScrollDown      PROC

        mov     bx,DOWN
        call    SetForScroll
        jc      scdnx

        test    [bp].ScrollFlags,DOMOVE
        jz      scdn10

        push    bx
        call    MoveDownRight
        pop     bx

scdn10: call    FillRectWithCell
        xor     ax,ax

scdnx:  ret

ScrollDown      ENDP

;/****************************************************************************
;*
;* SUBROUTINE NAME:     LVBToPVB
;*
;* DESCRIPTIVE NAME:    Video device handler copy LVB rectangle to PVB
;*
;* FUNCTION:    Copy a rectangle from an LVB on to the PVB
;*
;* ENTRY POINT: LVBToPVB
;*   LINKAGE:   Near Call from BUFFERUPDATE rouinte
;*
;* INPUT:
;*
;* AX = 0
;* SS:BP  --->  Stack frame                     (see VDHSTRUC.INC)
;* DS:SI  --->  Parameter block buffer          (see XGABUFUP.ASM)
;* ES:DI  --->  Mode data in environment buffer (see XGABUFUP.ASM)
;*
;* PARAMETER BLOCK FORMAT:
;*
;*   SIZE   DESCRIPTION
;*   ----   -----------
;*
;*   WORD   Parameter length
;*   WORD   Flags                     (target buffer - LVB, PVB)
;*   DWORD  Application data address
;*   DWORD  Application data2 address (cell to be used to fill void)
;*   WORD   Index (4)
;*   WORD   Starting row              (top row)
;*   WORD   Starting column           (left column)
;*   WORD   Secondary row             (bottom row)
;*   WORD   Secondary column          (right column)
;*   WORD   RepeatFactor              (# of times to scroll)
;*   WORD   LogicalBufSel
;*
;* OUTPUT:
;*
;* EXIT-NORMAL: AX = 0
;*
;* EXIT-ERROR:  AX = SetForScroll
;*
;* EFFECTS:     All
;*
;* INTERNAL REFERENCES: SetForScroll,MoveLVBRectToPVB
;*
;* EXTERNAL REFERENCES: None
;*
;****************************************************************************/

                PUBLIC  LVBToPVB                                ;@P1 begin
LVBToPVB        PROC

        xor     ax,ax                   ; clear error code
        push    ds:[si].RepeatFactor    ; save the old repeat factor
        push    ds:[si].Flags           ; save the old flags
        test    [si].Flags, PVB_SEL_BIT ; write to the PVB
        jz      ltpx                    ;   NO, do nothing

        or      [si].Flags, LVB_SEL_BIT ; LVB bit needs to be set

        mov     ds:[si].RepeatFactor,-1 ; this will be a scroll without move
        mov     bx,LVBPVB               ; pretend to be a scroll function
        call    SetForScroll            ; get the scroll parameters
        jc      ltpx

        call    MoveLVBRectToPVB        ; The fill rect is the rect to move
        xor     ax,ax

ltpx:   lds     si,[bp].ParmBuf
        pop     ds:[si].Flags           ; restore the old flags
        pop     ds:[si].RepeatFactor    ; 
        ret

LVBToPVB        ENDP                                            ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = SetForScroll
;*
;* DESCRIPTION   =
;*
;*      Set up parameters for a scroll
;*      SetForScroll does range checking and parameter adjustment for
;*      all scroll functions.  This is valid for 2 and 4 byte cell LVBs
;*      and for the fill cell supplied as 2 or 4 bytes.
;*
;*      All scrolls consist of two basic operations.  The first is
;*      move a rectangle.  The second is fill a rectangle.  The rectangle
;*      to be moved will be NULL if the scroll is greater than the
;*      depth of the rectangle in the direction of movement.
;*
;*      This routine calculates the source rectangle and destination
;*      rectangle for the move.  For UP and LEFT scrolling, the rectangle
;*      should be copied beginning to end.  For DOWN and RIGHT the copy
;*      should go from end to beginning.  This routine provides the
;*      correct buffer offset for the appropriate starting point of
;*      the rectangle.
;*
;* INPUT         =
;*
;*          BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;*          SS:BP - local data storage area
;*          DS:SI - user passed parameter block
;*          ES:DI - mode data structure
;*          [bp].minrow - index of top most row in LVB (PVB coordinates)
;*          [bp].mincol - index of left most row in LVB (PVB coordinates)
;*          [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;*          [bp].maxcol - index of right most row in LVB (PVB coordinates)
;*
;* OUTPUT        =
;*
;*       CARRY CLEAR
;*           BX = LVB selector if LVB scroll is indicated else 0
;*
;*           [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;*           [bp].ScrollFlags  = either DOFILL or DOMOVE+DOFILL
;*
;*           [bp].RowsToFill   = rows to be filled with the default cell
;*
;*           [bp].PVBFillOff   = offset of start of PVB fill rectangle
;*           [bp].PVBFillCount = # of bytes per fill line in PVB
;*           [bp].PVBFillSkip  = # of bytes to skip to reach next PVB line
;*
;*           [bp].LVBFillOff   = offset of start of LVB fill rectangle
;*           [bp].LVBFillCount = # of bytes per fill line in LVB
;*           [bp].LVBFillSkip  = # of bytes to skip to reach next LVB line
;*
;*           [bp].FillCellLow  = first word of default fill cell
;*           [bp].FillCellHigh = second word of default fill cell
;*
;*         if DOMOVE is set in ScrollFlags
;*
;*           [bp].RowsToMove     = number of rows to move
;*
;*           [bp].PVBMoveCount   = # of bytes per PVB row to move
;*           [bp].PVBMoveSkip    = # of bytes to skip to get to the next row
;*           [bp].PVBMoveSrcOff  = offset to start of PVB source buffer
;*           [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;*           [bp].LVBMoveCount   = # of bytes per PVB row to move
;*           [bp].LVBMoveSkip    = # of bytes to skip to get to the next row
;*           [bp].LVBMoveSrcOff  = offset to start of PVB source buffer
;*           [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;*       CARRY SET
;*           [bp].ScrollFlags = 0
;*
;*   CALLS   SetBaseRects, AdjustRects, CalcMoveValues, CalcFillValues
;*
;*   USES    AX,CX,DX,SI,DS,FLAGS
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

                PUBLIC  SetForScroll                            ;@P1 begin
SetForScroll    PROC

        call    SetGenParms             ; set general parameters for all
                                        ; buffer update functions
        call    SetBaseRects            ; do basic value setting on source,
                                        ; destination and fill rectangles

        .if     <nc>                    ; parms from SetBaseRects are good

            call    AdjustRects         ; adjust the rectangle values for the
                                        ; specific type of scroll

                                        ; At this point we have source and
                                        ; and destination rectangles that are
                                        ; both entirely contained in the LVB.
                                        ; We have also calculated the
                                        ; rectangle that will be left void
                                        ; when the moved rectangle is copied.

            test    [bp].ScrollFlags,DOMOVE ; Are move rectangles != NULL?
            .if     <nz>                ;   Yes, calculate the move parms
                call    CalcMoveValues  ;   and buffer lengths
            .endif
            call    CalcFillValues      ; calculate the fill rectangle parms
            mov     bx, [bp].LVB_SEL    ; (bx) = LVB selector

            clc

        .endif

        ret

SetForScroll    ENDP                                            ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = SetBaseRects
;*
;* DESCRIPTION   =
;*
;*      Set default values for source, dest and fill rectangles
;*
;*      SetBaseRects does basic rectangle value setting for the source
;*      and destination rectangles for the rectangle that needs to be
;*      moved as part of the scroll.  Default values for the fill
;*      rectangle are also set.
;*
;*      This routine also checks and adjusts the RepeatFactor, the number
;*      of rows or columns to be scrolled.  If it is 0, an error is returned.
;*
;* INPUT     =  BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;*              SS:BP - local data storage area
;*              DS:SI - user passed parameter block
;*              ES:DI - mode data structure
;*              [bp].minrow - index of top most row in LVB (PVB coordinates)
;*              [bp].mincol - index of left most row in LVB (PVB coordinates)
;*              [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;*              [bp].maxcol - index of right most row in LVB (PVB coordinates)
;*
;* OUTPUT   =
;*
;*          CARRY CLEAR
;*              CX = repeat factor
;*              [bp].ScrollFlags  = DOMOVE+DOFILL
;*              [bp].topscroll    = ParmBlock->Row
;*              [bp].topdest      =   "
;*              [bp].topfill      =   "
;*              [bp].leftscroll   = ParmBlock->Col
;*              [bp].leftdest     =   "
;*              [bp].leftfill     =   "
;*              [bp].rightscroll  = ParmBlock->Row2
;*              [bp].rightdest    =   "
;*              [bp].rightfill    =   "
;*              [bp].bottomscroll = ParmBlock->Col2
;*              [bp].bottomdest   =   "
;*              [bp].bottomfill   =   "
;*
;*          CARRY SET
;*              [bp].ScrollFlags = 0
;*
;*
;* CALLS   none
;*
;* USES    AX,CX,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;*                 topscroll = parmrow
;*                 leftscroll = parmcol
;*                 bottomscroll = parmrow2
;*                 rightscroll = parmcol2
;*                 topdest = topscroll
;*                 leftdest = leftscroll
;*                 bottomdest = bottomscroll
;*                 rightdest = rightscroll
;*                 topfill = topscroll
;*                 leftfill = leftscroll
;*                 bottomfill = bottomscroll
;*                 rightfill = rightscroll
;*                 DoMoveFlag = TRUE
;*                 DoFillFlag = TRUE
;*                 if  (RepCount == 0)
;*                     DoMoveFlag = FALSE
;*                     DoFillFlag = FALSE
;*                     set error
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                PUBLIC  SetBaseRects                            ;@P1 begin
SetBaseRects    PROC
        mov     ax,[si].Row         ; set all of the top coordinates
        .if     <ax b [bp].minrow> near
            mov     ax,[bp].minrow
        .endif
                                        ; BUGBUG this is really should not be
        .if     <ax a [bp].maxrow> near ; here, but it is necessary to pass
            mov     ax,[bp].maxrow      ; the component tests.  Remove it at
        .endif                          ; the first opertunity.

        test    bx,LVBPVB
        .if     <z>                     ; NOT LVB to PVB
            .if     <ax b es:[di].ScrlRectTop> near
                mov     ax,es:[di].ScrlRectTop
            .endif

            .if     <ax a es:[di].ScrlRectBottom> near
                mov     ax,es:[di].ScrlRectBottom
            .endif
        .endif

        mov     [bp].topscroll,ax
        mov     [bp].topdest,ax
        mov     [bp].topfill,ax

        mov     cx,[si].Row2        ; set all of the bottom coordinates
        .if     <cx a [bp].maxrow> near
            mov     cx,[bp].maxrow
        .endif
        test    bx,LVBPVB
        .if     <z>                     ; NOT LVB to PVB
            .if     <cx a es:[di].ScrlRectBottom> near
                mov     cx,es:[di].ScrlRectBottom
            .endif
        .endif

        mov     [bp].bottomscroll,cx
        mov     [bp].bottomdest,cx
        mov     [bp].bottomfill,cx

        .if     <ax a cx> near      ; rectangle is not valid
            mov     ax,ERROR_VIO_ROW
            jmp     sbrerr
        .endif

        mov     ax,[si].Col         ; set all of the left coordinates
        .if     <ax b [bp].mincol> near
            mov     ax,[bp].mincol
        .endif
                                        
        .if     <ax a [bp].maxcol> near 
            mov     ax,[bp].maxcol      
        .endif                          

        test    bx,LVBPVB
        .if     <z>                     ; NOT LVB to PVB
            .if     <ax b es:[di].ScrlRectLeft> near
                mov     ax,es:[di].ScrlRectLeft
            .endif

            .if     <ax a es:[di].ScrlRectRight> near
                mov     ax,es:[di].ScrlRectRight
            .endif
        .endif

        mov     [bp].leftscroll,ax
        mov     [bp].leftdest,ax
        mov     [bp].leftfill,ax

        mov     cx,[si].Col2        ; set all of the right coordinates
        .if     <cx a [bp].maxcol> near
            mov     cx,[bp].maxcol
        .endif
        test    bx,LVBPVB
        .if     <z>                     ; NOT LVB to PVB
            .if     <cx a es:[di].ScrlRectRight> near
                mov     cx,es:[di].ScrlRectRight
            .endif
        .endif
        mov     [bp].rightscroll,cx
        mov     [bp].rightdest,cx
        mov     [bp].rightfill,cx

        .if     <ax a cx> near      ; rectangle is not valid
            mov     ax,ERROR_VIO_COL
            jmp     sbrerr
        .endif

        cmp     ds:[si].ParmLength,LVBRowOff; Does caller want the touch rect?
        .if     <ae>                        ;   Yes, return the Touch Rect
            mov     ax,[bp].leftscroll
            mov     ds:[si].TouchXLeft,ax
            mov     ax,[bp].topscroll
            mov     ds:[si].TouchYTop,ax
            mov     ax,[bp].rightscroll
            mov     ds:[si].TouchXRight,ax
            mov     ax,[bp].bottomscroll
            mov     ds:[si].TouchYBottom,ax
        .endif

        mov     [bp].ScrollFlags, DOMOVE + DOFILL
        mov     cx, [si].RepeatFactor
        or      cx,cx               ; clears carry
        .if     <z>
            mov     [bp].ScrollFlags,cx ; do not Move or Fill
            xor     ax,ax           ; not an error not to scroll
            stc
        .endif

sbrx:   ret

sbrerr: stc
        jmp     sbrx

SetBaseRects    ENDP                                            ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = AdjustRects
;*
;* DESCRIPTION   =
;*
;*      Adjust values for source, dest and fill rectangles
;*
;*      AdjustRects does scroll specific rectangle value setting for the
;*      source and destination rectangles for the rectangle that needs to
;*      be moved as part of the scroll.  Values for the fill rectangle are
;*      also adjusted.
;*
;*      This routine also checks and adjusts the RepeatFactor, the number
;*      of rows or columns to be scrolled.  If the value would clear the
;*      entire scroll rectangle, (no area left to be moved) the DOMOVE
;*      flag in the scroll flags is cleared.
;*
;*      If the repeat factor is larger than the depth of the scroll rectangle
;*      in the direction it is being scrolled, the repeat factor is reduced
;*      to the depth of the scroll rectangle.
;*
;*
;* INPUT    =   BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;*              CX = repeat factor
;*              SS:BP - local data storage area
;*              DS:SI - user passed parameter block
;*              ES:DI - mode data structure
;*              [bp].topscroll  - source rectangle for move set to
;*              [bp].leftscroll   default values
;*              [bp].rightscroll
;*              [bp].bottomscroll
;*              [bp].topdest    - destination rectangle for move set
;*              [bp].leftdest     to default values
;*              [bp].rightdest
;*              [bp].bottomdest
;*              [bp].topfill    - rectangle left void by move set to
;*              [bp].leftfill     default values
;*              [bp].rightfill
;*              [bp].bottomfill
;*
;* OUTPUT    =
;*              CX = repeat factor adjusted to MIN (rect depth,repeat factor)
;*              [bp].ScrollFlags  =  DOMOVE clear if entire rectangle is vacant
;*
;*              [bp].topfill      = Rectangle that the scroll leaves vacant
;*              [bp].leftfill     =     "
;*              [bp].rightfill    =     "
;*              [bp].bottomfill   =     "
;*
;*            if  DOMOVE is set
;*              [bp].topscroll    = Rect adjusted to indicate source of move
;*              [bp].leftscroll   =     "
;*              [bp].rightscroll  =     "
;*              [bp].bottomscroll =     "
;*
;*              [bp].topdest      = Rect adjusted to indicate dest of move
;*              [bp].leftdest     =     "
;*              [bp].rightdest    =     "
;*              [bp].bottomdest   =     "
;*
;* CALLS   none
;*
;* USES    AX,CX,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;* UP:
;* DOWN:
;*     if (RepCount > bottomscroll - topscroll + 1)
;*         RepCount = bottomscroll - topscroll + 1
;*         DoMoveFlag = FALSE
;*     UP:
;*         topscroll = topscroll + RepCount
;*         bottomdest = bottomscroll - RepCount
;*         topfill = bottomdest + 1
;*     DOWN:
;*         bottomscroll = bottomscroll - RepCount
;*         topdest = topscroll + RepCount
;*         bottomfill = topdest - 1
;* LEFT:
;* RIGHT:
;*     if (RepCount > rightscroll - leftscroll + 1)
;*         RepCount = rightscroll - leftscroll + 1
;*         DoMoveFlag = FALSE
;*     LEFT:
;*         leftscroll = leftscroll + RepCount
;*         rightdest = rightscroll - RepCount
;*         leftfill = rightdest + 1
;*     RIGHT:
;*         rightscroll = rightscroll - RepCount
;*         leftdest = leftscroll + RepCount
;*         rightfill = leftdest - 1
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                PUBLIC  AdjustRects                             ;@P1 begin
AdjustRects     PROC
                                    ; correct coordinates for scroll type

        test    bx,UP+DOWN          ; Is this a scroll up or scroll down
        .if     <nz>                ;   Yes, do the up-down thing
            mov     ax,[bp].bottomscroll
            sub     ax,[bp].topscroll   ; (ax) = maximum possible scroll w/move
            .if     <cx a ax>
                and     [bp].ScrollFlags,NOT DOMOVE
                inc     ax          ; (ax) = scroll to clear entire rect
                mov     cx,ax       ; (cx) = maximum repcount
            .else
                test    bx,UP           ; Is this a scroll up?
                .if     <nz>            ;   Yes, do the up thing
                    add     [bp].topscroll,cx
                    mov     ax,[bp].bottomscroll
                    sub     ax,cx
                    mov     [bp].bottomdest,ax
                    inc     ax
                    mov     [bp].topfill,ax
                .else
                    sub     [bp].bottomscroll,cx
                    mov     ax,[bp].topscroll
                    add     ax,cx
                    mov     [bp].topdest,ax
                    dec     ax
                    mov     [bp].bottomfill,ax
                .endif
            .endif
        .else                           ; Do the left-right thing
            mov     ax,[bp].rightscroll
            sub     ax,[bp].leftscroll  ; (ax) = maximum possible scroll w/move
            .if     <cx a ax>
                and     [bp].ScrollFlags,NOT DOMOVE
                inc     ax              ; (ax) = scroll to clear entire rect
                mov     cx,ax           ; (cx) = maximum repcount
            .else
                test    bx,LEFT         ; Is this a scroll left?
                .if     <nz>            ;   Yes, do the left thing
                    add     [bp].leftscroll,cx
                    mov     ax,[bp].rightscroll
                    sub     ax,cx
                    mov     [bp].rightdest,ax
                    inc     ax
                    mov     [bp].leftfill,ax
                .else                   ; Do the Right thing
                    sub     [bp].rightscroll,cx
                    mov     ax,[bp].leftscroll
                    add     ax,cx
                    mov     [bp].leftdest,ax
                    dec     ax
                    mov     [bp].rightfill,ax
                .endif
            .endif
        .endif

        ret

AdjustRects     ENDP                                            ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = CalcMoveValues
;*
;* DESCRIPTION   =
;*
;*      Calculate values the move rectangle functions need
;*
;*      CalcMoveValues calculates the offsets into the source and destination
;*      rectangles used by the move functions.  The UP and LEFT scroll
;*      functions copy from the beginning of the buffer to the end.  The
;*      DOWN and RIGHT functions copy from the end of the buffer to the
;*      beginning.  This function provides the correct starting point
;*      for the scroll requested.
;*
;*      This routine also calculates the number of rows that need to
;*      be copied.  This value will always be at least one.
;*
;*      The number of bytes in each row is calculated.  The value of
;*      this number is always at least one * cellsize (2 or 4 bytes)
;*      and is always a multiple of cell size.
;*
;*      The number of bytes that need to be skipped to reach the start
;*      of the next row to be copied is calculated.  This value may be
;*      zero.
;*
;*      With the exception of the number of rows to move, all of the
;*      values above are calculated separately for the LVB and the PVB
;*      because the cell size may be different between the two.
;*
;* INPUT    =   BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;*              SS:BP - local data storage area
;*              DS:SI - user passed parameter block
;*              ES:DI - mode data structure
;*              [bp].lvb_width - width of the LVB in cells
;*              [bp].cellsize - number of bytes per cell in the LVB
;*
;*              [bp].minrow - index of top most row in LVB (PVB coordinates)
;*              [bp].mincol - index of left most row in LVB (PVB coordinates)
;*              [bp].maxrow - index of bottom most row in LVB (PVB coordinates)
;*              [bp].maxcol - index of right most row in LVB (PVB coordinates)
;*
;*              [bp].topscroll    = Rect adjusted to indicate source of move
;*              [bp].leftscroll   =     "
;*              [bp].rightscroll  =     "
;*              [bp].bottomscroll =     "
;*
;*              [bp].topdest      = Rect adjusted to indicate dest of move
;*              [bp].leftdest     =     "
;*              [bp].rightdest    =     "
;*              [bp].bottomdest   =     "
;*
;* OUTPUT   =
;*              [bp].RowsToMove     = number of rows to move
;*
;*              [bp].PVBMoveCount   = # of bytes per PVB row to move
;*              [bp].PVBMoveSkip    = # of bytes to skip to get to the next row
;*              [bp].PVBMoveSrcOff  = offset to start of PVB source buffer
;*              [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;*              [bp].LVBMoveCount   = # of bytes per PVB row to move
;*              [bp].LVBMoveSkip    = # of bytes to skip to get to the next row
;*              [bp].LVBMoveSrcOff  = offset to start of PVB source buffer
;*              [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* CALLS   none
;*
;* USES    AX,CX,DX,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;*          RowsToMove = bottomscroll - topscroll + 1
;*          PVBMoveCount = (rightscroll - leftscroll) * cellsize
;*          PVBRowSkip = modeCols * cellsize - PVBMoveCount
;*          LVBMoveCount = (rightscroll - leftscroll) * cellsize
;*          LVBRowSkip = lvb_width * cellsize - LVBMoveCount
;*          UP:
;*          LEFT:
;*              LVBMoveSrcOff = ((topscroll - minrow) * lvb_width +
;*                               (leftscroll - mincol)) * cellsize
;*              PVBMoveSrcOff = (topscroll * modeCols + leftscroll) *
;*                              cellsize
;*              LVBMoveDestOff = ((topdest - minrow) * lvb_width +
;*                                (leftdest - mincol)) * cellsize
;*              PVBMoveDestOff = (topdest * modeCols + leftdest) *
;*                              cellsize
;*          DOWN:
;*          RIGHT:
;*              LVBMoveSrcOff = ((bottomscroll - minrow) * lvb_width +
;*                               (rightscroll - mincol)) * cellsize
;*              PVBMoveSrcOff = (bottomscroll * modeCols + rightscroll) *
;*                              cellsize
;*              LVBMoveDestOff = ((bottomdest - minrow) * lvb_width +
;*                                (rightdest - mincol)) * cellsize
;*              PVBMoveDestOff = (bottomdest * modeCols + rightdest) *
;*                              cellsize
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                    PUBLIC  CalcMoveValues                      ;@P1 begin
CalcMoveValues      PROC

        mov     ax,[bp].bottomscroll    ; calculate the number of rows
        sub     ax,[bp].topscroll       ; to move
        inc     ax
        mov     [bp].RowsToMove,ax

        mov     cx,[bp].rightscroll     ; calculate bytes to move in PVB
        sub     cx,[bp].leftscroll
        inc     cx
        shl     cx,1
        mov     [bp].PVBMoveCount,cx


        mov     ax,es:[di].TextCols     ; calculate bytes to skip in PVB
        shl     ax,1
        sub     ax,cx
        mov     [bp].PVBMoveSkip,ax

        mov     ax,[bp].lvb_width       ; calculate bytes to skip in LVB
        shl     ax,1
        sub     ax,cx
        .if     <[bp].cellsize e WorldCellSize>
            shl     cx,1
            shl     ax,1
        .endif
        mov     [bp].LVBMoveCount,cx    ; bytes to move in LVB
        mov     [bp].LVBMoveSkip,ax
                                        ; calculate buffer copy addresses
        test    bx,UP+LEFT
        .if     <nz>                    ; Do the UP-LEFT thing
            mov     ax,[bp].topscroll   ; calculate PVB source offset
            mul     es:[di].TextCols
            add     ax,[bp].leftscroll
            shl     ax,1
            mov     [bp].PVBMoveSrcOff,ax

            mov     ax,[bp].topdest     ; calculate PVB destination offset
            mul     [bp].lvb_width
            add     ax,[bp].leftdest
            shl     ax,1
            mov     [bp].PVBMoveDestOff,ax

            mov     ax,[bp].topscroll   ; calculate LVB source offset
            sub     ax,[bp].minrow
            mul     [bp].lvb_width
            add     ax,[bp].leftscroll
            sub     ax,[bp].mincol
            shl     ax,1                ; (ax) = LVB src off for 2 byte cell
            mov     [bp].LVBMoveSrcOff,ax

            mov     ax,[bp].topdest     ; calculate LVB destination offset
            sub     ax,[bp].minrow
            mul     [bp].lvb_width
            add     ax,[bp].leftdest
            sub     ax,[bp].mincol
            shl     ax,1                ; (cx)= LVB dest off for 2 byte cell
            mov     [bp].LVBMoveDestOff,ax

            .if     <[bp].cellsize e WorldCellSize>
                shl     [bp].LVBMoveSrcOff,1    ; 4 bytes per cell
                shl     [bp].LVBMoveDestOff,1   ; 4 bytes per cell
            .endif

        .else                           ; Do the DOWN-RIGHT thing
            mov     ax,[bp].bottomscroll; calculate PVB source offset
            mul     es:[di].TextCols
            add     ax,[bp].rightscroll
            shl     ax,1
            mov     [bp].PVBMoveSrcOff,ax

            mov     ax,[bp].bottomdest  ; calculate PVB destination offset
            mul     [bp].lvb_width
            add     ax,[bp].rightdest
            shl     ax,1
            mov     [bp].PVBMoveDestOff,ax

            mov     ax,[bp].bottomscroll; calculate LVB source offset
            sub     ax,[bp].minrow
            mul     [bp].lvb_width
            add     ax,[bp].rightscroll
            sub     ax,[bp].mincol
            shl     ax,1                ; (ax) = LVB src off for 2 byte cell
            mov     [bp].LVBMoveSrcOff,ax

            mov     ax,[bp].bottomdest  ; calculate LVB destination offset
            sub     ax,[bp].minrow
            mul     [bp].lvb_width
            add     ax,[bp].rightdest
            sub     ax,[bp].mincol
            shl     ax,1                ; (cx)= LVB dest off for 2 byte cell
            mov     [bp].LVBMoveDestOff,ax
            .if     <[bp].cellsize e WorldCellSize>
                inc     [bp].LVBMoveSrcOff  ; start at last word of cell
                inc     [bp].LVBMoveDestOff ; start at last word of cell
                shl     [bp].LVBMoveSrcOff,1    ; 4 bytes per cell
                shl     [bp].LVBMoveDestOff,1   ; 4 bytes per cell
            .endif

        .endif
        ret

CalcMoveValues      ENDP                                        ;@P1 end

;/***************************************************************************
;*
;* FUNCTION NAME = CalcFillValues
;*
;* DESCRIPTION   =
;*
;*      Calculate values the fill rectangle function needs
;*
;*      CalcFillValues calculates the offset into the fill rectangle that
;*      is used by the fill function.
;*
;*      This routine also calculates the number of rows that need to
;*      be filled.  This value will always be at least one.
;*
;*      The number of bytes in each row is calculated.  The value of
;*      this number is always at least one * cellsize (2 or 4 bytes)
;*      and is always a multiple of cell size.
;*
;*      The number of bytes that need to be skipped to reach the start
;*      of the next row to be copied is calculated.  This value may be
;*      zero.
;*
;*      With the exception of the number of rows to move, all of the
;*      values above are calculated separately for the LVB and the PVB
;*      because the cell size may be different between the two.
;*
;* INPUT    =   BX - Flag indicating the type of scroll (UP,DOWN,LEFT,RIGHT)
;*              SS:BP - local data storage area
;*              DS:SI - user passed parameter block
;*              ES:DI - mode data structure
;*              [bp].lvb_width - width of the LVB in cells
;*              [bp].cellsize - number of bytes per cell in the LVB
;*
;*              [bp].minrow - index of top most row in LVB (PVB coordinates)
;*              [bp].mincol - index of left most row in LVB (PVB coordinates)
;*
;*              [bp].topfill      = Rect adjusted to indicate fill region
;*              [bp].leftfill     =     "
;*              [bp].rightfill    =     "
;*              [bp].bottomfill   =     "
;*
;* OUTPUT   =
;*              [bp].RowsToFill   = rows to be filled with the default cell
;*
;*              [bp].PVBFillCount = # of bytes per fill line in PVB
;*              [bp].PVBFillSkip  = # of bytes to skip to reach next PVB line
;*              [bp].PVBFillOff   = offset of beginning of PVB fill rectangle
;*
;*              [bp].LVBFillCount = # of bytes per fill line in LVB
;*              [bp].LVBFillSkip  = # of bytes to skip to reach next LVB line
;*              [bp].LVBFillOff   = offset of beginning of LVB fill rectangle
;*
;*              [bp].FillCellLow  = first word of default fill cell
;*              [bp].FillCellHigh = second word of default fill cell
;*
;* CALLS   none
;*
;* USES    AX,CX,DX,SI,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;*       RowsToFill = bottomfill - topfill + 1
;*       PVBFillOff = (topfill * modeCols + leftfill) * cellsize
;*       PVBFillCount = rightfill - leftfill * cellsize
;*       PVBFillSkip = modeCols * cellsize - PVBFillCount
;*       LVBFillOff = (leftfill - minrow) * lvb_width +
;*                    (topfill - mincol) * cellsize
;*       LVBFillCount = rightfill - leftfill * cellsize
;*       LVBFillSkip = modeCols * cellsize - LVBFillCount
;*       FillCellLow = first word of cell
;*       if (inputcellsize = 4)
;*           FillCellHigh = second word of cell
;*       else
;*           FillCellHigh = 0
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                    PUBLIC  CalcFillValues                      ;@P1 begin
CalcFillValues      PROC

        mov     ax,[bp].bottomfill      ; calculate the number of rows
        sub     ax,[bp].topfill         ; to fill
        inc     ax
        mov     [bp].RowsToFill,ax

        mov     ax,[bp].topfill         ; calculate PVB source offset
        mul     es:[di].TextCols
        add     ax,[bp].leftfill
        shl     ax,1
        mov     [bp].PVBFillOff,ax

        mov     cx,[bp].rightfill       ; calculate byte per PVB fill row
        sub     cx,[bp].leftfill
        inc     cx
        shl     cx,1
        mov     [bp].PVBFillCount,cx

        mov     ax,es:[di].TextCols     ; calculate bytes to skip in PVB
        shl     ax,1
        sub     ax,cx
        mov     [bp].PVBFillSkip,ax

        mov     ax,[bp].lvb_width       ; calculate bytes to skip in LVB
        shl     ax,1
        sub     ax,cx
        .if     <[bp].cellsize e WorldCellSize>
            shl     cx,1
            shl     ax,1
        .endif
        mov     [bp].LVBFillCount,cx    ; bytes to fill in LVB
        mov     [bp].LVBFillSkip,ax

        mov     ax,[bp].topfill         ; calculate LVB source offset
        sub     ax,[bp].minrow
        mul     [bp].lvb_width
        add     ax,[bp].leftfill
        sub     ax,[bp].mincol
        shl     ax,1

        .if     <[bp].cellsize e WorldCellSize>
            shl     ax,1
        .endif
        mov     [bp].LVBFillOff,ax

        test    bx,LVBPVB
        .if     <z>
IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
            lds     si,[si].AppCellAddr                                 ;;EPOCH ;; added for J-FUNC
            Call    Get_BVSCB           ; Get BVSCB Selecter            ;;EPOCH ;; added for J-FUNC
            .if     <nonzero ax> and    ; GetShrSeg is Complete !!!     ;;EPOCH ;; added for J-FUNC
            push    bx                                                  ;;EPOCH ;; added for J-FUNC
            mov     bx,ds               ; BX = DS                       ;;EPOCH ;; added for J-FUNC
            cmp     bx,ax               ; AX = BVSCB Selecter           ;;EPOCH ;; added for J-FUNC
            pop     bx                                                  ;;EPOCH ;; added for J-FUNC
            .if     <z> and             ; DS = BVSCB selecter !!!       ;;EPOCH ;; added for J-FUNC
            .if     <<byte ptr ds:[si+3]> e 0FFh> ;Handle for CGA Attr. ;;EPOCH ;; added for J-FUNC
                ;This request is from ANSICALL.DLL.                     ;;EPOCH ;; added for J-FUNC
                lodsw                   ; Get Cell                      ;;EPOCH ;; added for J-FUNC
                mov     [bp].FillCellLow,ax                             ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
                .if     <[bp].shadowFMTID eq PSFormat> ;EPOCH ?         ;;EPOCH ;; added for J-FUNC
                    xchg    ah,al       ; AL - Attr0                    ;;EPOCH ;; added for J-FUNC
                    mov     ah,ds:[si]  ; AH - Attr1                    ;;EPOCH ;; added for J-FUNC
                    Call    Translate   ; Common AX -> EPOCH AL         ;;EPOCH ;; added for J-FUNC
                    mov     byte ptr [bp+1].FillCellLow,al              ;;EPOCH ;; added for J-FUNC
                    mov     [bp].FillCellHigh,0                         ;;EPOCH ;; added for J-FUNC
                .else                                                   ;;EPOCH ;; added for J-FUNC
                    lodsw                                               ;;EPOCH ;; added for J-FUNC
                    xor     ah,ah                                       ;;EPOCH ;; added for J-FUNC
                    mov     [bp].FillCellHigh,ax                        ;;EPOCH ;; added for J-FUNC
                .endif                                                  ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
            .else                       ; Not From ANSICALL             ;;EPOCH ;; added for J-FUNC
                lds     si,[bp].ParmBuf ; (ds:si) -> parameter buffer   ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
                test    [si].Flags,CGAAttr      ; the jump is 5 lines down

                lds     si,[si].AppCellAddr
                lodsw
                mov     [bp].FillCellLow,ax
                mov     [bp].FillCellHigh,0

IFNDEF EPOCH                                                            ;;EPOCH ;; added for J-FUNC
                .if     <z> and
                .if     <[bp].cellsize e WorldCellSize>
ELSE                                                                    ;;EPOCH ;; added for J-FUNC
                .if     <z>                                             ;;EPOCH ;; added for J-FUNC
                    .if     <[bp].cellsize e WorldCellSize>             ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
                        lodsw
IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
                        xor     ah,ah                                   ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
                        mov     [bp].FillCellHigh,ax
                    .endif
IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
                .else                   ; From WrtTTY                   ;;EPOCH ;; added for J-FUNC
                    .if     <[bp].shadowFMTID eq PSFormat> ;EPOCH ?     ;;EPOCH ;; added for J-FUNC
                        xchg    ah,al   ; AL - Attr0                    ;;EPOCH ;; added for J-FUNC
                        mov     ah, ds:[si] ; AH - Attr1                ;;EPOCH ;; added for J-FUNC
                        Call    Translate   ; Common AX -> EPOCH AL     ;;EPOCH ;; added for J-FUNC
                        mov     byte ptr [bp+1].FillCellLow,al          ;;EPOCH ;; added for J-FUNC
                        mov     [bp].FillCellHigh,0                     ;;EPOCH ;; added for J-FUNC
                    .else                                               ;;EPOCH ;; added for J-FUNC
                        lodsw                                           ;;EPOCH ;; added for J-FUNC
                        xor     ah, ah                                  ;;EPOCH ;; added for J-FUNC
                        mov     [bp].FillCellHigh,ax                    ;;EPOCH ;; added for J-FUNC
                    .endif                                              ;;EPOCH ;; added for J-FUNC
                .endif                                                  ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
                lds     si,[bp].ParmBuf         ; (ds:si) -> parameter buffer
IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
            .endif                                                      ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
        .endif

        ret

CalcFillValues      ENDP                                        ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = MoveUpLeft
;*
;* DESCRIPTION   =
;*
;*      Move a rectangle for ScrollUp or ScrollLeft
;*
;*      MoveUpLeft copys a rectangle in the LVB and/or PVB from beginning
;*      to end, one line at a time.
;*
;* INPUT     =  BX = LVB selector or 0 if no LVB write indicated
;*              SS:BP - local data storage area
;*
;*              [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;*              [bp].RowsToMove     = number of rows to move
;*
;*              [bp].PVBMoveCount   = # of bytes per PVB row to move
;*              [bp].PVBMoveSkip    = # of bytes to skip to get to the next row
;*              [bp].PVBMoveSrcOff  = offset to start of PVB source buffer
;*              [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;*              [bp].LVBMoveCount   = # of bytes per PVB row to move
;*              [bp].LVBMoveSkip    = # of bytes to skip to get to the next row
;*              [bp].LVBMoveSrcOff  = offset to start of PVB source buffer
;*              [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* OUTPUT    =
;*              The rectangle in the LVB or PVB is moved as appropriate
;*
;* CALLS   none
;*
;* USES    AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;*        cursrcoff  = FirstMoveSrcOff
;*        curdestoff  = FirstMoveDestOff
;*        while (RowsToMove--)
;*            curcount = MoveCount
;*            while (curcount--)
;*                *curdestoff++ = *cursrcoff++
;*            cursrcoff += NextLineMove
;*            curdestoff += NextLineMove
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                PUBLIC  MoveUpLeft                              ;@P1 begin
MoveUpLeft      PROC

        cld                                 ; increment si, di
        .if     <nonzero bx>
            mov     ds,bx
            mov     es,bx
            mov     bx,[bp].RowsToMove
            mov     si,[bp].LVBMoveSrcOff
            mov     di,[bp].LVBMoveDestOff
            mov     dx,[bp].LVBMoveCount
            shr     dx,1                    ; convert bytes to words

mulf10:     mov     cx,dx                   ; (cx) = bytes to move this row
IFDEF D1348 ;check if DBCS && common lvb.
IFNDEF MSKK                                                             ;;MSKK  ;; added for J-FUNC
            .if    <bit <[bp].flgDBCS> and anyDBCS> and
            .if    <[bp].j_funcindx eq WorldFmtIndx>
ELSE                                                                    ;;MSKK  ;; added for J-FUNC
            .if    <bit <[bp].flgDBCS> and anyDBCS>                     ;;MSKK  ;; added for J-FUNC
ENDIF ; MSKK                                                            ;;MSKK  ;; added for J-FUNC
                push    bx                  ; save row count
                call    MoveUpLeftWrld
                pop     bx                  ; restore row count
            .else
                rep     movsw               ; move the line
            .endif
ELSE  ;D1348
            rep     movsw                   ; move the line
ENDIF ;D1348
            add     si,[bp].LVBMoveSkip     ; advance to the next source line
            add     di,[bp].LVBMoveSkip     ; advance to the next dest line
            dec     bx                      ; Are there more rows to move?
            jnz     mulf10                  ;   Yes, go do the next one

        .endif
        mov     bx,[bp].PVB_SEL
        .if     <nonzero bx>
            mov     ds,bx
            mov     es,bx
            mov     bx,[bp].RowsToMove
            mov     si,[bp].PVBMoveSrcOff
            mov     di,[bp].PVBMoveDestOff
            mov     dx,[bp].PVBMoveCount
            shr     dx,1                    ; convert bytes to words

mulf20:     mov     cx,dx                   ; (cx) = bytes to move this row
            REP_MOVSW                       ; Use this macro so CGA can share
                                            ; the same set of sources
            add     si,[bp].PVBMoveSkip     ; advance to the next source line
            add     di,[bp].PVBMoveSkip     ; advance to the next dest line
            dec     bx                      ; Are there more rows to move?
            jnz     mulf20                  ;   Yes, go do the next one

        .endif

        ret

MoveUpLeft      ENDP                                            ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = MoveDownRight
;*
;* DESCRIPTION   =
;*
;*      Move a rectangle for ScrollDown or ScrollRight
;*
;*      MoveDownRight copys a rectangle in the LVB and/or PVB from beginning
;*      to end, one line at a time.
;*
;* INPUT     =  BX = LVB selector or 0 if no LVB write indicated
;*              SS:BP - local data storage area
;*
;*              [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;*              [bp].RowsToMove     = number of rows to move
;*
;*              [bp].PVBMoveCount   = # of bytes per PVB row to move
;*              [bp].PVBMoveSkip    = # of bytes to skip to get to the next row
;*              [bp].PVBMoveSrcOff  = offset to start of PVB source buffer
;*              [bp].PVBMoveDestOff = offset to start of PVB destination buffer
;*
;*              [bp].LVBMoveCount   = # of bytes per PVB row to move
;*              [bp].LVBMoveSkip    = # of bytes to skip to get to the next row
;*              [bp].LVBMoveSrcOff  = offset to start of PVB source buffer
;*              [bp].LVBMoveDestOff = offset to start of PVB destination buffer
;*
;* OUTPUT    =
;*              The rectangle in the LVB or PVB is moved as appropriate
;*
;* CALLS   none
;*
;* USES    AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;* NOTES
;*
;* PSEUDOCODE
;*
;*        cursrcoff  = LastMoveSrcOff
;*        curdestoff  = LastMoveDestOff
;*        while (RowsToMove--)
;*            curcount = MoveCount
;*            while (curcount--)
;*                *curdestoff-- = *cursrcoff--
;*            cursrcoff -= NextLineMove
;*            curdestoff -= NextLineMove
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                PUBLIC  MoveDownRight                           ;@P1 begin
MoveDownRight   PROC

        std                                 ; decrement si, di
        .if     <nonzero bx>
            mov     ds,bx
            mov     es,bx
            mov     bx,[bp].RowsToMove
            mov     si,[bp].LVBMoveSrcOff
            mov     di,[bp].LVBMoveDestOff
            mov     dx,[bp].LVBMoveCount
            shr     dx,1                    ; convert bytes to words

mdrt10:     mov     cx,dx                   ; (cx) = bytes to move this row
IFDEF D1348 ;check if DBCS && common lvb.
IFNDEF MSKK                                                             ;;MSKK  ;; added for J-FUNC
            .if    <bit <[bp].flgDBCS> and anyDBCS> and
            .if    <[bp].j_funcindx eq WorldFmtIndx>
ELSE                                                                    ;;MSKK  ;; added for J-FUNC
            .if    <bit <[bp].flgDBCS> and anyDBCS>                     ;;MSKK  ;; added for J-FUNC
ENDIF ; MSKK                                                            ;;MSKK  ;; added for J-FUNC
                push    bx                  ; save row count
                call    MoveDownRightWrld
                pop     bx                  ; restore row count
            .else
                rep     movsw               ; move the line
            .endif
ELSE  ;D1348
            rep     movsw                   ; move the line
ENDIF ;D1348
            sub     si,[bp].LVBMoveSkip     ; advance to the next source line
            sub     di,[bp].LVBMoveSkip     ; advance to the next dest line
            dec     bx                      ; Are there more rows to move?
            jnz     mdrt10                  ;   Yes, go do the next one

        .endif
        mov     bx,[bp].PVB_SEL
        .if     <nonzero bx>
            mov     ds,bx
            mov     es,bx
            mov     bx,[bp].RowsToMove
            mov     si,[bp].PVBMoveSrcOff
            mov     di,[bp].PVBMoveDestOff
            mov     dx,[bp].PVBMoveCount
            shr     dx,1                    ; convert bytes to words

mdrt20:     mov     cx,dx                   ; (cx) = bytes to move this row
            REP_MOVSW                       ; Use this macro so CGA can share
                                            ; the same set of sources
            sub     si,[bp].PVBMoveSkip     ; advance to the next source line
            sub     di,[bp].PVBMoveSkip     ; advance to the next dest line
            dec     bx                      ; Are there more rows to move?
            jnz     mdrt20                  ;   Yes, go do the next one

        .endif

        ret

MoveDownRight   ENDP                                            ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = FillRectWithCell
;*
;* DESCRIPTION   =
;*
;*      Fill a rectangle for with the default cell
;*
;*      FillRectWithCell fills the specified rectangle in the LVB and/or
;*      PVB with the given cell, beginning to end, one line at a time.
;*
;* INPUT     =  BX = LVB selector or 0 if no LVB write indicated
;*              SS:BP - local data storage area
;*
;*              [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;*              [bp].RowsToFill   = rows to be filled with the default cell
;*
;*              [bp].PVBFillCount = # of bytes per fill line in PVB
;*              [bp].PVBFillSkip  = # of bytes to skip to reach next PVB line
;*              [bp].PVBFillOff   = offset of beginning of PVB fill rectangle
;*
;*              [bp].LVBFillCount = # of bytes per fill line in LVB
;*              [bp].LVBFillSkip  = # of bytes to skip to reach next LVB line
;*              [bp].LVBFillOff   = offset of beginning of LVB fill rectangle
;*
;*              [bp].FillCellLow  = first word of default fill cell
;*              [bp].FillCellHigh = second word of default fill cell
;*
;* OUTPUT     =
;*              The rectangle in the LVB or PVB is moved as appropriate
;*
;*
;*      CALLS   none
;*
;*      USES    AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;*      NOTES
;*
;*      PSEUDOCODE
;*
;*           curdestoff = FirstFillDestOff
;*           while (RowsToFill)
;*           for (curline = FirstFillLine; curline <= LastFillLine; curline++)
;*               curcount = FillCount
;*               while (curcount--)
;*                   *curdestoff = fillcell
;*               curdestoff += NextLineFill
;*
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                PUBLIC  FillRectWithCell                        ;@P1 begin
FillRectWithCell    PROC

        cld                                 ; increment si, di
        mov     ax,[bp].FillCellLow
        .if     <nonzero bx>
            mov     ds,bx
            mov     es,bx
            mov     bx,[bp].RowsToFill
            mov     di,[bp].LVBFillOff
            mov     dx,[bp].LVBFillCount
            .if     <[bp].cellsize e WorldCellSize>
                mov     si,[bp].FillCellHigh
                shr     dx,2                ; convert bytes to cells

frwc10:         mov     cx,dx               ; (cx) = bytes to move this row
;; IFDEF EPOCH  ;26Sep91 +                                                      ;;KY02D ;;EPOCH
;;              and     ah,not (epochDBCSLead+epochDBCSTrail)                   ;;KY02D ;;EPOCH
;; ENDIF        ;26Sep91 -                                                      ;;KY02D ;;EPOCH
                .repeat                     ; fill the line with the cell
                    stosw
                    xchg    ax,si
                    stosw
                    xchg    ax,si
                .loop
                add     di,[bp].LVBFillSkip ; advance to the next source line
                dec     bx                  ; Are there more rows to move?
                jnz     frwc10              ;   Yes, go do the next one
            .else
                shr     dx,1                ; convert bytes to cells

frwc20:         mov     cx,dx               ; (cx) = bytes to move this row
                rep     stosw               ; fill the line with the cell
                add     di,[bp].LVBFillSkip ; advance to the next source line
                dec     bx                  ; Are there more rows to move?
                jnz     frwc20              ;   Yes, go do the next one
IFDEF MSKK                                                              ;;MSKK  ;; added for J-FUNC
                mov     bx,[bp].RowsToFill                              ;;MSKK  ;; added for J-FUNC
                mov     di,[bp].LVBFillOff                              ;;MSKK  ;; added for J-FUNC
                push    es                                              ;;MSKK  ;; added for J-FUNC
                mov     es,[bp].j_dbcslvbsel; use DBCS flag LVB         ;;MSKK  ;; added for J-FUNC
                push    ax                                              ;;MSKK  ;; added for J-FUNC
                xor     ax,ax                                           ;;MSKK  ;; added for J-FUNC
                                                                        ;;MSKK  ;; added for J-FUNC
@@:             mov     cx,dx               ; (cx) = bytes to move this row     ;; added for J-FUNC
                rep     stosw               ; fill the line with the cell       ;; added for J-FUNC
                add     di,[bp].LVBFillSkip ; advance to the next source line   ;; added for J-FUNC
                dec     bx                  ; Are there more rows to move?      ;; added for J-FUNC
                jnz     @B                  ; Yes, go do the next one   ;;MSKK  ;; added for J-FUNC
                pop     ax                                              ;;MSKK  ;; added for J-FUNC
                pop     es                                              ;;MSKK  ;; added for J-FUNC
ENDIF ; MSKK                                                            ;;MSKK  ;; added for J-FUNC
            .endif
        .endif
        mov     bx,[bp].PVB_SEL
        .if     <nonzero bx>
            mov     ds,bx
            mov     es,bx
            mov     bx,[bp].RowsToFill
            mov     di,[bp].PVBFillOff
            mov     dx,[bp].PVBFillCount
            shr     dx,1                    ; convert bytes to words

frwc30:     mov     cx,dx                   ; (cx) = bytes to move this row
            REP_STOSW                       ; Use this macro so CGA can share
                                            ; the same set of sources
            add     di,[bp].PVBFillSkip     ; advance to the next dest line
            dec     bx                      ; Are there more rows to move?
            jnz     frwc30                  ;   Yes, go do the next one
        .endif

        ret

FillRectWithCell    ENDP                                        ;@P1 end


;/***************************************************************************
;*
;* FUNCTION NAME = MoveLVBRectToPVB
;*
;*      Copy a rectangle from LVB to PVB
;*
;*      MoveLVBRectToPVB copys the FillRect in the LVB to the FillRect in
;*      the PVB.  Conversions for different cell sizes are done at this time.
;*
;* INPUT    =   BX = LVB selector or 0 if no LVB write indicated
;*              SS:BP - local data storage area
;*
;*              [bp].PVB_Sel = PVB selector if PVB scroll is indicated else 0
;*
;*              [bp].RowsToFill   = rows to be filled with the default cell
;*
;*              [bp].PVBFillCount = # of bytes per fill line in PVB
;*              [bp].PVBFillSkip  = # of bytes to skip to reach next PVB line
;*              [bp].PVBFillOff   = offset of beginning of PVB fill rectangle
;*
;*              [bp].LVBFillCount = # of bytes per fill line in LVB
;*              [bp].LVBFillSkip  = # of bytes to skip to reach next LVB line
;*              [bp].LVBFillOff   = offset of beginning of LVB fill rectangle
;*
;*              [bp].FillCellLow  = first word of default fill cell
;*              [bp].FillCellHigh = second word of default fill cell
;*
;* OUTPUT    =
;*              The rectangle in the LVB or PVB is moved as appropriate
;*
;*
;*      CALLS   none
;*
;*      USES    AX,BX,CX,DX,SI,DI,DS,ES,FLAGS
;*
;*      NOTES
;*
;*      PSEUDOCODE
;*
;*          cursrcoff = LVBFillOff
;*          curdestoff = PVBFillOff
;*          while (RowsToFill)
;*              curcount = FillCount
;*              while (curcount--)
;*                  *curdestoff = *cursrcoff
;*              curdestoff += PVBFillSkip
;*              cursrcoff += LVBFillSkip
;*
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/

                PUBLIC  MoveLVBRectToPVB                        ;@P1 begin
MoveLVBRectToPVB    PROC

        cld                                 ; increment si, di
        .if     <nonzero bx> and
        mov     ds,bx                       ; (ds) = LVB segment
        mov     bx,[bp].PVB_Sel
        .if     <nonzero bx>
            mov     es,bx                   ; (es) = PVB segment
            mov     si,[bp].LVBFillOff      ; (si) = LVB rectangle offset
            mov     di,[bp].PVBFillOff      ; (di) = PVB rectangle offset
            mov     bx,[bp].RowsToFill
            mov     dx,[bp].LVBFillCount
            .if     <[bp].cellsize e WorldCellSize>
                shr     dx,2                ; convert bytes to cells

lrtp10:         mov     cx,dx               ; (cx) = bytes to move this row
                REP_MOVSW_ADDSI2_LOOP       ; Use this macro so CGA can share
                                            ; the same set of sources
                add     si,[bp].LVBFillSkip ; advance to the next LVB line
                add     di,[bp].PVBFillSkip ; advance to the next PVB line
                dec     bx                  ; Are there more rows to move?
                jnz     lrtp10              ;   Yes, go do the next one
            .else
                shr     dx,1                ; convert bytes to cells

lrtp20:         mov     cx,dx               ; (cx) = bytes to move this row
                REP_MOVSW                   ; Use this macro so CGA can share
                                            ; the same set of sources
                add     si,[bp].LVBFillSkip ; advance to the next LVB line
                add     di,[bp].PVBFillSkip ; advance to the next PVB line
                dec     bx                  ; Are there more rows to move?
                jnz     lrtp20              ;   Yes, go do the next one
            .endif
        .endif

        ret

MoveLVBRectToPVB    ENDP                                        ;@P1 end

IFDEF EPOCH                                                             ;;EPOCH ;; added for J-FUNC
;/********************************************************************* ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*  Attribute Translation.                                              ;;EPOCH ;; added for J-FUNC
;*  This procedure is used only for Epoch attribute translation.        ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*    Input  : AX - Attr0 and 1 of Common Format                        ;;EPOCH ;; added for J-FUNC
;*             These are set by WrtTTY of ANSI.                         ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*      AL - 7 : BG Hint    AH - 7 : Underline                          ;;EPOCH ;; added for J-FUNC
;*           6 : BG Red          6 : Reverse                            ;;EPOCH ;; added for J-FUNC
;*           5 : BG Green        5 : Blink                              ;;EPOCH ;; added for J-FUNC
;*           4 : BG Blue         4 :                FG Red              ;;EPOCH ;; added for J-FUNC
;*           3 : FG Hint         3 : V-Grid                             ;;EPOCH ;; added for J-FUNC
;*           2 : FG Red          2 : H-Grid                             ;;EPOCH ;; added for J-FUNC
;*           1 : FG Green        1 :                FG Green            ;;EPOCH ;; added for J-FUNC
;*           0 : FG Blue         0 :                FG Blue             ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*      Note:                                                           ;;EPOCH ;; added for J-FUNC
;*          Bit 0,1, and 4 of AH are embezzled by ANSI as RGB.          ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;*    Output : AL - Epoch Attr                                          ;;EPOCH ;; added for J-FUNC
;*                                                                      ;;EPOCH ;; added for J-FUNC
;**********************************************************************/;;EPOCH ;; added for J-FUNC
Translate proc  near                                                    ;;EPOCH ;; added for J-FUNC
        PUBLIC  Translate                                               ;;EPOCH ;; added for J-FUNC
        push    bx                                                      ;;EPOCH ;; added for J-FUNC
        push    ds                                                      ;;EPOCH ;; added for J-FUNC
        push    _data                                                   ;;EPOCH ;; added for J-FUNC
        pop     ds                                                      ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        .if     <[bp].shadowColor eq 4>     ; Epoch Color               ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
            .if     <bit ah and 40h>        ; Reverse ?                 ;;EPOCH ;; added for J-FUNC
                .if     <bit al nand 07h>   ; FG Color Off              ;;EPOCH ;; added for J-FUNC
                    mov     bl, ah                                      ;;EPOCH ;; added for J-FUNC
                    mov     bh, ah                                      ;;EPOCH ;; added for J-FUNC
                    shr     bh, 2           ; Get Red Bit               ;;EPOCH ;; added for J-FUNC
                    and     bx, 0403h       ; Get Red, Green & Blue     ;;EPOCH ;; added for J-FUNC
                    or      bl, bh                                      ;;EPOCH ;; added for J-FUNC
                    mov     al, bl          ; Change Attr               ;;EPOCH ;; added for J-FUNC
                .endif                                                  ;;EPOCH ;; added for J-FUNC
                mov     bx, offset cga2epoch                            ;;EPOCH ;; added for J-FUNC
                xlat                        ; Get Color                 ;;EPOCH ;; added for J-FUNC
                or      al, 04h             ; Force Reverse             ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
            .else                           ; Not Reverse               ;;EPOCH ;; added for J-FUNC
                and     al, 07h             ; Only ForeGround Attr      ;;EPOCH ;; added for J-FUNC
                mov     bx, offset cga2epoch                            ;;EPOCH ;; added for J-FUNC
                xlat                        ; Get Color                 ;;EPOCH ;; added for J-FUNC
            .endif                                                      ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        .else                               ; Epoch Mono                ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
            .if     <bit al nand 77h> or    ; Invisible ?               ;;EPOCH ;; added for J-FUNC
            .if     <bit ah and 40h> and    ; Reverse ?                 ;;EPOCH ;; added for J-FUNC
            .if     <bit ah nand 13h>       ; FG Color Off              ;;EPOCH ;; added for J-FUNC
                mov     al, 0cch                                        ;;EPOCH ;; added for J-FUNC
            .else                                                       ;;EPOCH ;; added for J-FUNC
                and     al, 08h             ; Only Mask For Intensity   ;;EPOCH ;; added for J-FUNC
                .if     <bit ah and 20h>    ; Blink                     ;;EPOCH ;; added for J-FUNC
                    or      al, 80h         ; Set                       ;;EPOCH ;; added for J-FUNC
                .endif                                                  ;;EPOCH ;; added for J-FUNC
                .if     <bit ah and 80h>    ; UnderScore                ;;EPOCH ;; added for J-FUNC
                    or      al, 40h         ; Set                       ;;EPOCH ;; added for J-FUNC
                .endif                                                  ;;EPOCH ;; added for J-FUNC
                .if     <bit ah and 40h>    ; Reverse                   ;;EPOCH ;; added for J-FUNC
                    or      al, 04h         ; Set                       ;;EPOCH ;; added for J-FUNC
                .endif                                                  ;;EPOCH ;; added for J-FUNC
            .endif                                                      ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        .endif                                                          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        .if     <bit ah and 08h>            ; V-Grid                    ;;EPOCH ;; added for J-FUNC
            or      al, 10h                 ; Set                       ;;EPOCH ;; added for J-FUNC
        .endif                                                          ;;EPOCH ;; added for J-FUNC
        .if     <bit ah and 04h>            ; H-Grid                    ;;EPOCH ;; added for J-FUNC
            or      al, 20h                 ; Set                       ;;EPOCH ;; added for J-FUNC
        .endif                                                          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        pop     ds                                                      ;;EPOCH ;; added for J-FUNC
        pop     bx                                                      ;;EPOCH ;; added for J-FUNC
        ret                                                             ;;EPOCH ;; added for J-FUNC
Translate endp                                                          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
Get_BVSCB proc  near                                                    ;;EPOCH ;; added for J-FUNC
        public  Get_BVSCB                                               ;;EPOCH ;; added for J-FUNC
;***********************************************************************;;EPOCH ;; added for J-FUNC
;* Output : AX - BVSCB Selector                                         ;;EPOCH ;; added for J-FUNC
;*               0 means Error.                                         ;;EPOCH ;; added for J-FUNC
;***********************************************************************;;EPOCH ;; added for J-FUNC
        push    bx                                                      ;;EPOCH ;; added for J-FUNC
        push    ds                                                      ;;EPOCH ;; added for J-FUNC
        push    si                                                      ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        lds     si, [bp].EnvBufParm     ; ES:DI -> environment buffer   ;;EPOCH ;; added for J-FUNC
        mov     ax, ds:[si].env_sessionNum ; Get Session Number         ;;EPOCH ;; added for J-FUNC
        push    _DATA                   ; Global Segment                ;;EPOCH ;; added for J-FUNC
        pop     ds                                                      ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        mov     si,OFFSET BvscbSel      ; (CX) = offset of selector save word   ;; added for J-FUNC
        shl     ax, 1                   ; To Word                       ;;EPOCH ;; added for J-FUNC
        add     si, ax                  ; Add Session Number            ;;EPOCH ;; added for J-FUNC
        .if     <<word ptr ds:[si]> e 0> ; IF  bvscbSel in this session > 0     ;; added for J-FUNC
            shr     ax, 1               ; Resume - Session Number       ;;EPOCH ;; added for J-FUNC
            mov     bx,offset bvsSegLabel ; (BX) = offset of selector label     ;; added for J-FUNC
            call    BinToHx             ; Convert binary in AX into Hex ASCII   ;; added for J-FUNC
            mov     word ptr ds:[bx+LNOFF],AX ; move 2 chars to segment label   ;; added for J-FUNC
            push    ds                  ; push selector (DS) for label string   ;; added for J-FUNC
            push    bx                  ; push offset to segment label string   ;; added for J-FUNC
            push    ds                  ; push selector (DS) for selector save  ;; added for J-FUNC
            push    si                  ; push offset for selector save word    ;; added for J-FUNC
            call    DOSGETSHRSEG        ; get the shared segment        ;;EPOCH ;; added for J-FUNC
            .if     < zero ax >                                         ;;EPOCH ;; added for J-FUNC
                mov     ax, ds:[si]     ; Get Returned Selector         ;;EPOCH ;; added for J-FUNC
            .else                                                       ;;EPOCH ;; added for J-FUNC
                xor     ax, ax          ; Error                         ;;EPOCH ;; added for J-FUNC
                mov     ds:[si], ax                                     ;;EPOCH ;; added for J-FUNC
            .endif                                                      ;;EPOCH ;; added for J-FUNC
        .else                                                           ;;EPOCH ;; added for J-FUNC
            mov     ax, ds:[si]         ; Get Returned Selector         ;;EPOCH ;; added for J-FUNC
        .endif                                                          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        pop     si                                                      ;;EPOCH ;; added for J-FUNC
        pop     ds                                                      ;;EPOCH ;; added for J-FUNC
        pop     bx                                                      ;;EPOCH ;; added for J-FUNC
        ret                                                             ;;EPOCH ;; added for J-FUNC
Get_BVSCB endp                                                          ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
        PUBLIC  BinToHx                                                 ;;EPOCH ;; added for J-FUNC
BinToHx PROC    NEAR                                                    ;;EPOCH ;; added for J-FUNC
;***********************************************************************;;EPOCH ;; added for J-FUNC
;*      Convert binary in AX into Hex ASCII equivalent.                 ;;EPOCH ;; added for J-FUNC
;*      DS must contained the _DATA selector.                           ;;EPOCH ;; added for J-FUNC
;***********************************************************************;;EPOCH ;; added for J-FUNC
        push    BX                                                      ;;EPOCH ;; added for J-FUNC
        mov     BX,16                   ; Convert codepage ID index to  ;;EPOCH ;; added for J-FUNC
        div     BL                      ;   Hex ASCII                   ;;EPOCH ;; added for J-FUNC
        mov     BL,AL                                                   ;;EPOCH ;; added for J-FUNC
        mov     AL,ds:[bx].HexDigit     ; High order Hex                ;;EPOCH ;; added for J-FUNC
        mov     BL,AH                                                   ;;EPOCH ;; added for J-FUNC
        mov     AH,ds:[bx].HexDigit     ; Low order Hex                 ;;EPOCH ;; added for J-FUNC
        pop     BX                                                      ;;EPOCH ;; added for J-FUNC
        ret                                                             ;;EPOCH ;; added for J-FUNC
BinToHx ENDP                                                            ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
ENDIF                                                                   ;;EPOCH ;; added for J-FUNC
                                                                        ;;EPOCH ;; added for J-FUNC
R2CSEG  ENDS
        END

