;*DDK*************************************************************************/
;
; 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.;
;*****************************************************************************/
;-------------------------------------------------------------------------
;
;   Module          = FFBLTSET
;
;   Description     = 386 code for the software blt operation set up functions
;
;   Functions       = eddf_MESSSetUpSrcDest16
;                     eddf_MESSSetUpSrcDest81
;                     eddf_MESSSetUpSrcDest41
;                     eddf_MESSSetUpSrcDest11
;                     eddf_MESSSetUpPatDest11
;                     eddf_MESSSetUpDest16
;                     eddf_MESSSetUpDest41
;                     eddf_MESSSetUpDestForPat41
;                     eddf_MESSSetUpDest11
;
;
;-------------------------------------------------------------------------

INCL_GPIBITMAPS EQU     1
include os2.inc
include eddinclt.inc

; Include the XGA assembler include files and the MESS include files

include eddhcone.inc
include eddhtype.inc
include eddhmacr.inc

include eddfcone.inc
include eddfmacr.inc
include eddftype.inc

?DF     equ     1       ; we dont want _TEXT segment defined
include cmacros.inc

include ffmacros.inc

include rmacros.inc



;-------------------------------------------------------------------------




_DATA           segment use32 dword public 'DATA'
                assume  cs:FLAT, ds:FLAT, es:FLAT

; Declare the external data elements we use
ifndef  _8514
externDP        ShadowXGARegs
else
include         8514.inc
externDP        Shadow8514Regs
endif
externDP        srcPixmap
externDP        dstPixmap
externDP        patPixmap
externDP        messSpad




_DATA           ends





;-------------------------------------------------------------------------





_TEXT           segment use32 dword public 'CODE'
                assume  cs:FLAT, ds:FLAT, es:FLAT




;-------------------------------------------------------------------------
; Macro:        SetUpMasksAndTotalBytes bpp
;
; Parameters:   ShadowXGARegs
;
; Returns:      _messSpad.startMask
;               _messSpad.startMaskInv
;               _messSpad.endMask
;               _messSpad.endMaskInv
;               _messSpad.totalBytes
;
;-------------------------------------------------------------------------

SetUpMasksAndTotalBytes macro bpp
        local notOneByteWide, getEndCoordsRToLBlt, gotEndCoords
        local gotStartAndEndMasks, loadTotalBytes

; First check that the bpp parameter is valid
CheckBpp SetUpMaskAndTotalBytes 1 or 4 bpp


        ; First we want to work out the start and end masks of the destination
        ; line.
        ; 
        ; The bits set in the masks indicate which bits in the first and
        ; last destination bytes of each line are to be included in the blt.
        ; 
        ; Left and right masks are calculated. These are then mapped to the
        ; start and end masks based on whether the blt is from left to right or
        ; right to left.
        ; 
        ;                   Leftmost    Rightmost
        ;                   Byte Mask   Byte Mask
if bpp eq 4
        ; x coord (mod 2)
        ;       0           11111111    11110000
        ;       1           00001111    11111111
endif ; bpp eq 4
if bpp eq 1
        ; x coord (mod 8)
        ;       0           11111111    10000000
        ;       1           01111111    11000000
        ;       2           00111111    11100000
        ;       3           00011111    11110000
        ;       4           00001111    11111000
        ;       5           00000111    11111100
        ;       6           00000011    11111110
        ;       7           00000001    11111111
endif ; bpp eq 1

        ; Put the destination lines leftmost x coordinate in bx
        ; and the rightmost x coordinate in ax.
        ; 
        ; The leftmost and rightmost coordinates depend upon whether the blt
        ; is going left to right or right to left.

rName bx DestLeftX
rName ax DestRightX

        ifndef  _8514
        test    ShadowXGARegs.pixel_op, BLTDIR_RIGHTTOLEFT
        else
        test    Shadow8514Regs.pixel_op, BLTDIR_RIGHTTOLEFT
        endif
        jnz     short getEndCoordsRToLBlt

        ; A Left to Right blt
        ; Start coordinate (dest_map_x) is the leftmost.
        ; Add the line length to get the rightmost coordinate.

        ifndef  _8514
        mov     bxDestLeftX, ShadowXGARegs.dest_map_x
        mov     axDestRightX, bxDestLeftX
        add     axDestRightX, ShadowXGARegs.dim1
        else
        mov     bxDestLeftX, Shadow8514Regs.dest_map_x
        mov     axDestRightX, bxDestLeftX
        add     axDestRightX, Shadow8514Regs.dim1
        endif
        jmp     short gotEndCoords

getEndCoordsRToLBlt:
        ; A Right to Left blt
        ; Start coordinate (dest_map_x) is the rightmost.
        ; Subtract the line length to get the leftmost coordinate.

        ifndef  _8514
        mov     axDestRightX, ShadowXGARegs.dest_map_x
        mov     bxDestLeftX, axDestRightX
        sub     bxDestLeftX, ShadowXGARegs.dim1
        else
        mov     axDestRightX, Shadow8514Regs.dest_map_x
        mov     bxDestLeftX, axDestRightX
        sub     bxDestLeftX, Shadow8514Regs.dim1
        endif

gotEndCoords:

        ; Use dl for the leftmost byte's mask
        ; and dh for the rightmost byte's mask
        ; 
        ; Calculation of correct masks requires them to be initially set to
        ; take all source bits from each end byte

        mov     dx, 0FFFFh

rName dl LeftMask
rName dh RightMask

        ; Now get the mask for the leftmost coordinate

        mov     cl, blPartOfDestLeftX
if bpp eq 4
        and     cl, 01h                 ; x coord % 2
        shl     cl, 2                   ; *4 to give 0 or 4
endif ; bpp eq 4
if bpp eq 1
        and     cx, 07h                 ; x coord % 8
endif ; bpp eq 1
        shr     dlLeftMask, cl          ; shift mask from 0 to 7 bits


        ; Now get the mask for the rightmost coordinate

        mov     cl, alPartOfDestRightX
if bpp eq 4
        and     cl, 01h                 ; x coord % 2
        inc     cl                      ; + 1
        shl     cl, 2                   ; *4 to give 4 or 8
endif ; bpp eq 4
if bpp eq 1
        and     cx, 07h
        inc     cl                      ; (x coord % 8) + 1
endif ; bpp eq 1
        shr     dhRightMask, cl         ; shift mask from 1 to 8 bits
        not     dhRightMask


        ; We have the leftmost and rightmost bytes masks
        ; Now map these to the start and end bytes
rFree dl LeftMask
rFree dh RightMask


        ; We are going to use dl for the start mask and dh for the end mask.
        ; Currently dl contains the leftmost mask and dh the rightmost mask.
        ; This is as required for a left to right blt.
        ; For a right to left blt swop dl and dh.

        ifndef  _8514
        test    ShadowXGARegs.pixel_op, BLTDIR_RIGHTTOLEFT
        else
        test    Shadow8514Regs.pixel_op, BLTDIR_RIGHTTOLEFT
        endif
        jz      short gotStartAndEndMasks
        xchg    dl, dh

gotStartAndEndMasks:

rName dl StartMask
rName dh EndMask


        ; Now calculate the total number of bytes to be blted per destination
        ; line.
        ; 
        ; Convert the x coordinates to bytes.
rFree bx DestLeftX
rFree ax DestRightX

if bpp eq 4
        shr     bx, 1
        shr     ax, 1
else  ; if bpp eq 4
        shr     bx, 3
        shr     ax, 3
endif ; if bpp eq 4 else


        ; ax is the address of the byte containing the rightmost pel
        ; bx is the address of the byte containing the leftmost pel
        ; Get the length of the destination line in bytes (minus one) in ax

        sub     ax, bx

        ; For a destination line length of 1 byte (ax now equals 0) the
        ; start and end masks must be combined

        jnz     short notOneByteWide

        ; Blt is only one byte wide so we must combine the start and end masks.

        and     dlStartMask, dhEndMask
        mov     _messSpad.startMask, dlStartMask
        mov     _messSpad.endMask, dlStartMask
        not     dlStartMask
        mov     _messSpad.startMaskInv, dlStartMask
        mov     _messSpad.endMaskInv, dlStartMask
        jmp     short loadTotalBytes


notOneByteWide:

        ; Load the scratchpad with the start and end masks

        mov     _messSpad.startMask, dlStartMask
        not     dlStartMask
        mov     _messSpad.startMaskInv, dlStartMask

        mov     _messSpad.endMask, dhEndMask
        not     dhEndMask
        mov     _messSpad.endMaskInv, dhEndMask


loadTotalBytes:

rFree dl StartMask
rFree dh EndMask

        ; ax contains the length of the destination line in bytes minus one
        ; Set up the .totalBytes field for the actual number of bytes per
        ; destination line

        cwde
        inc     eax
        mov     _messSpad.totalBytes, eax


        ; The _messSpad start and end masks and totalBytes fields are now
        ; set up.
endm


;-------------------------------------------------------------------------
; Macro:        SetUpSrcWidth bpp
;
; Parameters:   srcPixmap structure
;
; Returns:      _messSpad.srcWidthInBytes, eax
;
;-------------------------------------------------------------------------

SetUpSrcWidth macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcWidth 1 4 8 or 16 bpp

        movzx   eax, srcPixmap.xLen
if bpp eq 4
        shr     eax, 1
endif
if bpp eq 1
        shr     eax, 3
endif
        inc     eax
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcWidthInBytes, eax
endm


;-------------------------------------------------------------------------
; Macro:        SetUpPatWidthInBytes bpp
;
; Parameters:   patPixmap structure
;
; Returns:      _messSpad.srcWidthInBytes
;
; Notes: Here we return the pattern width in srcWidthInBytes. We know that
; we never use the patPixmap at the same time as the srcPixmap so it is
; ok to overlap these.
;
;-------------------------------------------------------------------------

SetUpPatWidth macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpPatWidth 1 bpp

        movzx   eax, patPixmap.xLen
        shr     eax, 3
        inc     eax
        mov     _messSpad.srcWidthInBytes, eax
endm


;-------------------------------------------------------------------------
; Macro:        SetUpDstWidth bpp
;
; Parameters:   dstPxmap structure
;
; Returns:      _messSpad.dstWidthInBytes
;
;-------------------------------------------------------------------------

SetUpDstWidth macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstWidth 1 4 8 16 or 24 bpp

        movzx   eax, dstPixmap.xLen
if bpp eq 4
        shr     eax, 1
endif
if bpp eq 1
        shr     eax, 3
endif
        inc     eax
if bpp eq 16
        shl     eax, 1
endif

if bpp eq 24
        mov     edx,eax
        shl     eax, 1
        add     eax,edx
endif
        mov     _messSpad.dstWidthInBytes, eax
endm


;-------------------------------------------------------------------------
; Macros:       SetUpSrcLineIncBTRL bpp
;               SetUpDstLineIncBTRL bpp
;               SetUpSrcLineIncTBRL bpp
;               SetUpDstLineIncTBRL bpp
;               SetUpSrcLineIncBTLR bpp
;               SetUpDstLineIncBTLR bpp
;               SetUpSrcLineIncTBLR bpp
;               SetUpDstLineIncTBLR bpp
;
; Parameters:   ShadowXGARegs, srcPixmap and dstPixmap structures
;               _messSpad.srcWidthInBytes
;               _messSpad.totalBytes
;
; Returns:      _messSpad.srcLineInc
;               _messSpad.dstLineInc
;
; Notes: These set of macros calculate the src and dst line to line increments.
; ie. the adjustedment to be made to the src/dst address after one line of the
; blt has been completed to get to the start of the next line of the blt.
;
; The last four letters of the macro name refer to the direction in which the
; blt is going to preceed in (eg bottom to top, left to right.)
;
; In the 4bpp and 1bpp case this calculation uses the totalBytes and
; srcWidthInBytes or dstWidthInBytes _messSpad values. This means that the
; SetUpSrcWidth, SetUpDstWidth, and SetUpMaskAndTotalBytes macros should be
; called before this macro is called.
;
;-------------------------------------------------------------------------

ifndef  _8514

SetUpSrcLineIncBTRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncBTRL 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width - blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, ShadowXGARegs.dim1
        sub     ax, srcPixmap.xLen
        cwde
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        sub     eax, _messSpad.srcWidthInBytes
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncBTRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncBTRL 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width - blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, ShadowXGARegs.dim1
        sub     ax, dstPixmap.xLen
        cwde
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        sub     eax, _messSpad.dstWidthInBytes
        mov     _messSpad.dstLineInc, eax
endif
endm


SetUpSrcLineIncTBRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncTBRL 1 4 8 or 16 bpp

        ; This blt runs from the top to the bottom and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width + blt width.
if (bpp eq 8) or (bpp eq 16)
        mov     ax, srcPixmap.xLen
        add     ax, ShadowXGARegs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.srcWidthInBytes
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncTBRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncTBRL 1 4 8 or 16 bpp

        ; This blt runs from the top to the bottom and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width + blt width.
if (bpp eq 8) or (bpp eq 16)
        mov     ax, dstPixmap.xLen
        add     ax, ShadowXGARegs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.dstWidthInBytes
        mov     _messSpad.dstLineInc, eax
endif
endm


SetUpSrcLineIncBTLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncBTLR 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width + blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, srcPixmap.xLen
        add     ax, ShadowXGARegs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
        neg     eax
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.srcWidthInBytes
        neg     eax
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncBTLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncBTLR 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width + blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, dstPixmap.xLen
        add     ax, ShadowXGARegs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
        neg     eax
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.dstWidthInBytes
        neg     eax
        mov     _messSpad.dstLineInc, eax
endif
endm


SetUpSrcLineIncTBLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncTBLR 1 4 8 or 16 bpp

        ; This blt runs from the top to the bottom and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width - blt width.
if (bpp eq 8) or (bpp eq 16)
        mov     ax, srcPixmap.xLen
        sub     ax, ShadowXGARegs.dim1
        cwde
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.srcWidthInBytes
        sub     eax, _messSpad.totalBytes
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncTBLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncTBLR 1 4 8 or 16 bpp

        ; This blt runs from the top to the bottom and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width - blt width.
if (bpp eq 8) or (bpp eq 16)
        mov     ax, dstPixmap.xLen
        sub     ax, ShadowXGARegs.dim1
        cwde
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.dstWidthInBytes
        sub     eax, _messSpad.totalBytes
        mov     _messSpad.dstLineInc, eax
endif
endm

else    ;_8514

SetUpSrcLineIncBTRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncBTRL 1 4 8 16 or 24 bpp

        ; This blt runs from the bottom to the top and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width - blt width).
if (bpp eq 8) or (bpp eq 16) or (bpp eq 24)
        mov     ax, Shadow8514Regs.dim1
        sub     ax, srcPixmap.xLen
        cwde
if bpp eq 16
        shl     eax, 1
endif

if bpp eq 24
        mov     edx,eax
        shl     eax, 1
        add     eax,edx
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        sub     eax, _messSpad.srcWidthInBytes
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncBTRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncBTRL 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width - blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, Shadow8514Regs.dim1
        sub     ax, dstPixmap.xLen
        cwde
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        sub     eax, _messSpad.dstWidthInBytes
        mov     _messSpad.dstLineInc, eax
endif
endm


SetUpSrcLineIncTBRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncTBRL 1 4 8 or 16 bpp

        ; This blt runs from the top to the bottom and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width + blt width.
if (bpp eq 8) or (bpp eq 16)
        mov     ax, srcPixmap.xLen
        add     ax, Shadow8514Regs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.srcWidthInBytes
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncTBRL macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncTBRL 1 4 8 or 16 bpp

        ; This blt runs from the top to the bottom and right to left.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width + blt width.
if (bpp eq 8) or (bpp eq 16)
        mov     ax, dstPixmap.xLen
        add     ax, Shadow8514Regs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.dstWidthInBytes
        mov     _messSpad.dstLineInc, eax
endif
endm


SetUpSrcLineIncBTLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncBTLR 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width + blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, srcPixmap.xLen
        add     ax, Shadow8514Regs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
        neg     eax
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.srcWidthInBytes
        neg     eax
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncBTLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncBTLR 1 4 8 or 16 bpp

        ; This blt runs from the bottom to the top and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be -(pixmap width + blt width).
if (bpp eq 8) or (bpp eq 16)
        mov     ax, dstPixmap.xLen
        add     ax, Shadow8514Regs.dim1
        cwde
        add     eax, 2                  ; compensate for -1 in xLen & dim1
        neg     eax
if bpp eq 16
        shl     eax, 1
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.totalBytes
        add     eax, _messSpad.dstWidthInBytes
        neg     eax
        mov     _messSpad.dstLineInc, eax
endif
endm


SetUpSrcLineIncTBLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpSrcLineIncTBLR 1 4 8 16 or 24 bpp

        ; This blt runs from the top to the bottom and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width - blt width.
if (bpp eq 8) or (bpp eq 16) or (bpp eq 24)
        mov     ax, srcPixmap.xLen
        sub     ax, Shadow8514Regs.dim1
        cwde
if bpp eq 16
        shl     eax, 1
endif

if bpp eq 24
        mov     edx,eax
        shl     eax, 1
        add     eax,edx
endif
        mov     _messSpad.srcLineInc, eax
else
        mov     eax, _messSpad.srcWidthInBytes
        sub     eax, _messSpad.totalBytes
        mov     _messSpad.srcLineInc, eax
endif
endm


SetUpDstLineIncTBLR macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpDstLineIncTBLR 1 4 8 16 or 24 bpp

        ; This blt runs from the top to the bottom and left to right.
        ; Set up the correct increments to get from line to line.
        ; This will be pixmap width - blt width.
if (bpp eq 8) or (bpp eq 16) or (bpp eq 24)
        mov     ax, dstPixmap.xLen
        sub     ax, Shadow8514Regs.dim1
        cwde
if bpp eq 16
        shl     eax, 1
endif
if bpp eq 24
        mov     edx,eax
        shl     eax, 1
        add     eax,edx
endif
        mov     _messSpad.dstLineInc, eax
else
        mov     eax, _messSpad.dstWidthInBytes
        sub     eax, _messSpad.totalBytes
        mov     _messSpad.dstLineInc, eax
endif
endm

endif   ;_8514

;-------------------------------------------------------------------------
; Macro:        SetUpSrcAddress bpp
;
; Parameters:   ShadowXGARegs, srcPixmap structure, _messSpad.srcWidthInBytes
;
; Returns:      esi (address of first byte/word to be used in the src pixmap)
;
;-------------------------------------------------------------------------

ifndef  _8514
SetUpSrcAddress macro bpp
        local SetUpSrcAddrLtoR

; First check that the bpp parameter is valid
CheckBpp SetUpSrcAddress 1 4 8 or 16 bpp

        ; Determine the address of the first position in the source
        ; This is srcWidthInBytes * ySrc + xSrc + srcPixmap.startAddr.
        mov     eax, _messSpad.srcWidthInBytes
        movzx   edx, ShadowXGARegs.src_map_y
        mul     edx
        movzx   edx, ShadowXGARegs.src_map_x
if bpp eq 16
        shl     edx, 1
endif
if bpp eq 4
        shr     edx, 1
endif
if bpp eq 1
        shr     edx, 3
endif
        add     eax, edx

        ; Pick up the source pixmap start address
rName esi SrcIndex
        mov     esiSrcIndex, srcPixmap.startAddr
        add     esiSrcIndex, eax

        ; esi points to the first pixel of the source
        ; BUT esi should point to the first byte of the source
        ; For 16bpp right to left this means the rightmost byte which is the
        ; next byte up in the bitmap
if bpp eq 16
        test    ShadowXGARegs.pixel_op, BLTDIR_RIGHTTOLEFT
        jz      short SetUpSrcAddrLtoR
        inc     esiSrcIndex
SetUpSrcAddrLtoR:
endif ; bpp eq 16

        ; esi is now the start address of the source data
endm

else    ;_8514

SetUpSrcAddress macro bpp
        local SetUpSrcAddrLtoR

; First check that the bpp parameter is valid
CheckBpp SetUpSrcAddress 1 4 8 or 16 bpp

        ; Determine the address of the first position in the source
        ; This is srcWidthInBytes * ySrc + xSrc + srcPixmap.startAddr.
        mov     eax, _messSpad.srcWidthInBytes
        movzx   edx, Shadow8514Regs.src_map_y
        mul     edx
        movzx   edx, Shadow8514Regs.src_map_x
if bpp eq 16
        shl     edx, 1
endif
if bpp eq 4
        shr     edx, 1
endif
if bpp eq 1
        shr     edx, 3
endif
        add     eax, edx

        ; Pick up the source pixmap start address
rName esi SrcIndex
        mov     esiSrcIndex, srcPixmap.startAddr
        add     esiSrcIndex, eax

        ; esi points to the first pixel of the source
        ; BUT esi should point to the first byte of the source
        ; For 16bpp right to left this means the rightmost byte which is the
        ; next byte up in the bitmap
if bpp eq 16
        test    Shadow8514Regs.pixel_op, BLTDIR_RIGHTTOLEFT
        jz      short SetUpSrcAddrLtoR
        inc     esiSrcIndex
SetUpSrcAddrLtoR:
endif ; bpp eq 16

        ; esi is now the start address of the source data
endm

endif   ;_8514


;-------------------------------------------------------------------------
; Macro:        SetUpPatAddress bpp
;
; Parameters:   ShadowXGARegs, patPixmap structure, _messSpad.srcWidthInBytes
;
; Returns:      esi (address of first byte/word to be used in the pat pixmap)
;
; Notes: Here we use srcWidthInBytes as the pattern width. This is the same
; use as in SetUpPatWidthInBytes. We know we never use the patPixmap at the
; same time as the srcPixmap so it is ok to overlap the use in this way.
;
;-------------------------------------------------------------------------

ifndef  _8514

SetUpPatAddress macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpPatAddress 1 bpp

        ; Determine the address of the first position in the pattern.
        ; This is srcWidthInBytes * ySrc + xSrc + patPixmap.startAddr.
        ; (srcWidthInBytes is set up with the pattern width in bytes!)
        mov     eax, _messSpad.srcWidthInBytes
        movzx   edx, ShadowXGARegs.patt_map_y
        mul     edx
        movzx   edx, ShadowXGARegs.patt_map_x
        shr     edx, 3
        add     eax, edx

        ; Pick up the pattern pixmap start address
rName esi PatIndex
        mov     esiPatIndex, patPixmap.startAddr
        add     esiPatIndex, eax

        ; esi is now the start address of the pattern data
endm

else
SetUpPatAddress macro bpp
; First check that the bpp parameter is valid
CheckBpp SetUpPatAddress 1 bpp

        ; Determine the address of the first position in the pattern.
        ; This is srcWidthInBytes * ySrc + xSrc + patPixmap.startAddr.
        ; (srcWidthInBytes is set up with the pattern width in bytes!)
        mov     eax, _messSpad.srcWidthInBytes
        movzx   edx, Shadow8514Regs.patt_map_y
        mul     edx
        movzx   edx, Shadow8514Regs.patt_map_x
        shr     edx, 3
        add     eax, edx

        ; Pick up the pattern pixmap start address
rName esi PatIndex
        mov     esiPatIndex, patPixmap.startAddr
        add     esiPatIndex, eax

        ; esi is now the start address of the pattern data
endm
endif


;-------------------------------------------------------------------------
; Macro:        SetUpDstAddress bpp
;
; Parameters:   ShadowXGARegs, dstPixmap structure, _messSpad.dstWidthInBytes
;
; Returns:      edi (address of first byte/word to be used in the dst pixmap)
;
;-------------------------------------------------------------------------

ifndef _8514

SetUpDstAddress macro bpp
        local SetUpDstAddrLtoR

; First check that the bpp parameter is valid
CheckBpp SetUpDstAddress 1 4 8 or 16 bpp

        ; Determine the address of the first position in the destination
        ; This is dstWidthInBytes * yDst + xDst + dstPixmap.startAddr
        mov     eax, _messSpad.dstWidthInBytes
        movzx   edx, ShadowXGARegs.dest_map_y
        mul     edx
        movzx   edx, ShadowXGARegs.dest_map_x
if bpp eq 16
        shl     edx, 1
endif
if bpp eq 4
        shr     edx, 1
endif
if bpp eq 1
        shr     edx, 3
endif
        add     eax, edx

        ; Pick up the destination start selector:offset pair
rName edi DstIndex
        mov     ediDstIndex, dstPixmap.startAddr
        add     ediDstIndex, eax

        ; edi points to the first pixel of the target
        ; BUT esi should point to the first byte of the target
        ; For 16bpp right to left this means the rightmost byte which is the
        ; next byte up in the bitmap
if bpp eq 16
        test    ShadowXGARegs.pixel_op, BLTDIR_RIGHTTOLEFT
        jz      short SetUpDstAddrLtoR
        inc     ediDstIndex
SetUpDstAddrLtoR:
endif ; bpp eq 16

        ; edi is now the start address of the destination data
endm

else
SetUpDstAddress macro bpp
        local SetUpDstAddrLtoR

; First check that the bpp parameter is valid
CheckBpp SetUpDstAddress 1 4 8 16 or 24 bpp

        ; Determine the address of the first position in the destination
        ; This is dstWidthInBytes * yDst + xDst + dstPixmap.startAddr
        mov     eax, _messSpad.dstWidthInBytes
        movzx   edx, Shadow8514Regs.dest_map_y
        mul     edx
        movzx   edx, Shadow8514Regs.dest_map_x
if bpp eq 24
        mov     ecx,edx
        shl     edx, 1
        add     edx,ecx
endif
if bpp eq 16
        shl     edx, 1
endif
if bpp eq 4
        shr     edx, 1
endif
if bpp eq 1
        shr     edx, 3
endif
        add     eax, edx

        ; Pick up the destination start selector:offset pair
rName edi DstIndex
        mov     ediDstIndex, dstPixmap.startAddr
        add     ediDstIndex, eax

        ; edi points to the first pixel of the target
        ; BUT esi should point to the first byte of the target
        ; For 16bpp right to left this means the rightmost byte which is the
        ; next byte up in the bitmap
if bpp eq 16
        test    Shadow8514Regs.pixel_op, BLTDIR_RIGHTTOLEFT
        jz      short SetUpDstAddrLtoR
        inc     ediDstIndex
SetUpDstAddrLtoR:
endif ; bpp eq 16

if bpp eq 24
        test    Shadow8514Regs.pixel_op, BLTDIR_RIGHTTOLEFT
        jz      short SetUpDstAddrLtoR
        inc     ediDstIndex
        inc     ediDstIndex
SetUpDstAddrLtoR:
endif ; bpp eq 16

        ; edi is now the start address of the destination data
endm
endif


;-------------------------------------------------------------------------
; Macro:        SetUpSrcToDstShift bpp
;
; Parameters:   ShadowXGARegs structure
;
; Returns:      _messSpad.srcToDestShift, _messSpad.srcIndexAdjusted
;
;-------------------------------------------------------------------------

ifndef  _8514

SetUpSrcToDstShift macro bpp,options
        local gotShift
; First check that the bpp parameter is valid
CheckBpp SetUpSrcToDstShift 1 or 4 bpp
;Check the options are valid
;               blank   - Require Source to Destination shift
;               pattern - Require Pattern to Destination shift
ifnb <options>
ifdif <options>, <pattern>
   .err
   %out SetUpSrcToDstShift options parameter must be blank or 'pattern'.
endif
endif

        ; Work out the source to destination shift. This is the number of
        ; bits that a word from the source needs to be shifted such that
        ; eight bits of it line up with a byte from the destination.
        ; 
        ; There are two cases:
        ; 
        ; 1) The src bit offset is >= the dst bit offset.
        ; 
        ;    For example, dst bit offset = 2, src bit offset = 5:
        ; 
        ;          01234567                - dst byte
        ;            D
        ;            <<<S                  - src to dst shift =  3
        ;          01234567.......         - src word (before aligning)
        ;          34567.......            - src word (after aligning)
        ; 
        ;    This will require the bits from the second byte picked up to the
        ;    right (........) of the byte where the source starts
        ; 
        ; 
        ; 2) The src bit offset is < the dst bit offset.
        ; 
        ;    For example, dst bit offset = 5, src bit offset = 2:
        ; 
        ;          01234567                - dst byte
        ;               D
        ;               <<<<<S             - src to dst shift = 5
        ;          ........01234567        - src word (before aligning)
        ;          ...01234567             - src word (after aligning)
        ; 
        ;    This will require the bits from the first byte picked up to the
        ;    left (........) of the byte where the source starts
        ; 
        ; 
        ; We must also consider converting from motorola to intel format:
        ; 
        ; Bitmap bits (motorola format)...
        ; 
        ;       addr n  addr n+1
        ;       ABDCEFGHabcdefgh
        ; 
        ; Reading bitmap bits into intel word register...
        ; 
        ;       msbyte  lsbyte
        ;       abcdefghABCDEFGH
        ; 
        ; We pick up the source word in intel format so that abcdefgh is in
        ; the msbyte and ABCDEFGH is in the lsbyte then we rotate left by the
        ; src to dst shift and get the required 8 bits in the lsbyte.
        ; 

        ; First of all we must calculate S and D (the src and dst bit offsets).
rName al S
rName dl D

ifb <options>
        ; use source map coordinates
        mov     alS, byte ptr ShadowXGARegs.src_map_x
else
        ; use pattern map coordinates
        mov     alS, byte ptr ShadowXGARegs.patt_map_x
endif

        mov     dlD, byte ptr ShadowXGARegs.dest_map_x
if bpp eq 1
        ; S and D are in the range 0 to 7.
        and     alS, 07h
        and     dlD, 07h
endif
if bpp eq 4
        ; S and D are either 0 or 4.
        and     alS, 01h
        shl     alS, 2
        and     dlD, 01h
        shl     dlD, 2
endif

        ; Now find S-D and jump to the correct case (either S>=D or S<D).
        sub     alS, dlD
        jc      short @f

        ; The src bit offset S is >= the dst bit offset D.
        ; In this case the src to dst shift is simply (S-D) and the address
        ; of the word to pick up is the address of the byte that the first
        ; bit is in, so there is no need to adjust the src address.
        mov     _messSpad.srcToDestShift, alS

        ; Set a flag to indicate that we have not adjusted the source index.
        mov     _messSpad.srcIndexAdjusted, FALSE

        jmp     short gotShift

@@:
        ; The src bit offset S is < the dst bit offset D.
        ; In this case the src to dst shift is 8+(S-D) and the address
        ; of the word to pick up is the address of the byte to the left of
        ; the byte in which the first bit is in, so the the src address must
        ; be adjusted by -1.
        add     alS, 8
        mov     _messSpad.srcToDestShift, alS
        dec     esiSrcIndex

        ; Set a flag to indicate that we have adjusted the source index.
        mov     _messSpad.srcIndexAdjusted, TRUE

gotShift:
rFree al S
rFree dl D
endm

else    ;_8514

SetUpSrcToDstShift macro bpp,options
        local gotShift
; First check that the bpp parameter is valid
CheckBpp SetUpSrcToDstShift 1 or 4 bpp
;Check the options are valid
;               blank   - Require Source to Destination shift
;               pattern - Require Pattern to Destination shift
ifnb <options>
ifdif <options>, <pattern>
   .err
   %out SetUpSrcToDstShift options parameter must be blank or 'pattern'.
endif
endif

        ; Work out the source to destination shift. This is the number of
        ; bits that a word from the source needs to be shifted such that
        ; eight bits of it line up with a byte from the destination.
        ; 
        ; There are two cases:
        ; 
        ; 1) The src bit offset is >= the dst bit offset.
        ; 
        ;    For example, dst bit offset = 2, src bit offset = 5:
        ; 
        ;          01234567                - dst byte
        ;            D
        ;            <<<S                  - src to dst shift =  3
        ;          01234567.......         - src word (before aligning)
        ;          34567.......            - src word (after aligning)
        ; 
        ;    This will require the bits from the second byte picked up to the
        ;    right (........) of the byte where the source starts
        ; 
        ; 
        ; 2) The src bit offset is < the dst bit offset.
        ; 
        ;    For example, dst bit offset = 5, src bit offset = 2:
        ; 
        ;          01234567                - dst byte
        ;               D
        ;               <<<<<S             - src to dst shift = 5
        ;          ........01234567        - src word (before aligning)
        ;          ...01234567             - src word (after aligning)
        ; 
        ;    This will require the bits from the first byte picked up to the
        ;    left (........) of the byte where the source starts
        ; 
        ; 
        ; We must also consider converting from motorola to intel format:
        ; 
        ; Bitmap bits (motorola format)...
        ; 
        ;       addr n  addr n+1
        ;       ABDCEFGHabcdefgh
        ; 
        ; Reading bitmap bits into intel word register...
        ; 
        ;       msbyte  lsbyte
        ;       abcdefghABCDEFGH
        ; 
        ; We pick up the source word in intel format so that abcdefgh is in
        ; the msbyte and ABCDEFGH is in the lsbyte then we rotate left by the
        ; src to dst shift and get the required 8 bits in the lsbyte.
        ; 

        ; First of all we must calculate S and D (the src and dst bit offsets).
rName al S
rName dl D

ifb <options>
        ; use source map coordinates
        mov     alS, byte ptr Shadow8514Regs.src_map_x
else
        ; use pattern map coordinates
        mov     alS, byte ptr Shadow8514Regs.patt_map_x
endif

        mov     dlD, byte ptr Shadow8514Regs.dest_map_x
if bpp eq 1
        ; S and D are in the range 0 to 7.
        and     alS, 07h
        and     dlD, 07h
endif
if bpp eq 4
        ; S and D are either 0 or 4.
        and     alS, 01h
        shl     alS, 2
        and     dlD, 01h
        shl     dlD, 2
endif

        ; Now find S-D and jump to the correct case (either S>=D or S<D).
        sub     alS, dlD
        jc      short @f

        ; The src bit offset S is >= the dst bit offset D.
        ; In this case the src to dst shift is simply (S-D) and the address
        ; of the word to pick up is the address of the byte that the first
        ; bit is in, so there is no need to adjust the src address.
        mov     _messSpad.srcToDestShift, alS

        ; Set a flag to indicate that we have not adjusted the source index.
        mov     _messSpad.srcIndexAdjusted, FALSE

        jmp     short gotShift

@@:
        ; The src bit offset S is < the dst bit offset D.
        ; In this case the src to dst shift is 8+(S-D) and the address
        ; of the word to pick up is the address of the byte to the left of
        ; the byte in which the first bit is in, so the the src address must
        ; be adjusted by -1.
        add     alS, 8
        mov     _messSpad.srcToDestShift, alS
        dec     esiSrcIndex

        ; Set a flag to indicate that we have adjusted the source index.
        mov     _messSpad.srcIndexAdjusted, TRUE

gotShift:
rFree al S
rFree dl D
endm

endif   ;_8514

;-------------------------------------------------------------------------
; Macro: CheckBpp name n1 n2... or nn bpp
;
; Notes: This macro checks that the bpp parameter is one of n1 to nn valid
; values for the bits per pel. If it is not then an error is generated.
; Up to four valid values can be specified. It is important that the "or"
; is not ommitted before the last valid value (unless there is only one
; valid value!).
;
; Example:
;       SomeMacroName macro bpp
;        CheckBpp SomeMacroName 1 4 8 or 16 bpp
;        ...
;       endm
;
;-------------------------------------------------------------------------

CheckBpp macro name, a, b, c, d, e, f, g
if2
 ifidn <e>, <or>
  if (g ne a) and (g ne b) and (g ne c) and (g ne d) and (g ne f)
   .err
   %out name macro bits per pel parameter must be a, b, c, d or f.
  endif
  exitm
 endif
 ifidn <d>, <or>
  if (f ne a) and (f ne b) and (f ne c) and (f ne e)
   .err
   %out name macro bits per pel parameter must be a, b, c, or e.
  endif
  exitm
 endif
 ifidn <c>, <or>
  if (e ne a) and (e ne b) and (e ne d)
   .err
   %out name macro bits per pel parameter must be a, b or d.
  endif
  exitm
 endif
 ifidn <b>, <or>
  if (d ne a) and (d ne c)
   .err
   %out name macro bits per pel parameter must be a or c.
  endif
  exitm
 endif
 if b ne a
  .err
  %out name macro bits per pel parameter must be a.
 endif
endif
endm

ifndef _8514
CheckTBLR macro
IFDEF FIREWALLS
        ; Check that the operation is running from top-left to bottom-right.
        test    ShadowXGARegs.pixel_op, BLTDIR_RIGHTTOLEFT+BLTDIR_BOTTOMTOTOP
        jz      short @f
        int     3
@@:
ENDIF ; FIREWALLS
endm

else  ;_8514
CheckTBLR macro
IFDEF FIREWALLS
        ; Check that the operation is running from top-left to bottom-right.
        test    Shadow8514Regs.pixel_op, BLTDIR_RIGHTTOLEFT+BLTDIR_BOTTOMTOTOP
        jz      short @f
        int     3
@@:
ENDIF ; FIREWALLS
endm

endif ;_8514

;-------------------------------------------------------------------------
; Macro:        SetUpSrcDest bpp
;
; Parameters:   ShadowXGARegs, pixmap structures
;
; Returns:      _messSpad.byteInc
;               _messSpad.dwordInc
;               _messSpad.startMask                      (1 or 4 bpp case only)
;               _messSpad.endMask                        (1 or 4 bpp case only)
;               _messSpad.startMaskInv                   (1 or 4 bpp case only)
;               _messSpad.endMaskInv                     (1 or 4 bpp case only)
;               _messSpad.totalBytes                     (1 or 4 bpp case only)
;               _messSpad.srcWidthInBytes
;               _messSpad.dstWidthInBytes
;               _messSpad.srcLineInc
;               _messSpad.dstLineInc
;               _messSpad.srcToDestShift                 (1 or 4 bpp case only)
;               edi - as first position in destination
;               esi - as first position in source
;               processors string operation flag        (8 or 16 bpp case only)
;
;-------------------------------------------------------------------------

SetUpSrcDest macro bpp
        local topToBottomRightToLeft, topToBottomLeftToRight
        local leftToRight, gotIncs

; First check that the bpp parameter is valid
CheckBpp SetUpSrcDest 1 4 8 or 16 bpp


if (bpp eq 1) or (bpp eq 4)
        ; Set up the start and end masks, and calculate the total width
        ; of the operation in destination bytes.
        SetUpMasksAndTotalBytes bpp
endif


        ; Work out the source and destination pixmap widths in bytes.
        SetUpSrcWidth bpp
        SetUpDstWidth bpp


        ; Find out which direction the blt is running in and do the direction
        ; dependent set up.

rName esi PixelOp

        ifndef  _8514
        mov     esiPixelOp, ShadowXGARegs.pixel_op
        else
        mov     esiPixelOp, Shadow8514Regs.pixel_op
        endif
        test    esiPixelOp, BLTDIR_RIGHTTOLEFT
        jz      leftToRight

        ; This blt runs from the right to the left.
        ; 
        ; Set up the string operation flag for post increments and set
        ; our byte increment and dword increment and adjust values.
        std
        mov     _messSpad.byteInc, -1
        mov     _messSpad.dwordInc, -4
        mov     _messSpad.dwordAdjust, 3


        ; Now work out the correct increments after each line
        test    esiPixelOp, BLTDIR_BOTTOMTOTOP
        jz      short topToBottomRightToLeft

        ; This blt runs from the bottom to the top and right to left.
        ; Set up the correct increments to get from line to line.
        SetUpSrcLineIncBTRL bpp
        SetUpDstLineIncBTRL bpp
        jmp     gotIncs

topToBottomRightToLeft:
        ; This blt runs from the top to the bottom and right to left.
        ; Set up the correct increments to get from line to line.
        SetUpSrcLineIncTBRL bpp
        SetUpDstLineIncTBRL bpp
        jmp gotIncs



leftToRight:
        ; This blt runs from the left to the right.  Set up the string
        ; operation flag for post increments and set our byte increment
        ; and dword increment and adjust values.
        cld
        mov     _messSpad.byteInc, 1
        mov     _messSpad.dwordInc, 4
        mov     _messSpad.dwordAdjust, 0

        ; Now work out the correct increments after each line
        test    esiPixelOp, BLTDIR_BOTTOMTOTOP
        jz      short topToBottomLeftToRight

        ; This blt runs from the bottom to the top and left to right.
        ; Set up the correct increments to get from line to line.
        SetUpSrcLineIncBTLR bpp
        SetUpDstLineIncBTLR bpp
        jmp     short gotIncs

topToBottomLeftToRight:
        ; This blt runs from the top to the bottom and left to right.
        ; Set up the correct increments to get from line to line.
        SetUpSrcLineIncTBLR bpp
        SetUpDstLineIncTBLR bpp

gotIncs:
rFree esi PixelOp



        ; Set up the address of the first position in the source
        SetUpSrcAddress bpp

        ; Set up the address of the first position in the destination
        SetUpDstAddress bpp



if (bpp eq 1) or (bpp eq 4)
        ; Set up the source to destination shift.
        SetUpSrcToDstShift bpp
endif


endm




;-------------------------------------------------------------------------
; Functions:    eddf_MESSSetUpSrcDest16
;               eddf_MESSSetUpSrcDest81
;               eddf_MESSSetUpSrcDest41
;               eddf_MESSSetUpSrcDest11
;
; See SetUpSrcDest macro.
;
;-------------------------------------------------------------------------

        align   4
cProc   eddf_MESSSetUpSrcDest16, <PUBLIC>
cBegin
rStart
        SetUpSrcDest 16
rEnd
cEnd

        align   4
cProc   eddf_MESSSetUpSrcDest81, <PUBLIC>
cBegin
rStart
        SetUpSrcDest 8
rEnd
cEnd

        align   4
cProc   eddf_MESSSetUpSrcDest41, <PUBLIC>
cBegin
rStart
        SetUpSrcDest 4
rEnd
cEnd

        align   4
cProc   eddf_MESSSetUpSrcDest11, <PUBLIC>
cBegin
rStart
        SetUpSrcDest 1
rEnd
cEnd



;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpPatDest11
;
; This does some set-up common to the pattern/destination operations
; which are used for text operations (ie no-wrap around so this is very
; like source/destination set-up)
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.startMask
;       _messSpad.endMask
;       _messSpad.totalBytes
;       _messSpad.srcWidthInBytes (used on the pattern)
;       _messSpad.dstWidthInBytes
;       _messSpad.dstLineInc
;       _messSpad.srcLineInc (used on the pattern)
;       _messSpad.srcToDestShift
;       edi - as first position in destination
;       esi - as first position in source
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpPatDest11, <PUBLIC>

cBegin
rStart
        ; These operations will always go bottom left to top right
        ; First work out the masks and the total width of the operation
        ; in destination bytes.
        SetUpMasksAndTotalBytes 1

        ; Now work out the pattern and destination pixmap widths in bytes.
        ; SetUpPatWidth will set srcWidthInBytes as the pattern width.
        SetUpPatWidth 1
        SetUpDstWidth 1

        ; Now work out the correct increments to get from line to line.
        ; We can use SetUpSrcLineIncBTLR here because at 1 bpp it use
        ; srcWidthInBytes and totalBytes, which we have already set up
        ; to correspond to the pattern.
        SetUpSrcLineIncBTLR 1
        SetUpDstLineIncBTLR 1

        ; Now work out the start addresses.
        SetUpPatAddress 1
        SetUpDstAddress 1

        ; Work out the src to destination shift
rFree esi PatIndex
rName esi SrcIndex
        SetUpSrcToDstShift 1 pattern
rFree esi SrcIndex
rName esi PatInex

rEnd
cEnd

;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpDest16
;
; This does some set-up common to destination only operations.
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.dstLineInc
;       _messSpad.dstWidthInBytes
;       edi - as first position in destination
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpDest16, <PUBLIC>

cBegin
rStart
        ; Destination only operations should only run from top-left to
        ; bottom right.  Don't allow anything else.
        CheckTBLR

        ; Set up the string operation flag
        cld

        ; Set up the destination width in bytes.
        SetUpDstWidth 16

        ; Set up the line increment
        SetUpDstLineIncTBLR 16

        ; Set up the start address
        SetUpDstAddress 16

rEnd
cEnd


;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpDest81
;
; This does some set-up common to destination only operations.
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.dstLineInc
;       _messSpad.dstWidthInBytes
;       edi - as first position in destination
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpDest81, <PUBLIC>

cBegin
rStart
        ; Destination only operations should only run from top-left to
        ; bottom right.  Don't allow anything else.
        CheckTBLR

        ; Set up the string operation flag
        cld

        ; Set up the destination width in bytes.
        SetUpDstWidth 8

        ; Set up the line increment
        SetUpDstLineIncTBLR 8

        ; Set up the start address
        SetUpDstAddress 8

rEnd
cEnd

ifdef BPP24 
;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpDest24
;
; This does some set-up common to destination only operations.
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.dstLineInc
;       _messSpad.dstWidthInBytes
;       edi - as first position in destination
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpDest24, <PUBLIC>

cBegin
rStart
        ; Destination only operations should only run from top-left to
        ; bottom right.  Don't allow anything else.
        CheckTBLR

        ; Set up the string operation flag
        cld

        ; Set up the destination width in bytes.
        SetUpDstWidth 24

        ; Set up the line increment
        SetUpDstLineIncTBLR 24

        ; Set up the start address
        SetUpDstAddress 24

rEnd
cEnd
endif ;BPP24 

;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpDest41
;
; This does some set-up common to destination only operations.
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.startMask
;       _messSpad.endMask
;       _messSpad.totalBytes
;       _messSpad.dstWidthInBytes
;       _messSpad.dstLineInc
;       edi - as first position in destination
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpDest41, <PUBLIC>

cBegin
rStart
        ; Destination only operations should only run from top-left to
        ; bottom right.  Don't allow anything else.
        CheckTBLR

        ; Set up the start and endmasks, and the total width of the operation
        ; in destination bytes.
        SetUpMasksAndTotalBytes 4

        ; Now work out the destination width in bytes.
        SetUpDstWidth 4

        ; Now work out the increment to get from line to line.
        SetUpDstLineIncTBLR 4

        ; Now work out the start address.
        SetUpDstAddress 4

rEnd
cEnd

;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpDestForPat41
;
; This does some set-up common to pattern/destination operations at 4,1
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.startMask - note this is a different use of the mask
;       _messSpad.totalBytes
;       _messSpad.dstWidthInBytes
;       _messSpad.dstLineInc
;       edi - first position in destination
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpDestForPat41, <PUBLIC>

cBegin
rStart
        ; These operations should only run from top-left to
        ; bottom left.  Don't allow anything else.
        CheckTBLR

        ; Now time to work out some stuff..
        ; startMask
        ifndef  _8514
        mov     bx, ShadowXGARegs.dest_map_x
        else
        mov     bx, Shadow8514Regs.dest_map_x
        endif
        mov     cx, bx

        ; Work out the mask for the first pel (either 11110000 or 00001111)
        mov     dl, 0F0h
        and     cl, 01h
        shl     cl, 2
        shr     dl, cl
        mov     _messSpad.startMask, dl

        ; Now work out how many times we will increment the
        ; destination pointer during each row and store it in totalBytes
        ; The destination pointer is incremented after every odd (ie lsb
        ; of x coordinate set) pel.
        and     ebx, 01h
        ifndef  _8514
        add     bx, ShadowXGARegs.dim1
        else
        add     bx, Shadow8514Regs.dim1
        endif
        inc     ebx
        shr     ebx, 1
        mov     _messSpad.totalBytes, ebx

        ; Now work out the destination width in bytes.
        SetUpDstWidth 4

        ; Now work out the increment to get from line to line.
        SetUpDstLineIncTBLR 4

        ; Now work out start address
        SetUpDstAddress 4

rEnd
cEnd

;-------------------------------------------------------------------------
; Function: eddf_MESSSetUpDest11
;
; This does some set-up common to destination only operations.
;
; Parameters:
;       ShadowXGARegs, pixmap structures
;
; Returns:
;       _messSpad.startMask
;       _messSpad.endMask
;       _messSpad.fullBytes
;       _messSpad.totalBytes
;       _messSpad.dstWidthInBytes
;       _messSpad.dstLineInc
;       edi - as first position in destination
;
;-------------------------------------------------------------------------
        align   4
cProc   eddf_MESSSetUpDest11, <PUBLIC>

cBegin
rStart
        ; Destination only operations should only run from top-left to
        ; bottom right.  Don't allow anything else.
        CheckTBLR

        ; Set up the start and endmasks, and the total width of the operation
        ; in destination bytes.
        SetUpMasksAndTotalBytes 1

        ; Now work out the destination width in bytes.
        SetUpDstWidth 1

        ; Now work out the increment to get from line to line.
        SetUpDstLineIncTBLR 1

        ; Now work out the start address.
        SetUpDstAddress 1


rEnd
cEnd




_TEXT ends


END
