;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;        Copyright (c) 1987-1990  Texas Instruments Incorporated.         ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Extension                                     ;
;-------------------------------------------------------------------------;
;                                                                         ;
;  Bitblt                                                                 ;
;                                                                         ;
;  Bitblt a rectangle from a source bitmap to a destination bitmap.       ;
;  The source and destination bitmaps must already be setup prior         ;
;  to calling this function by using the set_srcbm() and set_dstbm        ;
;  functions.                                                             ;
;                                                                         ;
;  Notes:                                                                 ;
;                                                                         ;
;  If the source and destination bitmaps are different pixel sizes, one   ;
;  of the bitmaps must be mono (1 bit per pixel) and the other color.     ;
;                                                                         ;
;  There are 2 possible cases:                                            ;
;                                                                         ;
;       Case 1: SRC=Mono, Dst=Color. In this case a bitblt with expand    ;
;               is performed. Pixels with value 1 are expanded to the     ;
;               value contained in COLOR1, and 0 pixels using COLOR0.     ;
;                                                                         ;
;       Case 2: SRC=Color, Dst=Mono. In this case a bitblt with shrink    ;
;               is performed. Source pixels which match the value in      ;
;               COLOR0 will be mapped to 0s in the destination bitmap.    ;
;               All others will be mapped to 1s.                          ;
;                                                                         ;
;  The clipping rectangle not valid during a shrink operation, or when    ;
;  the destination bitmap is not the screen.                              ;
;                                                                         ;
;  Usage: bitblt(wt, ht, sx, sy, dx, dy);                                 ;
;-------------------------------------------------------------------------;
;  12/15/87  Original Version Written                       J.G.Littleton ;
;  07/16/88  Added TIGA direct mode                         Graham Short  ;
;  09/07/88  Access globals thru env struct                 W.S.Egr       ;
;  12/05/88  NULL bitmap struct ptr now indicates screen    JGL           ;
;  01/05/89  Added clipping if DST bitmap screen            JGL           ;
;  09/05/89  Fixed clipping when screen sx is negative      JGL           ;
;  09/21/89  Added preclipping of dstbm to the window       Graham Short  ;
;-------------------------------------------------------------------------;
        .include   gspreg.inc
        .include   gsptypes.inc
        .include   gspglobs.inc
        .mlib      gspmac.lib

;  Global Definitions
        .globl  _dm_bitblt, _bitblt

;  Register Usage
Rsptr   .set    A0
Rtmp    .set    A1
Rsaddr  .set    A2
Rdaddr  .set    A3
Rsptch  .set    A4
Rdptch  .set    A5
Rspix   .set    A6
Rdpix   .set    A7
Rsave   .set    A9
Rsave2  .set    A10
Rsave3  .set    A11
Rdptr   .set    A12

WV_MASK .set    0800h   ; Mask for EV bit in INTPEND/INTENA

;
; DIRECT MODE ENTRY POINT
;
_dm_bitblt:
        mmtm    SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A10,A11,A12    
        mmtm    SP,B0,B1,B2,B3,B7
        Popc    A8                      ;pop Ptr to args
;------------------------------------------------------------------------;
;  Get bitblt parameters into registers, extent, src and dst origin      ;
;------------------------------------------------------------------------;
        move    A8,B10                  ;need pointer in B-file
        move    *B10+,DYDX,1            ;Ht:Wt extent
        move    B10,A8                  ;need pointer in A-file
        move    *A8+,Rsaddr,1           ;SrcY:SrcX
        move    *A8,Rdaddr,1            ;DstY:DstX
        jruc    common_ep
;
;   C-PACKET ENTRY POINT
;
_bitblt:
        mmtm    SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A10,A11,A12
        mmtm    SP,B0,B1,B2,B3,B7
;------------------------------------------------------------------------;
;  Get bitblt parameters into registers, extent, src and dst origin      ;
;------------------------------------------------------------------------;
        move    STK,B10
        move    *-B10,DYDX,1            ;pop Wt
        move    *-B10,B11,1             ;pop Ht
        move    B10,STK
        sll     16,B11                  
        movy    B11,DYDX                ;Ht:Wt
        Popc    Rsaddr                  ;pop SrcX
        Popc    A8                      ;pop SrcY
        sll     16,A8                   
        movy    A8,Rsaddr               ;SrcY:SrcX
        Popc    Rdaddr                  ;pop DstX
        Popc    A8                      ;pop DstY
        sll     16,A8                   
        movy    A8,Rdaddr               ;DstY:DstX
;
; 2 ENTRY POINTS JOIN UP HERE
;
common_ep:
        setf    16,0,0
        move    @CONTROL,Rsave,0        ;save CONTROL
        move    @PSIZE,Rsave2,0         ;save PSIZE
        move    @CONVSP,A8,0            ;save CONVSP...
        sll     16,A8
        movy    A8,Rsave2               ;...in MS 16 bits of Rsave2
        move    @INTENB,Rsave3,0        ;save INTENB
;------------------------------------------------------------------------;
;  Preclip destination bitmap to the window using window option 1        ;
;------------------------------------------------------------------------;
        move    @(_env+ENVIRONMENT_DSTBM),Rdptr,1
        jrnz    no_preclip_dst
        move    @(_env+ENVIRONMENT_XYORIGIN),A8,1
        addxy   A8,Rdaddr
        move    Rdaddr,DADDR
        setf    2,0,0
        move    @CONTROL+6,A8           ; check if preclipping required
        jrz     no_preclip_dst
        movk    1,A8
        move    A8,@CONTROL+6           ; set window option 1
        setf    1,0,0
        clrs    A8
        move    A8,@INTENB+11           ; clear the Window violation enable bit        
        setf    16,0,0
        fill    xy                      ; adjust DADDR and DYDX
        jrv     exit_bitblt             ; check for dest. array outside window
        clrs    A8
        move    A8,@INTPEND+11          ; clear the Window violation pending bit        
        move    Rsave3,@INTENB,0        ; restore interrupt enable
        move    Rsave,@CONTROL,0        ; restore window option        
        move    DADDR,A8                ; determine adjust amount 
        subxy   Rdaddr,A8               
        addxy   A8,Rsaddr               ; adjust source array by adjust amount
        move    DADDR,Rdaddr            ; restore X-Y format for dest. addr
no_preclip_dst:
        setf    16,0,0
;------------------------------------------------------------------------;
;  Preclip source bitmap for negative X (bug in cvxyl)                   ;
;------------------------------------------------------------------------;
        move    @(_env+ENVIRONMENT_SRCBM),Rsptr,1
        jrnz    no_preclip_src
        move    @(_env+ENVIRONMENT_XYORIGIN),A8,1
        addxy   A8,Rsaddr
        move    Rsaddr,A8
        sext    A8,0
        jrnn    no_preclip_src
preclip_src:
        neg     A8
        addxy   A8,Rsaddr               ;adjust Rsaddr(X) to zero 
        addxy   A8,Rdaddr               ;adjust Rdaddr(X)
        move    A8,B10
        subxy   B10,DYDX                ;reduce X extent accordingly
        jrxle   exit_bitblt             
no_preclip_src:
;------------------------------------------------------------------------;
;  Setup Src Bitmap parameters                                           ;
;------------------------------------------------------------------------;
        move    Rsptr,Rsptr
        jrz     src_is_screen
src_linear:
        move    *Rsptr(BITMAP_PITCH),Rsptch,0
        move    Rsaddr,Rtmp
        srl     16,Rtmp                 ;0:SrcY
        mpyu    Rsptch,Rtmp             ;SrcY * SPTCH
        move    *Rsptr(BITMAP_PSIZE),Rspix,0
        move    Rspix,A8
        zext    Rsaddr,0                ;0:SrcX
        lmo     A8,A8
        subk    31,A8
        neg     A8
        sll     A8,Rsaddr               ;SrcX * PSIZE
        add     Rtmp,Rsaddr
        move    *Rsptr(BITMAP_ADDR),A8,1
        add     A8,Rsaddr
        jruc    src_set
src_is_screen:
        move    Rsaddr,SADDR            ;move XY format of source address into SADDR
        move    @PSIZE,Rspix,0
        move    DPTCH,Rsptch
        cvxyl   Rsaddr,Rsaddr           ;make linear format of source address in Rsaddr
src_set:
;------------------------------------------------------------------------;
;  Setup DST Bitmap parameters                                           ;
;------------------------------------------------------------------------;
        move    Rdptr,Rdptr
        jrz     dst_is_screen
dst_linear:
        move    *Rdptr(BITMAP_PITCH),Rdptch,0
        move    Rdaddr,Rtmp             ;DstY:DstX
        srl     16,Rtmp                 ;0:DstY
        mpyu    Rdptch,Rtmp             ;DstY * DPTCH
        zext    Rdaddr,0                ;0:DstX
        move    *Rdptr(BITMAP_PSIZE),Rdpix,0
        move    Rdpix,A8
        lmo     A8,A8
        subk    31,A8
        neg     A8
        sll     A8,Rdaddr               ;DstX * PSIZE
        add     Rtmp,Rdaddr
        move    *Rdptr(BITMAP_ADDR),A8,1
        add     A8,Rdaddr               ;add bitmap offset
        jruc    dst_set
dst_is_screen:
        move    Rdaddr,DADDR            ;move XY format of dest. address into DADDR
        move    @PSIZE,Rdpix,0
        move    DPTCH,Rdptch
        cvxyl   Rdaddr,Rdaddr           ;make linear format of dest. address in Rdaddr
        move    @(_env+ENVIRONMENT_SRCBM),Rtmp,1 ;get ptr to source bitmap
        jrz     scrn_to_scrn
dst_set:
;------------------------------------------------------------------------;
;  Both source and destination bitmaps are setup. Now check for          ;
;  cases where the bitmaps are different pixel sizes. There are          ;
;  3 possible cases:                                                     ;
;                   src == dst                                           ;
;                   src >  dst  (munge)                                  ;
;                   src <  dst  (expand)                                 ;
;------------------------------------------------------------------------;
        cmp     Rspix,Rdpix
        jrz     src_eq_dst
        jrnn    src_lt_dst
;------------------------------------------------------------------------;
;  SRC > DST                                                             ;
;------------------------------------------------------------------------;
src_gt_dst:
        move   DYDX,A8
        zext   DYDX,0
        move   DYDX,Rtmp
        srl    16,A8                    ;Y extent counter
;
;  Read Color SRC with FS1, Write Mono DST with FS0                         
;
        exgf   Rspix,1                  ;field 1 to src pixel size
        move   COLOR0,B10
        zext   B10,1                    ;isolate 1 pixel
        setf   1,0,0
munge_loop:
        move   Rsaddr,SADDR
        move   Rdaddr,DADDR
        move   Rtmp,DYDX
munge_hline:
        move   *SADDR+,B11,1         ;read color pixel
        xor    B10,B11               ;if (equal to COLOR0)
        jrz    set_munged            ;  shrink to 0
        movk   1,B11                 ;else shrink to 1
set_munged:
        move   B11,*DADDR+,0         ;write mono pixel
        dsjs   DYDX,munge_hline      
        add    Rsptch,Rsaddr
        add    Rdptch,Rdaddr
        dsjs   A8,munge_loop
        exgf   Rspix,1               ;restore FS1
        setf   16,0,0                ;restore FS0
        jruc   exit_bitblt
;------------------------------------------------------------------------;
;  SRC == DST                                                            ;
;------------------------------------------------------------------------;
src_eq_dst:
        move    Rdpix,@PSIZE,0
        move    Rsptch,SPTCH
        move    Rdptch,DPTCH
        move    Rsaddr,SADDR
;------------------------------------------------------------------------;
; If either the source or destination pitch is not a multiple of 16,     ;
; then the bitblt will have to be handled a line at time.                ;
;------------------------------------------------------------------------;
        move    Rsptch,A8
        andi    0Fh,A8
        jrnz    sed_badpitch
        move    Rdptch,A8
        andi    0Fh,A8
        jrnz    sed_badpitch
;------------------------------------------------------------------------;
;  Bitmap pitches are multiples of 16, perform the bitblt                ;
;  all at once.                                                          ;
;------------------------------------------------------------------------;
        move    Rdptr,Rdptr
        jrnz    sed_dlinear
        pixblt  L,XY       
        jruc    exit_bitblt 
sed_dlinear:        
        move    Rdaddr,DADDR
        pixblt  L,L
        jruc    exit_bitblt
sed_badpitch:
        move    Rdaddr,DADDR
        move    DYDX,A8
        zext    DYDX,0
        ori     [1,0],DYDX
        srl     16,A8             ;Y extent counter
sed_loop:
        move    Rsaddr,SADDR
        move    Rdaddr,DADDR
        pixblt  L,L
        add     Rsptch,Rsaddr
        add     Rdptch,Rdaddr
        dsjs    A8,sed_loop
        jruc    exit_bitblt
;------------------------------------------------------------------------;
;  SRC < DST                                                             ;
;------------------------------------------------------------------------;
src_lt_dst:
        move    Rdpix,@PSIZE,0
        move    Rsptch,SPTCH
        move    Rdptch,DPTCH
        move    Rsaddr,SADDR
;
        move    Rdptch,A8
        andi    0Fh,A8
        jrnz    sld_badpitch
;
        move    Rdptr,Rdptr
        jrnz    sld_dlinear
        pixblt  B,XY
        jruc    exit_bitblt
sld_dlinear:
        move    Rdaddr,DADDR
        pixblt  B,L
        jruc    exit_bitblt
sld_badpitch:
        move    DYDX,A8
        zext    DYDX,0
        ori     010000h,DYDX
        srl     16,A8                   ;Y extent counter
sld_loop:
        move    Rsaddr,SADDR
        move    Rdaddr,DADDR
        pixblt  B,L
        add     Rsptch,Rsaddr
        add     Rdptch,Rdaddr
        dsjs    A8,sld_loop
        jruc    exit_bitblt
;------------------------------------------------------------------------;
;  Special case where both source and destination bitmaps are            ;
;  the screen. Handle overlapping bitmaps in this case.                  ;
;------------------------------------------------------------------------;
scrn_to_scrn:
        move    DPTCH,SPTCH
        move    @CONVDP,@CONVSP,0
;------------------------------------------------------------------------;
;  If the source and destination bitmaps overlap, adjust                 ;
;  the transfer direction accordingly.                                   ;
;------------------------------------------------------------------------;
        move    @CONTROL,A8,0
        andni   (PBV_MASK | PBH_MASK),A8 ;kill direction
        cmpxy   SADDR,DADDR
        jryn    vdir_set
        ori     PBV_MASK,A8
vdir_set:
        cmpxy   SADDR,DADDR
        jrxn    hdir_set
        ori     PBH_MASK,A8
hdir_set:
        move    A8,@CONTROL,0
        move    *A8,A8,0                ;allow piped write to complete
        pixblt  XY,XY
exit_bitblt:
        move    Rsave,@CONTROL,0
        move    Rsave2,@PSIZE,0
        srl     16,Rsave2
        move    Rsave2,@CONVSP,0
        move    Rsave3,@INTENB,0
        mmfm    SP,B0,B1,B2,B3,B7
        mmfm    SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A10,A11,A12    
        rets    2
