;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;        Copyright (c) 1988-1990  Texas Instruments Incorporated.         ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Core                                          ;
;-------------------------------------------------------------------------;
;   void set_clip_rect(w, h, xleft, ytop)				  ;
;   unsigned short w, h;     /* width and height of window */		  ;
;   short xleft, ytop;	     /* top left corner of window */		  ;
;                                                                         ;
;   This function sets window start (B5) and window end (B6) registers    ;
;   to the dimensions specified by the passed parameters.  Coordinates	  ;
;   xleft and ytop are specified relative to the current drawing origin.  ;
;-------------------------------------------------------------------------;
; Revision history:                                                       ;
;  10/23/88...Original version written......................Graham Short  ;
;  01/10/89...Modified name/parms to match math/grafix......W.S.Egr       ;
;  03/06/89...Fixed bug in WEND being set 1 pixel too big...Graham Short  ;
;  02/15/90...Limit clip window to boundaries of screen.....J.R. Van Aken ;
;-------------------------------------------------------------------------;
;
        .title    'set clipping rectangle'
        .file     'setclip.asm'
;
        include   gsptypes.inc 
        include   gspglobs.inc            
	include   gspreg.inc
;
;   DECLARE GLOBAL FUNCTION NAMES
;
        .globl    _set_clip_rect
        .globl    _dm_set_clip_rect
;
;
;   DIRECT-MODE ENTRY POINT
;
_dm_set_clip_rect:

        MOVE      B0,*-SP,1           ;save register
        MOVE      STK,B0              ;copy program stack pointer
	MOVE	  *-B0,B0,1	      ;get pointer to arg buffer
	MOVE	  *B0+,WEND,1	      ;WEND = h::w
	MOVE	  *B0,WSTART,1	      ;WSTART = ytop::xleft
        JR        COMMON_EP
;
;
;   C-PACKET ENTRY POINT
;
_set_clip_rect:

        MOVE      B0,*-SP,1           ;save register
	MOVE	  *-STK,A8,1	      ;get width w
        MOVE      A8,WEND             ;put width into WEND
	MOVE	  *-STK,A8,1	      ;get height h
        MOVE      A8,B0               ;
	SLL	  16,B0 	      ;move h into y half
	MOVY	  B0,WEND	      ;WEND = h::w
        MOVE      *-STK,A8,1          ;get xleft
        MOVE      A8,WSTART           ;put xleft into WSTART
        MOVE      *-STK,A8,1          ;get ytop
        MOVE      A8,B0               ;
	SLL	  16,B0 	      ;move ytop into y half
        MOVY      B0,WSTART           ;WSTART = ytop::xleft
;
;
;   COMMON ENTRY POINT
;
COMMON_EP:

        MOVE      @(_env+ENVIRONMENT_XYORIGIN),B0,1 ;drawing origin
        ADDXY     B0,WSTART           ;convert xleft, ytop
        ADDXY     WSTART,WEND         ;ytop+h::xleft+w
; Make sure clip window does not extend past right edge of screen.
        SETF      16,0,0
	MOVE	  @(_config+CONFIG_DISP_HRES),B0,0 ;screen width
	CMPXY	  WEND,B0	      ;is xleft+w > hres ?
	JRXNN	  RIGHT_OK	      ;jump if xleft+w <= hres
	MOVX	  B0,WEND	      ;stop window at right edge
RIGHT_OK:
; Make sure clip window does not extend past bottom edge of screen.
	MOVE	  @(_config+CONFIG_DISP_VRES),B0,0 ;screen height
	SLL	  16,B0 	      ;move vres into y half
	CMPXY	  WEND,B0	      ;is ytop+h > vres ?
	JRYNN	  BOT_OK	      ;jump if ytop+h <= vres
        MOVY      B0,WEND             ;stop window at bottom edge
BOT_OK:
; Make sure clip window does not extend past left edge of screen.
        CLR       B0                  ;x::y = 0::0
	CMPXY	  B0,WSTART	      ;is xleft < 0 or ytop < 0 ?
        JRXNN     LEFT_OK             ;jump if xleft >= 0
        MOVX      B0,WSTART           ;stop window at left edge
LEFT_OK:
; Make sure clip window does not extend past top edge of screen.
        JRYNN     TOP_OK              ;jump if ytop >= 0
        MOVY      B0,WSTART           ;stop window at top edge
TOP_OK:
	NOT	  B0		      ;x::y = -1::-1
        ADDXY     B0,WEND             ;make final WEND adjustment
; Restore registers and return.
        MOVE      *SP+,B0,1           ;restore register
        MOVE      *SP(32),STK,1       ;restore program stack pointer
        RETS      2                   ;
        .end

