;*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    ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = PATCAHE.ASM
;*
;* DESCRIPTIVE NAME = 
;*
;*
;* VERSION      V2.0
;*
;* DATE         10/13/88
;*
;* DESCRIPTION  This file contains the routines that generate the 8514 pattern  
;*              cache.
;*
;* FUNCTIONS    far_cache_the_pattern 
;*              cache_the_pattern
;*              spread_pattern
;*              wes_kluge
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   10/13/88                     Author:  Wes Rupel       [wesleyr]
;*****************************************************************************/

        .286p
        .xlist
        include cmacros.inc
        include pmgre.inc
        include driver.inc
        include assert.mac
        include 8514.inc
        include profile.inc
        .list
        .286p

sBegin  Data
        externW         PatCacheX
        externW         PatCacheY
        externW         PatCacheXExt
        externW         PatCacheYExt
        externW         hwFlags
sEnd    Data

sBegin  Code
        assumes cs,Code

DEBUG = 1

publab  macro   foo
  ifdef DEBUG
        public  foo     ;; generates debugging labels
      ifndef  foo
        foo:
      endif
  endif
endm

page

;/***************************************************************************
;*
;* FUNCTION NAME = cache_the_pattern
;*
;* DESCRIPTION   = Caches the pattern in off-screen 8514 memory. 
;*
;*                 Registers Preserved:       
;*                       BH,DS,BP,SI    
;*                 Registers Destroyed:       
;*                       AX,BL,CX,DX,DI 
;*
;* INPUT         = DS = Data
;*                 SI = DDC 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*                 
;**************************************************************************/

CMDPATCOLOR     =       (\
                         CMD_C_HRECT+CMD_BYTE_LO+CMD_BYTE+CMD_FV_VAR+CMD_DY+\
                         CMD_DX+CMD_MA_ACCESS+CMD_PA_ONE+CMD_RW_W\
                        )
CMDCOPY=CMD_C_CRECT+CMD_FV_FIX+CMD_DX+CMD_DY+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW_W

        assumes ds,Data
        assumes es,nothing


        public  far_cache_the_pattern
far_cache_the_pattern   proc                     far
        profile entered
        call    cache_the_pattern
        profile exiting
        ret
far_cache_the_pattern   endp


        public  cache_the_pattern
cache_the_pattern       proc                     near
        profile entered
        push    si

;/*
;** Set up a maximal clip rectangle. It doesn't have to be exact because we
;** know the bounds of what we are writing on the board and don't have to worry
;** about overwriting what we shouldn't.
;*/

;/*
;** GrabScreen must be done before calling this!
;*/

        WaitQ   4                       ; set clip rectangle to max
        outwQ   XMIN,(0+XMIN_2DECODE)   ; min x
        outwQ   XMAX,(1023+XMAX_2DECODE); max x
        outwQ   YMIN,(0+YMIN_2DECODE)   ; min y
        outwQ   YMAX,(1023+YMAX_2DECODE); max y

;/*
;** We must cache a pattern on the board. Since we always go to the destination
;** in this path, we always cache the color version of the brush.
;*/

        WaitQ   8                             ; need room in the queue
        outwQ   MODE,(MODE_2DECODE+MD_PS_ONES); pattern always 1s
        outbQ   FUNCTION_1,(FUNC_2OP_VAR+FUNC_S)
        outbQ   WRITE_ENABLE,WRITE_ALL_PLANES ; all planes enabled for writing
        mov     ax,SIZE_PATTERN - 1           ; LX is 0-based
        outwQ   LX,ax
        mov     cx,PatCacheYExt               ; height of cache buffer
        mov     ax,cx
        dec     ax                            ; now 0-based
        outwQ   LY,ax
        .errnz  LY_2DECODE
        outwQ   X0,PatCacheX                  ; starting x of pattern cache
        outwQ   Y0,PatCacheY                  ; starting y of pattern cache
        outwQ   CMD_FLAGS,CMDPATCOLOR         ; do entire cached pattern

        add     si,ddc_pa.pa_abColor          ; Ds:Si -> color brush pixels

        mov     bl,00000001b                  ; when to rewind to brush start
        .errnz  SIZE_PATTERN - 8
        mov     dx,COLOR_1                    ; variable data port


pp_cache_8_bpp_lp:

        outsw                                     ; send 8 pixels to cache buffer
        outsw
        outsw
        outsw
        .errnz  SIZE_PATTERN - 8

        rol     bl,1                              ; rewind to brush start ?
        sbb     ax,ax
        and     ax,(SIZE_PATTERN * SIZE_PATTERN); # bytes in pattern if rewind
        sub     si,ax                             ; perhaps rewind to brush begin

        loop    pp_cache_8_bpp_lp                ; for all cached pattern rows...

;/*
;** We now have a double copy of the color pattern cached.
;** It has SIZE_PATTERN width, but is twice the height of the
;** normal pattern (it was duplicated once in the Y direction).
;**
;** We will now use hardware assist to duplicate the double-pattern all the
;** way across (in the X direction).
;*/

        call    spread_pattern

        pop     si
        profile exiting
        ret
cache_the_pattern        endp

;/***************************************************************************
;*
;* FUNCTION NAME = spread_pattern
;*
;* DESCRIPTION   = 
;*     This routine takes a rectangle at the left edge of the display and     
;*     duplicates it in the X direction to fill the scanlines.  We now have a 
;*     double copy of the color pattern cached.  It has SIZE_PATTERN width,   
;*     but is twice the height of the normal pattern (it was duplicated once).
;*     On each copy we double the size of the pattern.  Copy# 1 -> 2 *        
;*     SIZE_PATTERN Copy# 2 -> 4 * SIZE_PATTERN Copy# 3 -> 8 * SIZE_PATTERN   
;*     Copy# 4 -> 16 * SIZE_PATTERN Copy# 5 -> 32 * SIZE_PATTERN Copy# 6 -> 64
;*     * SIZE_PATTERN Copy# 7 -> 128 * SIZE_PATTERN = ScreenWidth             
;*
;*                 Registers Preserved:       
;*                       BX,DS,BP       
;*                 Registers Destroyed:       
;*                       AX,CX,DX,DI,SI 
;*
;* INPUT         = DS = Data
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*                 
;**************************************************************************/

        public  sp_next_copy

        assumes ds,Data
        assumes es,nothing

        public  spread_pattern
spread_pattern       proc    near
        profile entered
        mov     di,SIZE_PATTERN
        WaitQ   5
publab sp_func
        outbQ   FUNCTION_1,(FUNC_2OP_COPY+FUNC_S)
publab sp_mode
        outwQ   MODE,(MODE_2DECODE+MD_PS_ONES)
publab sp_ly
        mov     ax,PatCacheYExt                   ; height of cache buffer
        dec     ax                                ; LY is 0-based
        outwQ   LY,ax
        .errnz  LY_2DECODE
publab sp_x0
    
        outwQ   X0,0                             ; starting x of Source Rect
publab sp_y0
        outwQ   Y0,PatCacheY                     ; starting y of Source Rect
        mov     si,ax

        mov     cx,7                             ; need seven copy ops to fill the scanlength
        .errnz  SIZE_PATTERN - 8
sp_next_copy:

publab sp_copy
        WaitQ   4
        mov     ax,di
        add     di,di
publab sp_x1
        outwQ   X1,ax                             ; starting x of Dest Rect
        dec     ax                                ; LX is zero-based
publab sp_lx
        outwQ   LX,ax
publab sp_y1
        outwQ   Y1,si                             ; starting y of Dest Rect (same as src)
publab sp_cmd
        outwQ   CMD_FLAGS,CMDCOPY
        loop    sp_next_copy


ifdef SHOWPATT
        WaitQ   4                       ; set clip rectangle to max
        outwQ   XMIN,(0+XMIN_2DECODE)   ; min x
        outwQ   XMAX,(1023+XMAX_2DECODE); max x
        outwQ   YMIN,(0+YMIN_2DECODE)   ; min y
        outwQ   YMAX,(1023+YMAX_2DECODE); max y

        mov     di,SIZE_PATTERN

        mov     cx,7                    ; need seven copy ops to fill the scanlength
        .errnz  SIZE_PATTERN - 8
ssp_next_copy:

        WaitQ   5
publab sp_func
        outbQ   FUNCTION_1,(FUNC_2OP_COPY+FUNC_S)
publab sp_mode
        outwQ   MODE,(MODE_2DECODE+MD_PS_ONES)
publab sp_ly
        mov     ax,PatCacheYExt                  ; height of cache buffer
        dec     ax                               ; LY is 0-based
        outwQ   LY,ax
        .errnz  LY_2DECODE
publab sp_x0
        outwQ   X0,0                             ; starting x of Source Rect
publab sp_y0
        outwQ   Y0,PatCacheY                     ; starting y of Source Rect

;/*
;**---start loop here ---
;*/

publab sp_copy
        WaitQ   4
        mov     ax,di
        add     di,di
publab sp_x1
        outwQ   X1,ax                             ; starting x of Dest Rect
        dec     ax                                ; LX is zero-based
publab sp_lx
        outwQ   LX,ax
publab sp_y1
        outwQ   Y1,16                             ; starting y of Dest Rect (same as src)
publab sp_cmd
        outwQ   CMD_FLAGS,CMDCOPY
        loop    ssp_next_copy

endif ;SHOWPATT


        profile exiting
        ret
spread_pattern       endp

sEnd    Code
        end

