📄 circle.asm
字号:
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 + -