        .width    132
;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;          Copyright (c) 1990  Texas Instruments Incorporated.            ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Core                                          ;
;-------------------------------------------------------------------------;
; clear_page 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.						  ;
;									  ;
;   This function uses VRAM serial-register transfers to rapidly fill	  ;
;   the current drawing page with the pixel value specified in the	  ;
;   argument.  If the argument is -1, the drawing page 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.			  ;
;									  ;
;   This routine initially calculates the number of rows of VRAM required ;
;   to contain the drawing page as					  ;
;	    nrows = DPTCH*(VSBLNK-VEBLNK)/(512*16)			  ;
;   which is the correct value as long as the display is noninterlaced	  ;
;   and only VRAM bank 0 is installed.	If the display is interlaced,	  ;
;   the routine corrects this value by doubling it.  If VRAM banks 0 and  ;
;   1 are both installed, the routine halves the value. 		  ;
;-------------------------------------------------------------------------;
; Usage:  clear_page(val);						  ;
;                                                                         ;
; Description of stack arguments:                                         ;
;   unsigned long val;	    /* non-replicated pixel value */		  ;
;                                                                         ;
; Returned in register A8:  void (undefined).				  ;
;                                                                         ;
; Registers altered:  A8                                                  ;
;-------------------------------------------------------------------------;
; Revision history:                                                       ;
;   05/03/90...Original version written...................Jerry Van Aken  ;
;   09/14/90...Modified to handle both 1 and 2 banks......Jerry Van Aken  ;
;-------------------------------------------------------------------------;
;
	.title	  'clear page'
	.file	  'clearpag.asm'
;
;     DECLARE GLOBAL FUNCTION NAME
;
	.def	  _clear_page
	.def	  _dm_clear_page
;
;
;     DEFINE CONSTANTS
;
        .nolist
        .copy     gspreg.inc          ;define 34010 register names
        .list
;Addresses of TDB Control Registers 0 and 1
TDBCR0	.set	  0C0002000h
TDBCR1	.set	  0C0002010h
; 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
Rcr1	.set	  B0		      ;TDB10 control register 1
Rtemp   .set      B14                 ;temporary register
;
;
;    TIGA DIRECT-MODE ENTRY POINT
;
_dm_clear_page:

	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_page:

	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,B0,B1,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
;
; Set up PMASK and CONTROL registers for VRAM bulk initialization.
        CLR       Rtemp               ;
        MOVE      Rtemp,@CONTROL+5,0  ;set PPOP = replace, transp. on
        SETF      16,0,0              ;
	MOVE	  Rtemp,@PMASK,0      ;write-enable all planes
;
; The 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 n+n pixels
        ADD       B10,B10             ;double shift count
	DSJS	  B11,LOOP	      ;double pixels again?
DEFAULT:
;
; Replicate pixel value throughout one row of all 256Kx4 VRAMs.
; This is the row containing the first scan line of the drawing page.
; Model VRAM as 512x512 (1 bank) or 1024x512 (2 banks) frame buffer
; with pixel depth of 16 bits.
	MOVE	  OFFSET,DADDR	      ;OFFSET is address of drawing page
	MOVE	  DPTCH,SPTCH	      ;save copy of screen pitch
	MOVK	  1,DYDX	      ;
	SLL	  16,DYDX	      ;fill region is 1 pixel high
	MOVI	  512,DPTCH	      ;frame buffer width = 512 pixels
	SETF	  16,0,0	      ;
	MOVE	  @TDBCR1,Rcr1,0      ;get TDB10 control register 1
	BTST	  1,Rcr1	      ;1 or 2 banks of VRAM?
	JRZ	  ONEBANK	      ;jump if 1 bank

	SLL	  1,DPTCH	      ;if 2 banks, 1024 pixels/row
ONEBANK:
	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
	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 the row containing the first scan line of
; the drawing page into the serial register.
; Note that the value "read" by the PIXT below is a "don't care".
	MOVE	  OFFSET,DADDR	      ;point to initial VRAM row
	SETF	  2,0,0 	      ;
	MOVK	  1,Rtemp	      ;turn off screen refresh and...
	MOVE	  Rtemp,@DPYCTL+11,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
;
; Calculate the number of scan lines contained in the drawing page.
	SETF	  16,0,0	      ;
	MOVE	  @VSBLNK10,DYDX,0    ;get vertical start blank value
	MOVE	  @VEBLNK10,Rtemp,0   ;get vertical end blank value
	SUB	  Rtemp,DYDX	      ;number of scan lines per page
;
; If display is interlaced, need to double scan lines per page.
	BTST	  14,Rsave2	      ;interlaced?
	JRNZ	  NILC		      ;jump if noninterlaced

	SLL	  1,DYDX	      ;double scan line count
NILC:
;
; If scan lines are doubled on monitor, need to halve scan lines/page.
	BTST	  7,Rcr1	      ;doubled?
	JRZ	  NOTDBL	      ;jump if lines not doubled

	SRL	  1,DYDX	      ;halve scan line count
NOTDBL:
;
; Determine number of rows in VRAM occupied by drawing page.
	LMO	  SPTCH,Rtemp	      ;get ~log2(screen pitch)
	NOT	  Rtemp 	      ;convert to left shift count
	SLL	  Rtemp,DYDX	      ;DPTCH*(HSBLNK-HEBLNK)=bits/page
	SRL	  9+4,DYDX	      ;no. of rows = (bits/page)/(512*16)
;
; If VRAM banks 0 and 1 both installed, need to halve # rows per page.
	BTST	  1,Rcr1	      ;1 or 2 banks of VRAM?
	JRZ	  NOT2BKS	      ;jump if 1 bank

	SRL	  1,DYDX	      ;if 2 banks, halve scan count
NOT2BKS:
;
; Now copy serial register into all VRAM rows that correspond to the
; area of the frame buffer occupied by the drawing page.
; Note that the color "written" by the FILL below is a "don't care".
	MOVE	  OFFSET,DADDR	      ;point to initial row in page
	SLL	  16,DYDX	      ;set DY = number of rows to clear
	INC	  DYDX		      ;set DX = 1 (1 word write per row)
	FILL	  L		      ;do lots of 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,B0,B1,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

