        .width    132
;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;          Copyright (c) 1990  Texas Instruments Incorporated.            ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Core                                          ;
;-------------------------------------------------------------------------;
; clear_frame_buffer function						  ;
;									  ;
;   This routine is hardware-specific to the TMS34010 TIGA Development	  ;
;   Board (TDB10).  It works with the TDB10 configured with either one	  ;
;   or two banks of VRAM.  Only the first 3/4 of each VRAM (rows 0-383)   ;
;   are cleared (or filled) by this function.  The last 1/4 (rows 384-	  ;
;   511) are assumed to be mapped into the top of memory.		  ;
;									  ;
;   This function uses VRAM serial-register transfers to rapidly fill	  ;
;   the entire frame buffer with the pixel value specified in the	  ;
;   argument.  If the argument is -1, the frame buffer is filled with	  ;
;   the current background color (in COLOR0).				  ;
;									  ;
;   When the TDB10 is configured with a single bank of VRAM, the 9-bit	  ;
;   row address output to the 256Kx4 VRAMs consists of TMS34010 logical   ;
;   address bits 13-21.  When configured with two banks of VRAM, the	  ;
;   9-bit column address consists of logical address bits 14-22; the	  ;
;   decode logic responds to the TR- signal output on the 34010's LAD14   ;
;   pin by broadcasting the row address to both banks.	Logical address   ;
;   bit 4, the VRAM bank-select bit, is ignored.			  ;
;									  ;
;-------------------------------------------------------------------------;
; Usage:  clear_frame_buffer(val);					  ;
;                                                                         ;
; Description of stack arguments:                                         ;
;   unsigned long val;	    /* non-replicated pixel value */		  ;
;                                                                         ;
; Returned in register A8:  void (undefined).				  ;
;                                                                         ;
; Registers altered:  A8                                                  ;
;-------------------------------------------------------------------------;
; Revision history:                                                       ;
;   04/04/90...Original version written...................Jerry Van Aken  ;
;   09/14/90...Modified to handle both 1 and 2 banks......Jerry Van Aken  ;
;-------------------------------------------------------------------------;
;
        .title    'clear frame buffer'
        .file     'clearfrm.asm'
;
;     DECLARE GLOBAL FUNCTION NAME
;
        .def      _clear_frame_buffer
	.def	  _dm_clear_frame_buffer
;
;
;     DEFINE CONSTANTS
;
        .nolist
        .copy     gspreg.inc          ;define 34010 register names
        .list
; Define video memory parameters.
VRAM_START .set   010000000h	      ;TDB VRAM start address
VRAM1BIT   .set   0C0002011h	      ;CR1 bit 1 (1=VRAM1 present)
; Assign names to several A- and B-file registers.
Rsave1	.set	  A0		      ;save original PSIZE register
Rsave2	.set	  A1		      ;save original DPYCTL register
Rsave3	.set	  A8		      ;save original PMASK register
Rsave4	.set	  A14		      ;save original CONTROL register
Rtemp   .set      B14                 ;temporary register
;
;
;    TIGA DIRECT-MODE ENTRY POINT
;
_dm_clear_frame_buffer:

        MOVE      -*A14,A8,1          ;get dm-data area address
	MOVE	  *A8,A8,1	      ;get 32-bit val arg
        JR        COMMON_EP
;
;
;    C-PACKET ENTRY POINT
;
_clear_frame_buffer:

	MOVE	  *-A14,A8,1	      ;pop 32-bit val arg
;
;
;    2 ENTRY POINTS JOIN UP HERE
;
COMMON_EP:
        MMTM      SP,A0,A1            ;save registers
        MMTM      SP,B2,B3,B7,B9,B10,B11,B12,B13,B14
	MOVE	  A8,COLOR1	      ;copy argument val
;
; If argument val is -1, use current COLOR0 as default fill color.
	INC	  A8		      ;test for val = -1
	JRNZ	  NOTDEFAULT	      ;jump if val != -1
	MOVE	  COLOR0,COLOR1       ;use current background color
NOTDEFAULT:
;
; Save the following 34010 registers:  PSIZE, PMASK, DPYCTL and CONTROL.
        SETF      16,0,0              ;
        MOVE      @PSIZE,Rsave1,0     ;save pixel size
        MOVE      @DPYCTL,Rsave2,0    ;save display control
        MOVE      @PMASK,Rsave3,0     ;save plane mask
        SETF      10,0,0              ;
        MOVE      @CONTROL+5,Rsave4,0 ;save PPOP and transparency
;
; Load PMASK and CONTROL with bulk clear values.
        CLR       Rtemp               ;
        MOVE      Rtemp,@CONTROL+5,0  ;set PPOP = replace, transp. on
        SETF      16,0,0              ;
	MOVE	  Rtemp,@PMASK,0      ;write-enable all planes
;
; TDB Card supports pixel sizes 1, 2, 4 and 8 (but not 16) bits.
; Replicate pixel value throughout 16 LSBs of 34010's COLOR1 register.
	CMP	  COLOR0,COLOR1       ;use background as default color?
	JREQ	  DEFAULT	      ;if so, jump
	MOVE	  Rsave1,B10	      ;copy original pixel size
        EXGF      B10,0               ;set field 0 size = pixel size
        ZEXT      COLOR1,0            ;zero bits to left of pixel
	MOVE	  Rsave1,B10	      ;copy pixel size again
        LMO       B10,B11             ;log2(pixel size)
        SUBK      27,B11              ;initialize loop count
LOOP:
        MOVE      COLOR1,B12          ;copy n pixels
        SLL       B10,B12             ;make n more pixels
        OR        B12,COLOR1          ;concatenate 2n pixels
        ADD       B10,B10             ;double shift count
	DSJS	  B11,LOOP	      ;double pixels again?
DEFAULT:
;
; Replicate pixel value throughout first row of all 4 (1 bank) or 8
; (2 banks) 256Kx4 VRAMs.  Model VRAM as 512x384 (1 bank) or 1024x384
; (2 banks) frame buffer with pixel depth of 16 bits.
	MOVI	  VRAM_START,DADDR    ;load TDB's VRAM base address
	MOVK	  1,DYDX	      ;
	SLL	  16,DYDX	      ;fill region is 1 pixel high
	MOVI	  512,DPTCH	      ;frame buffer width = 512 pixels
	SETF	  1,0,0 	      ;
	MOVE	  @VRAM1BIT,Rtemp,0   ;are there 1 or 2 banks of VRAM?
	SLL	  Rtemp,DPTCH	      ;if 2 banks, 1024 pixels/row
	MOVX	  DPTCH,DYDX	      ;width of fill region in pixels
	SLL	  4,DPTCH	      ;pitch = width*(16 bits/pixel)
	MOVK	  16,Rtemp	      ;frame buffer depth = 16 bits
        SETF      16,0,0              ;
	MOVE	  Rtemp,@PSIZE,0      ;specify pixel size as 16 bits
	MOVE	  *Rtemp,Rtemp,0      ;read junk to ensure valid PSIZE
        FILL      L                   ;fill VRAM row 0 with pixel value
;
; Within each VRAM, transfer row 0 into four 512-bit serial registers.
; Note that the value "read" by the PIXT below is a "don't care".
        CLR       DADDR               ;source address (point to row 0)
        MOVI      06800h,Rtemp        ;turn off screen refresh and...
	MOVE	  Rtemp,@DPYCTL,0     ;...enable serial-register cycles
	MOVE	  *Rtemp,Rtemp,0      ;read junk to ensure valid DPYCTL
        PIXT      *DADDR,Rtemp        ;"read" is VRAM mem-to-reg cycle
;
; Now copy serial registers into rows 1 thru 383 of all VRAMs.
; Note that the color "written" by the FILL below is a "don't care".
	MOVE	  DPTCH,DADDR	      ;dest'n address (point to row 1)
	MOVI	  [383,1],DYDX	      ;1 SRT write for each of 383 rows
        FILL      L                   ;do 383 VRAM reg-to-mem cycles
;
; Bulk initialization of VRAM is complete.  Restore registers and return.
	MOVE	  Rsave1,@PSIZE,0     ;restore original pixel size
	MOVE	  Rsave2,@DPYCTL,0    ;restore original display control
	MOVE	  Rsave3,@PMASK,0     ;restore original plane mask
        SETF      10,0,0              ;
        MOVE      Rsave4,@CONTROL+5,0 ;restore PPOP and transparency
        MMFM      SP,B2,B3,B7,B9,B10,B11,B12,B13,B14
        MMFM      SP,A0,A1            ;
        MOVE      *SP(32),STK,1       ;restore C program stack pointer
        RETS      2                   ;
        .end

