-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathcircle.src
178 lines (152 loc) · 4.2 KB
/
circle.src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
.page
.subttl CIRCLE Command
;*************************************************************
;
; circle s,(pc),xr(,(yr)(,(as)(,(ae)(,(rot) (,inc) ) ) ) )
; -- draw an ellipse
; s = color selection (1-4) (default = fg (1))
; pc = center coordinates (default = xpos,ypos)
; xr = x-radius - yr = y-radius (default = xr)
; as,ae = arc start & arc end (defalut = 0)
; rot = rotation angle (default = 0)
; inc = increment to next point (default = 2)
;
;*************************************************************
circle jsr grpcol ;make sure graphics area has been allocated, get color
ldx #xcircl-vwork
jsr incor2 ;get optional center coordinates
jsr optwrd ;get 2-byte x-radius (default to zero?)
sty xradus
sta xradus+1
jsr optwrd ;get 2-byte y-radius (.c=0 if not given)
sty yradus
bcs 10$ ;branch if y-radius given (318018-03 mod; fab)
lda xradus ;else use x radius for y as well
sta yradus
lda xradus+1
bit _graphm
bpl 10$ ;skip if not multicolor mode
asl yradus ;double it for circle
rol a
10$ sta yradus+1
ldx #xradus-vwork
jsr scalxy ;scale the values ;(318018-03 mod; fab)
.byte $ea,$ea,$ea,$ea,$ea ;(318018-03 placeholder; fab)
jsr optwrd ;get optional 2-byte arc start
sty angbeg
sta angbeg+1
jsr optwrd ;get optional 2-byte arc end
sty angend
sta angend+1
jsr optwrd ;get optional 2-byte rotation angle
sta z_p_temp_1 ;swap y and a
tya
ldy z_p_temp_1
jsr gtang1 ;set sine & cosine for rotation angle
ldx #angend-vwork ;test if angend>angbeg
ldy #angbeg-vwork
jsr subtwo
bcc circ10 ;skip if yes
lda #104
ldy #1
jsr addtw2 ;add 360 to arc-end
sta vwork,x
tya
sta vwork+1,x
circ10
ldx #3
circ20
lda xradus,x ;duplicate x-rad/y-rad in xdist2/ydist2
sta xdist2,x
dex
bpl circ20
lda #$90
jsr angdst ;get distances * rotation angle
; xdist1 = xr*cos -- ydist1 = yr*sin
; xdist2 = xr*sin -- ydist2 = yr*cos
ldx #7
circ30
lda xdist1,x ;move for later use
sta xrcos,x
dex
bpl circ30
jsr cirsub ;get 1st point on circle
jsr dstpos ;move to xpos/ypos
; draw circle with connected lines
; incrementing angbeg by cirinc for each point
ldx #2
jsr optbyt ;get optional 1 byte increment value (default is 2)
txa ;must be >0
bne 40$ ;ok
jmp fcerr ;bad
40$ stx circle_segment
clc
circ45 lda circle_segment
adc angbeg ;add increment (carry assumed clear)
sta angbeg
bcc circ50
inc angbeg+1
circ50 ldx #angend-vwork ;test if angend>angbeg
ldy #angbeg-vwork
jsr subtwo
bcs cirend ;yes - do once more
jsr cirsub ;get next point on circle
jsr drawln ;connect to last point
bcc circ45 ;loop always
cirend
ldy #angend-vwork
jsr cirs10 ;get last point for arc-end
jmp drawln
.page
;***********************************************************
;
; cirsub -- find the next point on the circle
; x = xctr + xr*cos(a)*sin(b) + yr*sin(a)*cos(b)
; y = yctr + xr*sin(a)*sin(b) - yr*cos(a)*cos(b)
; where: a = rotation angle -- b = circle arc angle
;
;***********************************************************
cirsub ldy #angbeg-vwork
cirs10 jsr getang ;get sine & cosine values for arc angle
ldx #7
1$ lda xrcos,x ;move radius * rotation-angle values to xdist
sta xdist1,x
dex
bpl 1$
lda #$50
jsr angdst ;multiply times arc-angle values
lda #$10 ;fall thru to angplt
;**************************************************************
;
; anglpt -- determine a point on the screen
; xdest = xcentr +/- xdist1 +/- ydist1
; ydest = ycentr +/- xdist2 +/- ydist2
; a = signs: +/-,+/-,+/-,+/-,0,0,0,0
;
;**************************************************************
anglpt sta angcnt ;save plus or minus signs
ldy #xcentr-vwork
ldx #xdist1-vwork
10$ asl angcnt+1
rol angcnt ;get sign
jsr dotwo ;add or subtract 1st value to center pt
inx
inx ;point to next value
asl angcnt+1
rol angcnt ;get next sign
jsr dotwo2 ;add or subtract to previous result
pha
tya ;save 2-byte result on stack
pha
ldy #ycentr-vwork ;set to do y-point
inx
inx ;point to next value
cpx #xdist2-vwork
beq 10$ ;loop to do y-point
ldx #3
20$ pla
sta xdest,x ;move results to xdest/ydest
dex
bpl 20$
rts
;.end