;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;        Copyright (c) 1987-1990  Texas Instruments Incorporated.         ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Extension                                     ;
;-------------------------------------------------------------------------;
;                                                                         ;
; patn_line function                                                      ;
;                                                                         ;
;   This function fills a single horizontal line of the specified width   ;
;   with the current pattern.  This function is designed to be called     ;
;   from another assembly language routine; it cannot be called from a    ;
;   GSP-C program.  For the sake of convenient integration of this        ;
;   function into shape-filling functions, the arguments are passed in    ;
;   the B-file registers.  Prior to the call, the registers are set up    ;
;   in a manner similar to that required for a FILL XY instruction, with  ;
;   the exception that B8, which contains the color0 value, must also be  ;
;   valid.  The intent is that a call to this function is to be used in   ;
;   place of the FILL instruction.  This function requires that the       ;
;   calling program loads the 16 MSBs of DYDX with >0001 prior to the     ;
;   call; the 16 LSBs of DYDX specify the fill width.                     ;
;-------------------------------------------------------------------------;
; At call:  B-file registers are set up for FILL XY instruction, with     ;
;           the exception that B8 must contain the color0 value to be     ;
;           used for the pattern fill.  B9 contains the color1 value.     ;
;                                                                         ;
; Registers altered:  Same as those altered by FILL instruction.          ;
;-------------------------------------------------------------------------;
; Revision history:                                                       ;
;   3/02/87...Original version written..................Jerry Van Aken    ;
;   6/24/87...Allocated stack buffer for pattern........JV                ;
;  09/12/88...Access globals from environment struct....W.S.Egr           ;
;   7/14/89...Added 34020 support.......................A. Sharp          ;
;-------------------------------------------------------------------------;
;
        .title    'pattern line fill'
        .file     'patn_line'
;
;     DECLARE GLOBAL FUNCTION NAME
;
        .globl    _patn_line
;
;
;     DEFINE CONSTANTS
        .include  oem.inc
        .include  gspreg.inc
        .include  gsptypes.inc      ;Offsets into environment struct
        .include  gspglobs.inc          
;
;     ENTRY POINT
;
_patn_line:

        SETF      16,0,0              ;
        MMTM      SP,A0,A1,A2         ;save registers
        MMTM      SP,B0,B1,B7

* Copy current row of pattern to 32-bit buffer on system stack.
        MOVE      @(_pattern+PATTERN_DATA),B10,1    ;pattern start address
        MOVK      15,B11              ;load 4-bit mask
        SLL       16,B11              ;align mask with 4 LSBs of y
        AND       DADDR,B11           ;isolate 4 LSBs of y
        SRL       12,B11              ;convert y to index value
        ADD       B11,B10             ;index into pattern
        MOVE      *B10,B10,0          ;get 16-bit row of pattern
        MOVE      B10,B11             ;
        SLL       16,B11              ;
        MOVY      B11,B10             ;replicate row to 32 bits
;
        .if     GSP_34010 ; Code used if the processor is a 34010
        MOVE      DADDR,B12           ;
        NEG       B12                 ;shift count = -(LSBs of x)
        RL        B12,B10             ;align pattern with x
        MOVE      B10,*-SP,1          ;push 32 pattern bits
* Determine whether fill width is less than 32 pixels.
        MOVE      SP,SADDR            ;load buffer start address
        MOVK      32,B10              ;
        SUBXY     B10,DYDX            ;is DX < 32 pixels?
        JRNV      LONG                ;if not, jump to long fill
* Handle special case of fill width < 32 bits.
        ADDXY     B10,DYDX            ;restore DX
        PIXBLT    B,XY                ;fill remaining pixels
        JRUC      DONE

* Fill width >= 32 pixels.  Pattern fill to specified width.
LONG:
        MOVE      DYDX,A1             ;get specified DX value
        MOVK      32,A0               ;buffered row width = 32
        MOVE      DADDR,A2            ;save screen dest'n address
        MOVX      B10,DYDX            ;set fill width = 32 pixels
LOOP:
        PIXBLT    B,XY                ;fill next 32 pixels
        MOVE      SP,SADDR            ;reinitialize buffer address
        ADDXY     A0,A2               ;increment dest'n address
        MOVE      A2,DADDR            ;
        SUBXY     A0,A1               ;is DX >= 32 pixels?
        JRNV      LOOP                ;if so, loop again
* Take care of the less than 32 pixels remaining to be filled.
        ADDXY     A0,A1               ;restore DX
        MOVE      A1,DYDX             ;
        PIXBLT    B,XY                ;fill remaining pixels
* Restore registers and return to calling routine.
DONE:
        ADDK      32,SP               ;discard pattern from stack
        .endif
;
        .if     GSP_34020 ; Code used if the processor is a 34020
        CPW       DADDR,B0
        JRNV      IN_WINDOW
        SETF      2,0,0               ;
        MOVI      CONTROL+6,A0        ;Pointer to window mode bits
        SUBK      3,A0                ;Check if windowing bits both set
        JRNZ      IN_WINDOW      
        CLRC                          ;Temporary fix for bug in silicon
        CLIP
        JRZ       EXIT                ;Jump if rect outside window
IN_WINDOW:
        GETPS     B0                  ;get pixel size
        RMO       B0,B0               ;binary log of psize
        NEG       B0                  ;prepare for shift
        MOVK      32,B1
        SRL       B0,B1               ;32/(2**binary log of psize)=pix's/wrd
        SUBK      1,B1                ;so the complement will count pix's/wrd
        MOVE      B2,B12              
        ANDN      B1,B12              ;pix adr now rounded to pix's/word bndry
        NEG       B12                 ;shift count = -(5 LSBs of x)
        RL        B12,B10             ;rotate pattern to offset '20 alignment
        MOVE      B10,B13             ;load aligned pattern
        PFILL     XY
EXIT:
        .endif
;
        MMFM      SP,B0,B1,B7
        MMFM      SP,A0,A1,A2         ;restore registers
        RETS      0                   ;return

        .end

