;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;        Copyright (c) 1986-1990  Texas Instruments Incorporated.         ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Extension                                     ;
;-------------------------------------------------------------------------;
; patnfill_rect function                                                  ;
;                                                                         ;
;   Draw pattern-filled rectangle given the coordinates at the top left   ;
;   corner of the rectangle, and the width w and height h of the          ;
;   rectangle.  The interior of the rectangle is filled with the current  ;
;   pattern in the current colors 0 and 1.                                ;
;-------------------------------------------------------------------------;
; Usage:  patnfill_rect(w, h, xleft, ytop);                               ;
;                                                                         ;
; Description of stack arguments:                                         ;
;   int w, h;         /* width and height of rectangle */                 ;
;   int xleft, ytop;  /* coordinates at top left of rectangle */          ;
;                                                                         ;
; Returned in register A8:  Void (undefined).                             ;
;                                                                         ;
; Registers altered:  A8                                                  ;
;-------------------------------------------------------------------------;
; Revision history:                                                       ;
;   2/ 4/86...Original version written...................Jerry Van Aken   ;
;   5/12/86...Added TI copyright notice..................JV               ;
;   3/06.87...Modified to use W=01 mode preclip..........JV               ;
;   4/22/87...Eliminated I/O register write hazard.......JV               ;
;  07/12/88...Added TIGA direct mode and dstbm check.....W.S.Egr          ;
;  09/09/88...Access globals thru environment struct.....W.S.Egr          ;
;   7/14/89...Added 34020 support........................A. Sharp         ;
;   8/21/89...Simplified 34020 inner loop per JVA........A. Sharp         ;
;-------------------------------------------------------------------------;
;
        .title    'pattern rectangle'
        .file     'patnrect.asm'
        .include  gsptypes.inc          ;offsets into environment struct
        .include  gspglobs.inc          
        .include  gspreg.inc
        .include  oem.inc
;
;     DECLARE GLOBAL FUNCTION NAME
;
        .globl    _patnfill_rect
        .globl    _dm_patnfill_rect
;
;    DIRECT-MODE ENTRY POINT
;
_dm_patnfill_rect:
        MMTM      SP,A0,A1,A2,A3,A4,A5,A6,A7,A9;Save A-file registers
        MMTM      SP,B0,B1,B2,B5,B6,B7,B10,B11,B12,B13,B14
        move      -*A14,A8,1          ;get dm-data area address
        move      A8,B10              ;address dm-data stack from b-file
        move      *B10+,DYDX,1        ;1st dword parm is height::width
        move      *B10,DADDR,1        ;2nd dword parm is ytop::xleft
        jruc      common_ep
;
;    C-PACKET ENTRY POINT
;
_patnfill_rect:
* Save registers
        MMTM      SP,A0,A1,A2,A3,A4,A5,A6,A7,A9 ;Save A-file registers
        MMTM      SP,B0,B1,B2,B5,B6,B7,B10,B11,B12,B13,B14
* Pop the the arguments from the stack.
        MOVE      STK,B14             ;
        MOVE      *-B14,DYDX,1        ;Pop w
        MOVE      *-B14,B10,1         ;Pop h
        MOVE      *-B14,DADDR,1       ;Pop xleft
        MOVE      *-B14,B11,1         ;Pop ytop
        MOVE      B14,STK             ;
        SLL       16,B10              ;
        MOVY      B10,DYDX            ;Concatenate w, h
        SLL       16,B11              ;
        MOVY      B11,DADDR           ;Concatenate xleft, ytop
;
;    2 ENTRY POINTS JOIN UP HERE
;
common_ep:
;
;    Check for destination bitmap pointing to the screen.  If not, abort for
;    now.  Linear drawing capability will be added at a later time.
;
        move      @(_env+ENVIRONMENT_DSTBM),A8,1        ;destination bit-map global variable
        jrnz      EXIT                ;if zero, dstbm is set to screen
        .if     GSP_34010 ; Code used if the processor is a 34010
* Set window to intersection of fill rectangle and clipping rectangle.
        SETF      2,0,0               ;
        MOVI      CONTROL+6,A0        ;Pointer to window mode bits
        MOVE      *A0,A1,0            ;Save window mode bits
        MOVK      1,A4                ;
        MOVE      A4,*A0,0            ;Set window mode W = 1
        MOVE      @(_env+ENVIRONMENT_XYORIGIN),B10,1    ;Viewport origin displacement
        ADDXY     B10,DADDR           ;Convert to screen coord's
        FILL      XY                  ;Preclip fill rect to window
        MOVE      A1,*A0,0            ;Restore window mode bits
        JRV       EXIT                ;Jump if rect outside window
        MOVE      DADDR,WSTART        ;Set window to clipped rect
        MOVE      DADDR,WEND          ;
        ADDXY     DYDX,WEND           ;
        MOVI      010001h,B10         ;
        SUBXY     B10,WEND            ;
* Set start address to top left corner of 1st pattern cell.
        MOVE      B10,B7              ;
        SLL       4,B7                ;DX = DY = 16
        MOVE      B7,B12              ;
        SUBXY     B10,B12             ;Mask: x = y = 15
        ANDN      B12,DADDR           ;Truncate to cell boundary
        MOVE      DADDR,A0            ;Copy start address
* Calculate cell counts in x and y directions.
        MOVE      WEND,B11            ;
        ANDN      B12,B11             ;Truncate to cell boundary
        SUBXY     DADDR,B11           ;
        SRL       4,B11               ;pixel count --> cell count
        ADDXY     B10,B11             ;
        MOVE      B11,A1              ;
        SETF      16,0,0              ;
        ZEXT      A1,0                ;isolate xcount
        MOVE      B11,A2              ;
        SRL       16,A2               ;isolate ycount
* Set up x and y increments for pattern fill.
        MOVK      010h,A3             ;x increment = 16
        SLL       20,A4               ;y increment = 16
* Set up pitch and source pointer for bit pattern.
        MOVK      16,SPTCH            ;pitch of bit pattern
        LMO       SPTCH,B10           ;
        MOVE      @CONVSP,A8,0        ;save copy of CONVSP
        MOVE      B10,@CONVSP,0       ;set CONVSP for bit pattern
        MOVE      @(_pattern+PATTERN_DATA),A6,1 ;load address of bit pattern
* Fill specified rectangle with bit pattern expanded to colors 0 and 1
        MOVE      A0,A5               ;initialize dest'n pointer
        MOVE      A1,A7               ;initialize xcount
LOOP:
        MOVE      A5,DADDR            ;update current dest'n addr
        MOVE      A6,SADDR            ;update current source addr
        PIXBLT    B,XY                ;draw 16x16 pixels of pattern
        ADDXY     A3,A5               ;move 16 pixels to right
        DSJS      A7,LOOP             ;if --xcount > 0, loop again
        MOVE      A1,A7               ;re-initialize xcount
        ADDXY     A4,A0               ;move down 16 pixels
        MOVE      A0,A5               ;init pointer for next row
        DSJS      A2,LOOP             ;if --ycount > 0, loop again
        MOVE      A8,@CONVSP,0        ;Restore CONVSP register
        .endif
;
        .if     GSP_34020 ; Code used if the processor is a 34020
        MOVE      @(_env+ENVIRONMENT_XYORIGIN),B10,1    ;Viewport origin displacement
        ADDXY     B10,DADDR           ;Convert to screen coord's
        SETF      2,0,0               ;
        MOVI      CONTROL+6,A0        ;Pointer to window mode bits
        SUBK      3,A0                ;Check if windowing bits both set
        JRNZ      NO_CLIP        
        CLRC                          ;Temporary fix for bug in silicon
        CLIP
        JRZ       EXIT                ;Jump if rect outside window
NO_CLIP:
        SETF      16,0,0              ;
* Set up y count
        MOVE      DYDX,A1
        MOVE      A1,A2
        SRL       16,A1
        MOVI      00010000H,A0
        MOVY      A0,A2
        MOVE      A2,DYDX
        MOVE      DADDR,A2
* Calculate pattern adjustment
        GETPS     B0         
        RMO       B0,B0
        NEG       B0
        MOVK      32,B1
        SRL       B0,B1               ;number pixels per 32 bit word
        SUBK      1,B1                ;so complement will count pix's/wrd
        MOVE      DADDR,B0            ;
        ANDN      B1,B0               ;address rounded to pix's/word bndry
        NEG       B0                  ;shift count = -(LSBs of x)
* Copy current row of pattern to register.
        MOVE      @(_pattern+PATTERN_DATA),A9,1    ;copy pattern start address
LOOP:
        MOVE      A9,B10              ;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
        RL        B0,B10              ;align pattern for x address
        MOVE      B10,B13             ;load aligned pattern
        PFILL     XY
        ADDXY     A0,A2
        MOVE      A2,DADDR
        DSJ       A1,LOOP
        .endif

* All done.  Restore registers and return
EXIT:
        MMFM      SP,B0,B1,B2,B5,B6,B7,B10,B11,B12,B13,B14
        MMFM      SP,A0,A1,A2,A3,A4,A5,A6,A7,A9 ;Restore A-file registers
        RETS      2                   ;Return
        .end
