⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 circle.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	CIRCLE - iAPX 88/86 CIRCLE STATEMENT SUPPORT
;***
; CIRCLE - iAPX 88/86 CIRCLE STATEMENT SUPPORT
;
;	Copyright <C> 1986 - 1988, Microsoft Corporation
;
;Purpose:
;
; BASIC Syntax mapping to included runtime entry points:
;
; - CIRCLE Statement:
;
;      CIRCLE (x,y),r [,color [,start,end [,aspect]]]
;	 |	|
;	 |	|
;	 |    Coord routines B$CSTT B$CSTO B$CASP B$CIRC
;	 |						 |
;	 +-----------------------------------------------+
;
;******************************************************************************
	INCLUDE switch.inc
	INCLUDE rmacros.inc	; Runtime Macro Defintions
	INCLUDE const.inc	;constant definitions

	USESEG	CONST		
	USESEG	_DATA		
	USESEG	_BSS		
	USESEG	GR_TEXT 	

	INCLUDE seg.inc 	; Segment definitions
	INCLUDE idmac.inc	

sBegin	_BSS			
;
;****************************************************************************
; External low-level function vectors
;****************************************************************************
;
	externW b$MapXYC	
	externW b$SetPixFirstC	
	externW b$SetPixC	
	externW b$SetPixLastC	

	externW B$A_END		;defined in GWDATA.ASM
	externW B$A_START	;defined in GWDATA.ASM
	externW b$ASPECTR	;defined in GWDATA.ASM
	externW B$CSTCNT 	;defined in GWDATA.ASM
	externW B$CENCNT 	;defined in GWDATA.ASM
	externW B$CRCSUM 	;defined in GWDATA.ASM
	externB B$CPLOTF 	;defined in GWDATA.ASM
	externB B$CLINEF 	;defined in GWDATA.ASM
	externW B$CNPNTS 	;defined in GWDATA.ASM
	externW B$CPCNT		;defined in GWDATA.ASM
	externW B$CPCNT8 	;defined in GWDATA.ASM
	externB B$COPTFL 	;defined in GWDATA.ASM
	externW B$GX_OLD 	;defined in GWDATA.ASM
	externW B$GXPOS		;defined in GWDATA.ASM
	externW B$GRPACX 	;defined in GWDATA.ASM
	externW B$GRPACY 	;defined in GWDATA.ASM

	externQ B$LXDIF		; defined in GRFPINIT.ASM
	externB B$WNDWSW 	;defined in GWDATA.ASM


	externW B$VXMIN		;defined in GWDATA.ASM
	externW B$VYMIN		;defined in GWDATA.ASM
	externW B$VXMAX		;defined in GWDATA.ASM
	externW B$VYMAX		;defined in GWDATA.ASM
	externW B$CXOFF		;defined in GWDATA.ASM
	externW B$CYOFF		;defined in GWDATA.ASM

sEnd	_BSS			

sBegin	_DATA			

	externB B$CLIPF

sEnd	_DATA			

sBegin	CONST			

	externD b$FP_1 	; s.p. constant   1.0
	externD b$FP_256	; s.p. constant 256.0

	.8087			
FP_4OPI 	DD	1.273239545 ; 4/PI
FP_3PIO2	DD	4.71238898  ; 3*PI/2
FP_2PI		DD	6.283185306 ; 2*PI
FP_SQR2O2	DD	0.707106781 ; SQR(2)/2

sEnd	CONST			

	externFP B$fcomp	
	externFP B$fcompz	
	externFP B$fcompp	
	externFP B$FIX8		
	externFP B$COS4 	
	externFP B$SIN4 	

assumes CS,GR_TEXT		
sBegin	GR_TEXT 		


	externNP B$CLRATR


	externNP B$GetAspect	

	externNP B$INVIEW
	externNP B$CLINE2

	externNP B$ERR_FC
	externNP B$fmlds	
	externNP B$fmldw	
	externNP B$ftolrnd	
	externNP B$COORD1	
	externNP B$SCINIT	; Performs screen initialization
	externNP B$ERR_OV	;overflow error


	SUBTTL	B$CSTT - process optional start angle for CIRCLE statement
	PAGE
;***
;B$CSTT - process optional start angle for CIRCLE statement
;Purpose:
;	Process optional start angle for CIRCLE by saving it for later
;	in B$A_START.  Set bit 2 in flag variable B$COPTFL to
;	1 to indicate that a start angle was specified.
;Entry:
;	sAngle	= S.P. start angle in radians
;Exit:
;	B$A_START contains start angle
;Uses:
;	Per Convention
;****
cProc	B$CSTT,<PUBLIC,FAR>	
parmD	sAngle			
cBegin				
	PUSH	DI		;protect registers
	MOV	AL,4		;note start angle spec flag
	MOV	DI,OFFSET DGROUP:B$A_START ;POINT DI AT B$A_START
	JMP	SHORT CIR_SAVE	;save start angle and return
cEnd	<nogen> 		

	PAGE
	SUBTTL	B$CSTO -  process optional end angle for CIRCLE statement
;***
;B$CSTO -  process optional end angle for CIRCLE statement
;Purpose:
;	Process optional end angle for CIRCLE by saving it for later
;	in B$A_END.  Set bit 1 in flag variable B$COPTFL to
;	1 to indicate that an end angle was specified.
;Entry:
;	sAngle = S.P. end angle in radians
;Exit:
;	B$A_START contains end angle
;Uses:
;	Per Convention
;****
cProc	B$CSTO,<PUBLIC,FAR>	
parmD	sAngle			
cBegin				
	PUSH	DI
	MOV	AL,2		;note end angle spec flag
	MOV	DI,OFFSET DGROUP:B$A_END ;POINT DI AT B$A_END

CIR_SAVE:
	PUSH	ES		
	PUSH	DS		
	POP	ES		;Set ES = DS
	OR	B$COPTFL,AL	;set appropriate flag
	PUSH	SI
	LEA	SI,sAngle	;INIT SOURCE REGISTER
	CLD			;CLEAR DIRECTION FLAG
	MOVSW
	MOVSW			;save specified parameter
	POP	SI
	POP	ES		
	POP	DI
cEnd				


	SUBTTL	B$CASP - process optional aspect ratio for CIRCLE statement
	PAGE
;***
;B$CASP - process optional aspect ratio for CIRCLE statement
;
;Purpose:
; Process optional aspect ratio for CIRCLE.  Bit 3 in B$COPTFL is set to 1 to
; indicate non-default aspect ratio. Compare aspect ratio to 1. If greater than
; one,then set bit 0 in B$COPTFL to 1 to indicate that x axis must be scaled
; instead of y axis, and invert the aspect ratio (an aspect ratio greater than
; 1 is repre- sented as 256/n but is inverted to n/256 after setting flag bit
; in B$COPTFL). Multiply aspect ratio by 256 (i.e.,store numerator n only of
; aspect ratio (n/256)) and save as integer in b$ASPECTR.
;
;Entry:
;	aRatio = S.P. aspect ratio
;Exit:
;	None
;Uses:
;	Per convention
;****
cProc	B$CASP,<PUBLIC,FAR>,ES	
parmD	aRatio			
cBegin				

	OR	B$COPTFL,8	;FLAG NON-DEFAULT ASPECT RATIO


	FLD	aRatio		; ST0 = aspect ratio
	FLD	b$FP_1		; ST0 = 1.0, ST1 = aspect ratio
	CALL	B$fcomp 	; compare
	JNC	CIRC11		; brif aspect ratio already < 1.0
	OR	B$COPTFL,1	; Set scaling x flag
	FDIVR	b$FP_1		; ratio = 1.0/ratio
				; MAKE NUMBER FRACTION OF 256
CIRC11: 			
	FMUL	b$FP_256	; ratio = 256.0 * ratio


	CALL	B$ftolrnd	;round, pop off numeric stack, result in DX:AX
;
; This odd slice of code monkeys with negative aspect ratios so that we get the
; same results as produced by our interpreters (IBM and GW) when the specified
; aspect ratio is negative(!). At this point, BX contains an integer value (256
; * aspect ratio). Any value which has a low byte of zero and a non-zero high
; byte is mapped to 256 (aspect ratio of 1); otherwise the high byte is forced
; to zero.
;
	OR	AL,AL		;is low byte zero?
	JNZ	ZSTOASP 	;low byte is nonzero
				;so zero out high byte and store
	OR	AH,AH		;is high byte also zero?
	JZ	ZSTOASP 	;zero out high byte and store
	MOV	AH,1		;force aspect ratio to 1
	JMP	SHORT STOASP	;store the aspect ratio
ZSTOASP:
	XOR	AH,AH		;zero out high byte of aspect
STOASP:
	MOV	b$ASPECTR,AX	 ;SAVE ASPECT RATIO
cEnd				

	SUBTTL	B$CIRC - process the CIRCLE statement
	PAGE
;***
;B$CIRC, $CI0	   process the CIRCLE statement
;
;Purpose:
;	Draw the circle at the specified center coordinates with the
;	specified radius and of the specified color.  Arcs may be
;	drawn by specifying the start and end angles; segments may
;	be drawn by specifying these angles as negative.  The circle
;	may be scaled by specifying the aspect ratio.
;
;  flag bytes:
;
;  B$CLINEF:		   circle line to center flag
;	  lo bit (bit 0) set means draw line to ctr from start angle
;	  bit 1 set means line to ctr from start angle already drawn (bug fix)
;	  hi bit (bit 7) set means draw line to ctr from end angle
;	  bit 6 set means line to ctr from end angle already drawn (bug fix)
;
;  B$COPTFL:		   circle option flag
;	  bit 0 set means scale x axis by aspect ratio
;	  bit 0 clear means scale y axis by aspect ratio
;	  bit 1 set means end angle specified
;	  bit 2 set means start angle specified
;	  bit 3 set means aspect specified
;	  bits 4-7 unused
;
;  B$CPLOTF:  indicates which points to plot if start and end angles specified
;
;
;Entry:
;	Radius	= radius (spexp)
;	Color	= color specification
;
;Exit:
;	graphics accumulators set at center
;Uses:
;	Per convention
;****
CRCERR:
	JMP	B$ERR_FC	;ALLOW ONLY POSITIVE NOS

CRCOV:				
	JMP	B$ERR_OV	;jump to overflow error

cProc	B$CIRC,<PUBLIC,FAR>,<ES,DI,SI> 
parmD	Radius			
parmW	Color			
cBegin				

	CALL	B$SCINIT	; init screen if not already done
	cCall	B$COORD1	;Convert points
	LEA	BX,Radius	; Get ptr to radius
	MOV	AX,Color	; Get specified Color

;	Give error if color parm < -1.	We should be giving an error
;	for any negative color value, but -1 is what is passed if the
;	user defaulted the color parm.

	CMP	AX,-1		; is color < -1 ?
	JL	CRCERR		; yes, give IFC

	CALL	OLD_CIR 	; Perform circle function
	MOV	B$COPTFL,AL	; Reset options.
cEnd				



OLD_CIR:			
	MOV	CX,BX
	PUSH	AX		;SAVE COLOR ATTRIBUTE

	MOV	AH,[BX+3]	;get sign byte
	OR	AH,AH		;IS RADIUS POSITIVE?
	JS	CRCERR		;NO: issue error message
	FLD	DWORD PTR [BX]	; ST0 = value ref'd by bx

	CMP	B$WNDWSW,0	
	JZ	CIRCL1		; Scale only if Window active
	FMUL	[B$LXDIF]	
CIRCL1:
	CALL	B$ftolrnd	;round & pop ST0, convert to integer in DX:AX
	OR	DX,DX		; test if over 64K
	JNZ	CRCOV		; if so, then overflow error
	OR	AX,AX		; test if over 32K
	JS	CRCOV		; if so, then overflow error
	MOV	B$GX_OLD,AX	;SAVE RADIUS

	FILD	B$GX_OLD 	; load onto numeric stack (ST0)


	FMUL	FP_SQR2O2	; [ST0] = radius * SQR(2)/2 = # Pt.s to plot

	CALL	B$ftolrnd	;convert to integer in AX (pop from num. stack)
	MOV	B$CNPNTS,AX	;B$CNPNTS=RADIUS*SQR(2)/2=# PTS TO PLOT

	TEST	B$COPTFL,8	;Is aspect ratio defaulted?
	JNZ	NDFASP		;NO: don't get default aspect ratio

	CALL	B$GetAspect	;Yes: get default aspect ratio
;GetAspect returns BX=256*aspect ratio and DX=256/aspect ratio
	OR	BH,BH		;Is aspect ratio > 1?
	JZ	SAVASP		;NO: scale y and save BX in b$ASPECTR
	OR	B$COPTFL,1	;Set scaling x flag
	XCHG	BX,DX		;Scaling x, using 1/aspect ratio
SAVASP: 			;Save aspect ratio
	MOV	b$ASPECTR,BX	;b$ASPECTR:=BX
NDFASP: 			;Non default aspect ratio
	MOV	CX,B$GRPACX	;Get coords saved by $CI0
	MOV	DX,B$GRPACY
	POP	AX		;RESTORE COLOR ATTRIBUTE
	CALL	B$CLRATR 	;SET COLOR ATTRIBUTE OF CIRCLE
	PUSH	B$GX_OLD 	;B$GX_OLD CONTAINS RADIUS
	POP	B$GXPOS		;B$GXPOS:=RADIUS
	XOR	BX,BX		;BX:=0 (DEFAULT START ANGLE)
	MOV	B$CLINEF,BL	;CLEAR B$CLINEF

;If optional circle generation is supported (OGCircle = 1) but the
;routine does not support clipping (OGCircleClip = 0), then software
;circle generation must be used when the aspect ratio is specified or
;when clipping is required.

	MOV	B$CLIPF,BL	;Assume clipping not required
				;B$ClipCheck always called now
	CALL	B$ClipCheck	;check if clipping will occur
;B$CLIPF = FF means clipping required
;B$CLIPF = 0 means clipping not required


	XOR	AX,AX		;CLEAR FLOATING COUNT
	XOR	CX,CX		;CLEAR FLOATING COUNT
	XOR	DX,DX		;CLEAR INTEGER COUNT
ANGLES: TEST	B$COPTFL,4	;START ANGLE SPECIFIED?
	JZ	NOSTRT		;NO: USE DEFAULT COUNTS

	FLD	DWORD PTR B$A_START 

	MOV	CL,1		;LO BIT SET FOR LINE TO CNTR
	CALL	ANGLE_CALC	;GO DO ANGLE CALCULATIONS - result in AX
	XCHG	AX,DX		;put start result in DX


NOSTRT:


	TEST	B$COPTFL,2	;END ANGLE SPECIFIED?
	JZ	NOEND		;NO: USE DEFAULT COUNT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -