]> 4ch.mooo.com Git - 16.git/blob - 16/xlib/XCIRCLE.ASM
4e7503132b54c962c63f60f42074825a5bc8c893
[16.git] / 16 / xlib / XCIRCLE.ASM
1 ;-----------------------------------------------------------------------\r
2 ;\r
3 ; MODULE XCIRCLE\r
4 ;\r
5 ;   This module was written by Matthew MacKenzie\r
6 ;   matm@eng.umd.edu\r
7 ;\r
8 ; Circles, full and empty.\r
9 ;\r
10 ; Compile with Tasm.\r
11 ; C callable.\r
12 ;\r
13 ; ****** XLIB - Mode X graphics library                ****************\r
14 ; ******                                               ****************\r
15 ;\r
16 ; egg@dstos3.dsto.gov.au\r
17 ; teg@bart.dsto.gov.au\r
18 ;-----------------------------------------------------------------------\r
19 \r
20 include xlib.inc\r
21 include xcircle.inc\r
22 \r
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
24 ; _x_circle\r
25 ;\r
26 ; Draw a circle.\r
27 ;\r
28 ; C near-callable as:\r
29 ; int x_circle (WORD Left, WORD Top, WORD Diameter,\r
30 ;                WORD Color, WORD ScreenOffs);\r
31 ;\r
32 ; No clipping is performed.\r
33 ;\r
34 ; ax, bx, cx, and dx bite the dust, as Homer would say.\r
35 \r
36 ; we plot into eight arcs at once:\r
37 ;      4 0\r
38 ;    6 \|/ 2\r
39 ;     --*--\r
40 ;    7 /|\ 3\r
41 ;      5 1\r
42 ;\r
43 ; 0, 1, 4, and 5 are considered x-major; the rest, y-major.\r
44 ;\r
45 ; The x-major plots grow out from the top and bottom of the circle,\r
46 ; while the y-major plots start at the left and right edges.\r
47 \r
48         .data\r
49 \r
50         align 2\r
51 \r
52 ColumnMask      db      011h,022h,044h,088h\r
53 \r
54         .code\r
55 \r
56         public _x_circle\r
57         align   2\r
58 _x_circle proc\r
59 ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word\r
60 LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error:word=LocalStk\r
61 ; Tasm 1.0 does not allow the \ line continuation\r
62 ;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \\r
63 ;         offset4:word, offset5:word, offset6:word, offset7:word, \\r
64 ;         mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \\r
65 ;         shrunk_radius:word, diameter_even:word, error:word=LocalStk\r
66 \r
67         push bp\r
68         mov  bp, sp\r
69         sub  sp, LocalStk\r
70         push si\r
71         push di\r
72         push ds\r
73 \r
74 ; find starting locations of plots 2, 3, 6, and 7\r
75         mov di, _ScrnLogicalByteWidth\r
76         xor dx, dx\r
77 \r
78         mov ax, Diameter    ; find vertical midpoint\r
79         dec ax\r
80         shr ax, 1\r
81         adc dx, 0           ; remember if it's rounded\r
82         mov shrunk_radius, ax ; radius, rounded down for adding\r
83         mov diameter_even, dx ; (diameter - 1) & 1, effectively\r
84         add ax, Top\r
85         mul di              ; vertical midpoint in bytes\r
86         add ax, ScreenOffs\r
87 \r
88         mov bx, Left\r
89         mov cx, bx          ; save for later\r
90         mov si, bx\r
91         shr si, 2\r
92         add si, ax\r
93         mov offset6, si\r
94         and bx, 3           ; column of left side\r
95         mov bl, ColumnMask[bx]\r
96         mov mask6n7, bx\r
97 \r
98         add cx, Diameter\r
99         dec cx\r
100         mov bx, cx\r
101         shr cx, 2\r
102         add cx, ax\r
103         mov offset2, cx\r
104         and bx, 3           ; column of right side\r
105         mov bl, ColumnMask[bx]\r
106         mov mask2n3, bx\r
107 \r
108         cmp diameter_even, 1\r
109         jne @@MiddlePlotsOverlap\r
110         add si, di\r
111         add cx, di\r
112 @@MiddlePlotsOverlap:\r
113         mov offset7, si\r
114         mov offset3, cx\r
115 \r
116 ; starting locations of 0, 1, 4, and 5\r
117         mov bx, Left\r
118         add bx, shrunk_radius ; find horizontal midpoint\r
119 \r
120         mov ax, Top         ; top in bytes\r
121         mul di\r
122         add ax, ScreenOffs\r
123         mov si, ax\r
124 \r
125         mov ax, Diameter    ; bottom in bytes\r
126         dec ax\r
127         mul di\r
128         add ax, si\r
129 \r
130         mov di, bx          ; horizontal midpoint in bytes\r
131         shr di, 2\r
132         add si, di              ; top midpoint in bytes\r
133         mov offset4, si\r
134         add di, ax              ; bottom midpoint in bytes\r
135         mov offset5, di\r
136         and bx, 3           ; column of horizontal midpoint\r
137         mov bl, ColumnMask[bx]\r
138         mov mask4n5, bx\r
139 \r
140         cmp diameter_even, 1\r
141         jne @@TopAndBottomPlotsOverlap\r
142         rol bl, 1\r
143         jnc @@TopAndBottomPlotsOverlap\r
144         inc si\r
145         inc di\r
146 @@TopAndBottomPlotsOverlap:\r
147         mov offset0, si\r
148         mov offset1, di\r
149         mov mask0n1, bx\r
150 \r
151 ; we've got our eight plots in their starting positions, so\r
152 ; it's time to sort out the registers\r
153         mov bx, _ScrnLogicalByteWidth\r
154 \r
155         mov dx, SCREEN_SEG\r
156         mov ds, dx\r
157 \r
158         mov dx, SC_INDEX    ; set VGA to accept column masks\r
159         mov al, MAP_MASK\r
160         out dx, al\r
161         inc dx              ; gun the engine...\r
162 \r
163         mov si, Diameter    ; initial y is radius -- 2 #s per pixel\r
164         inc si\r
165 \r
166         mov cx, si\r
167         neg cx\r
168         add cx, 2\r
169         mov error, cx       ; error = -y + one pixel since we're a step ahead\r
170 \r
171         xor cx, cx          ; initial x = 0\r
172         mov ah, byte ptr Color\r
173         jmp @@CircleCalc        ; let's actually put something on the screen!\r
174 \r
175 ; move the x-major plots horizontally and the y-major plots vertically\r
176 @@NoAdvance:\r
177         mov al, byte ptr mask0n1\r
178         out dx, al\r
179         mov di, offset0     ; plot 0\r
180         mov [di], ah\r
181         rol al, 1           ; advance 0 right\r
182         mov byte ptr mask0n1, al\r
183         adc di, 0\r
184         mov offset0, di\r
185         mov di, offset1\r
186         mov [di], ah        ; plot 1\r
187         ror al, 1           ; what was that bit again?\r
188         adc di, 0           ; advance 1 right\r
189         mov offset1, di\r
190 \r
191         mov al, byte ptr mask2n3\r
192         out dx, al\r
193         mov di, offset2\r
194         mov [di], ah        ; plot 2\r
195         sub di, bx          ; advance 2 up\r
196         mov offset2, di\r
197         mov di, offset3\r
198         mov [di], ah        ; plot 3\r
199         add di, bx          ; advance 3 down\r
200         mov offset3, di\r
201 \r
202         mov al, byte ptr mask4n5\r
203         out dx, al\r
204         mov di, offset4\r
205         mov [di], ah\r
206         ror al, 1\r
207         mov byte ptr mask4n5, al\r
208         sbb di, 0\r
209         mov offset4, di\r
210         mov di, offset5\r
211         mov [di], ah\r
212         rol al, 1\r
213         sbb di, 0\r
214         mov offset5, di\r
215 \r
216         mov al, byte ptr mask6n7\r
217         out dx, al\r
218         mov di, offset6\r
219         mov [di], ah\r
220         sub di, bx\r
221         mov offset6, di\r
222         mov di, offset7\r
223         mov [di], ah\r
224         add di, bx\r
225         mov offset7, di\r
226 \r
227         jmp @@CircleCalc\r
228 \r
229 ; move all plots diagonally\r
230 @@Advance:\r
231         mov al, byte ptr mask0n1\r
232         out dx, al\r
233         mov di, offset0\r
234         mov [di], ah        ; plot 0\r
235         rol al, 1           ; advance 0 right and down\r
236         mov byte ptr mask0n1, al\r
237         adc di, bx\r
238         mov offset0, di\r
239         mov di, offset1\r
240         mov [di], ah        ; plot 1\r
241         ror al, 1           ; what was that bit again?\r
242         adc di, 0           ; advance 1 right and up\r
243         sub di, bx\r
244         mov offset1, di\r
245 \r
246         mov al, byte ptr mask2n3\r
247         out dx, al\r
248         mov di, offset2\r
249         mov [di], ah        ; plot 2\r
250         ror al, 1           ; advance 2 up and left\r
251         mov byte ptr mask2n3, al\r
252         sbb di, bx\r
253         mov offset2, di\r
254         mov di, offset3\r
255         mov [di], ah        ; plot 3\r
256         rol al, 1\r
257         sbb di, 0           ; advance 3 down and left\r
258         add di, bx\r
259         mov offset3, di\r
260 \r
261         mov al, byte ptr mask4n5\r
262         out dx, al\r
263         mov di, offset4\r
264         mov [di], ah\r
265         ror al, 1\r
266         mov byte ptr mask4n5, al\r
267         sbb di, 0\r
268         add di, bx\r
269         mov offset4, di\r
270         mov di, offset5\r
271         mov [di], ah\r
272         rol al, 1\r
273         sbb di, bx\r
274         mov offset5, di\r
275 \r
276         mov al, byte ptr mask6n7\r
277         out dx, al\r
278         mov di, offset6\r
279         mov [di], ah\r
280         rol al, 1\r
281         mov byte ptr mask6n7, al\r
282         adc di, 0\r
283         sub di, bx\r
284         mov offset6, di\r
285         mov di, offset7\r
286         mov [di], ah\r
287         ror al, 1\r
288         adc di, bx\r
289         mov offset7, di\r
290 \r
291 ; do you realize the entire function has been set up for this little jot?\r
292 ; keep in mind that radii values are 2 per pixel\r
293 @@CircleCalc:\r
294         add cx, 2           ; x += 1\r
295         mov di, error\r
296         add di, cx          ; error += (2 * x) + 1\r
297         inc di\r
298         jl @@CircleNoError\r
299         cmp cx, si          ; x > y?\r
300         ja @@FleeFlyFlowFum\r
301         sub si, 2           ; y -= 1\r
302         sub di, si          ; error -= (2 * y)\r
303         mov error, di\r
304         jmp @@Advance\r
305 @@CircleNoError:\r
306         mov error, di\r
307         jmp @@NoAdvance\r
308 \r
309 @@FleeFlyFlowFum:\r
310         pop ds\r
311         pop di\r
312         pop si\r
313         mov sp,bp\r
314         pop bp\r
315 \r
316         ret\r
317 \r
318 _x_circle endp\r
319 \r
320 \r
321 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
322 ; _x_filled_circle\r
323 ;\r
324 ; Draw a disc.\r
325 ;\r
326 ; C near-callable as:\r
327 ; int x_filled_circle (WORD Left, WORD Top, WORD Diameter,\r
328 ;                      WORD Color, WORD ScreenOffs);\r
329 ;\r
330 ; No clipping is performed.\r
331 ;\r
332 ; ax, bx, cx, dx, and es bite the dust, as Homer would say.\r
333 ; DF is set to 0 (strings go forward).\r
334 \r
335         .data\r
336 \r
337         align 2\r
338 \r
339 ; the only entries of these tables which are used are positions\r
340 ; 1, 2, 4, and 8\r
341 LeftMaskTable   db      0, 0ffh, 0eeh, 0, 0cch, 0, 0, 0, 088h\r
342 RightMaskTable  db              0, 011h, 033h, 0, 077h, 0, 0, 0, 0ffh\r
343 \r
344         .code\r
345 \r
346         public _x_filled_circle\r
347         align   2\r
348 _x_filled_circle proc\r
349 ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word\r
350 ; Tasm 1.0 does not allow the \ line continuation\r
351 ;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \\r
352 ;         offset4:word, offset5:word, offset6:word, offset7:word, \\r
353 ;         mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \\r
354 ;         shrunk_radius:word, diameter_even:word, error:word, \\r
355 ;         jump_vector:word=LocalStk\r
356 LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error,jump_vector:word=LocalStk\r
357 \r
358         push bp\r
359         mov  bp, sp\r
360         sub  sp, LocalStk\r
361         push si\r
362         push di\r
363 \r
364         cld                                     ; strings march forward\r
365 \r
366 ; this first part is identical to the other function --\r
367 ; the only differences, in fact, are in the drawing and moving around\r
368 \r
369 ; find starting locations of plots 2, 3, 6, and 7\r
370         mov di, _ScrnLogicalByteWidth\r
371         xor dx, dx\r
372 \r
373         mov ax, Diameter    ; find vertical midpoint\r
374         dec ax\r
375         shr ax, 1\r
376         adc dx, 0           ; remember if it's rounded\r
377         mov shrunk_radius, ax ; radius, rounded down for adding\r
378         mov diameter_even, dx ; (diameter - 1) & 1, effectively\r
379         add ax, Top\r
380         mul di              ; vertical midpoint in bytes\r
381         add ax, ScreenOffs\r
382 \r
383         mov bx, Left\r
384         mov cx, bx          ; save for later\r
385         mov si, bx\r
386         shr si, 2\r
387         add si, ax\r
388         mov offset6, si\r
389         and bx, 3           ; column of left side\r
390         mov bl, ColumnMask[bx]\r
391         mov mask6n7, bx\r
392 \r
393         add cx, Diameter\r
394         dec cx\r
395         mov bx, cx\r
396         shr cx, 2\r
397         add cx, ax\r
398         mov offset2, cx\r
399         and bx, 3           ; column of right side\r
400         mov bl, ColumnMask[bx]\r
401         mov mask2n3, bx\r
402 \r
403         cmp diameter_even, 1\r
404         jne @@MiddlePlotsOverlap\r
405         add si, di\r
406         add cx, di\r
407 @@MiddlePlotsOverlap:\r
408         mov offset7, si\r
409         mov offset3, cx\r
410 \r
411 ; starting locations of 0, 1, 4, and 5\r
412         mov bx, Left\r
413         add bx, shrunk_radius ; find horizontal midpoint\r
414 \r
415         mov ax, Top         ; top in bytes\r
416         mul di\r
417         add ax, ScreenOffs\r
418         mov si, ax\r
419 \r
420         mov ax, Diameter    ; bottom in bytes\r
421         dec ax\r
422         mul di\r
423         add ax, si\r
424 \r
425         mov di, bx          ; horizontal midpoint in bytes\r
426         shr di, 2\r
427         add si, di              ; top midpoint in bytes\r
428         mov offset4, si\r
429         add di, ax              ; bottom midpoint in bytes\r
430         mov offset5, di\r
431         and bx, 3           ; column of horizontal midpoint\r
432         mov bl, ColumnMask[bx]\r
433         mov mask4n5, bx\r
434 \r
435         cmp diameter_even, 1\r
436         jne @@TopAndBottomPlotsOverlap\r
437         rol bl, 1\r
438         jnc @@TopAndBottomPlotsOverlap\r
439         inc si\r
440         inc di\r
441 @@TopAndBottomPlotsOverlap:\r
442         mov offset0, si\r
443         mov offset1, di\r
444         mov mask0n1, bx\r
445 \r
446 ; we've got our eight plots in their starting positions, so\r
447 ; it's time to sort out the registers\r
448         mov bx, _ScrnLogicalByteWidth\r
449 \r
450         mov dx, SCREEN_SEG\r
451         mov es, dx\r
452 \r
453         mov dx, SC_INDEX    ; set VGA to accept column masks\r
454         mov al, MAP_MASK\r
455         out dx, al\r
456         inc dx              ; gun the engine...\r
457 \r
458         mov si, Diameter    ; initial y is radius -- 2 #s per pixel\r
459         inc si\r
460 \r
461         mov cx, si\r
462         neg cx\r
463         add cx, 2\r
464         mov error, cx       ; error = -y + one pixel since we're a step ahead\r
465 \r
466         xor cx, cx          ; initial x = 0\r
467         mov ah, byte ptr Color\r
468         jmp @@FilledCircleCalc ; let's actually put something on the screen!\r
469 \r
470 \r
471 ; plotting is completely different from in the other function (naturally)\r
472 @@PlotLines:\r
473         push cx                         ; we'll need cx for string stores\r
474 \r
475 ; draw x-major horz. lines, from plot 4 to plot 0 and from plot 5 to plot 1\r
476         mov di, mask0n1\r
477         and di, 0000fh          ; we only want the lower nybble for the mask table\r
478         mov al, RightMaskTable[di]\r
479         mov di, offset0         ; left and right offsets the same?\r
480         cmp di, offset4\r
481         jne @@PlotXMajorNontrivial ; try and say this one 10 times fast!\r
482         mov di, mask4n5\r
483         and di, 0000fh\r
484         and al, LeftMaskTable[di] ; intersection of left & right masks\r
485         out dx, al                      ; set mask\r
486         mov di, offset4\r
487         mov es:[di], ah\r
488         mov di, offset5\r
489         mov es:[di], ah\r
490         jmp @@PlotYMajor\r
491 @@PlotXMajorNontrivial:\r
492         out dx, al          ; draw right edge\r
493         mov es:[di], ah\r
494         mov di, offset1\r
495         mov es:[di], ah\r
496 \r
497         mov di, mask4n5         ; draw left edge\r
498         and di, 0000fh\r
499         mov al, LeftMaskTable[di]\r
500         out dx, al\r
501         mov di, offset4\r
502         mov es:[di], ah\r
503         mov di, offset5\r
504         mov es:[di], ah\r
505 \r
506         mov al, 0ffh            ; set mask for middle chunks\r
507         out dx, al\r
508         mov al, ah                      ; ready to store two pixels at a time\r
509         inc di                          ; move string start past left edge\r
510         mov cx, offset1         ; store line from plot 5 to plot 1, exclusive\r
511         sub cx, di                      ; width of section in bytes\r
512         push cx\r
513         shr cx, 1                       ; draw midsection eight pixels at a time\r
514         rep stosw\r
515         adc cx, 0                       ; draw last four pixels, if such there are\r
516         rep stosb\r
517 \r
518         mov di, offset4         ; draw line from plot 4 to plot 0\r
519         inc di                          ; move past left edge\r
520         pop cx\r
521         shr cx, 1\r
522         rep stosw\r
523         adc cx, 0\r
524         rep stosb\r
525 \r
526 @@PlotYMajor:\r
527 ; draw y-major horz. lines, from plot 6 to plot 2 and from plot 7 to plot 3\r
528         mov di, mask2n3\r
529         and di, 0000fh          ; we only want the lower nybble for the mask table\r
530         mov al, RightMaskTable[di]\r
531         mov di, offset2         ; left and right offsets the same?\r
532         cmp di, offset6\r
533         jne @@PlotYMajorNontrivial ; try and say this one 10 times fast!\r
534         mov di, mask6n7\r
535         and di, 0000fh\r
536         and al, LeftMaskTable[di] ; intersection of left & right masks\r
537         out dx, al                      ; set mask\r
538         mov di, offset6\r
539         mov es:[di], ah\r
540         mov di, offset7\r
541         mov es:[di], ah\r
542         jmp @@ClimaxOfPlot\r
543 @@PlotYMajorNontrivial:\r
544         out dx, al          ; draw right edge\r
545         mov es:[di], ah\r
546         mov di, offset3\r
547         mov es:[di], ah\r
548 \r
549         mov di, mask6n7         ; draw left edge\r
550         and di, 0000fh\r
551         mov al, LeftMaskTable[di]\r
552         out dx, al\r
553         mov di, offset6\r
554         mov es:[di], ah\r
555         mov di, offset7\r
556         mov es:[di], ah\r
557 \r
558         mov al, 0ffh            ; set mask for middle chunks\r
559         out dx, al\r
560         mov al, ah                      ; ready to store two pixels at a time\r
561 \r
562         inc di                          ; move string start past left edge\r
563         mov cx, offset3         ; draw line from plot 7 to plot 3, exclusive\r
564         sub cx, di                      ; width of section in bytes\r
565         push cx\r
566         shr cx, 1                       ; store midsection\r
567         rep stosw\r
568         adc cx, 0\r
569         rep stosb\r
570 \r
571         mov di, offset6         ; draw line from plot 6 to plot 2\r
572         inc di                          ; move past left edge\r
573         pop cx\r
574         shr cx, 1\r
575         rep stosw\r
576         adc cx, 0\r
577         rep stosb\r
578 \r
579 @@ClimaxOfPlot:\r
580         pop cx\r
581         jmp [jump_vector]       ; either @@Advance or @@NoAdvance\r
582 \r
583 \r
584 ; unlike their counterparts in the other function, these do not draw --\r
585 ; they only move the eight pointers\r
586 \r
587 ; move the x-major plots horizontally and the y-major plots vertically\r
588 @@NoAdvance:\r
589         mov al, byte ptr mask0n1 ; advance left x-major plots\r
590         mov di, offset0\r
591         rol al, 1           ; advance 0 right\r
592         mov byte ptr mask0n1, al\r
593         adc di, 0\r
594         mov offset0, di\r
595         mov di, offset1\r
596         ror al, 1           ; what was that bit again?\r
597         adc di, 0           ; advance 1 right\r
598         mov offset1, di\r
599 \r
600         mov al, byte ptr mask4n5 ; advance left x-major plots\r
601         mov di, offset4\r
602         ror al, 1\r
603         mov byte ptr mask4n5, al\r
604         sbb di, 0\r
605         mov offset4, di\r
606         mov di, offset5\r
607         rol al, 1\r
608         sbb di, 0\r
609         mov offset5, di\r
610 \r
611         mov al, byte ptr mask2n3\r
612         mov di, offset2\r
613         sub di, bx          ; advance 2 up\r
614         mov offset2, di\r
615         mov di, offset3\r
616         add di, bx          ; advance 3 down\r
617         mov offset3, di\r
618 \r
619         mov al, byte ptr mask6n7\r
620         mov di, offset6\r
621         sub di, bx\r
622         mov offset6, di\r
623         mov di, offset7\r
624         add di, bx\r
625         mov offset7, di\r
626 \r
627         jmp @@FilledCircleCalc\r
628 \r
629 ; move all plots diagonally\r
630 @@Advance:\r
631         mov al, byte ptr mask0n1\r
632         mov di, offset0\r
633         rol al, 1           ; advance 0 right and down\r
634         mov byte ptr mask0n1, al\r
635         adc di, bx\r
636         mov offset0, di\r
637         mov di, offset1\r
638         ror al, 1           ; what was that bit again?\r
639         adc di, 0           ; advance 1 right and up\r
640         sub di, bx\r
641         mov offset1, di\r
642 \r
643         mov al, byte ptr mask2n3\r
644         mov di, offset2\r
645         ror al, 1           ; advance 2 up and left\r
646         mov byte ptr mask2n3, al\r
647         sbb di, bx\r
648         mov offset2, di\r
649         mov di, offset3\r
650         rol al, 1\r
651         sbb di, 0           ; advance 3 down and left\r
652         add di, bx\r
653         mov offset3, di\r
654 \r
655         mov al, byte ptr mask4n5\r
656         mov di, offset4\r
657         ror al, 1\r
658         mov byte ptr mask4n5, al\r
659         sbb di, 0\r
660         add di, bx\r
661         mov offset4, di\r
662         mov di, offset5\r
663         rol al, 1\r
664         sbb di, bx\r
665         mov offset5, di\r
666 \r
667         mov al, byte ptr mask6n7\r
668         mov di, offset6\r
669         rol al, 1\r
670         mov byte ptr mask6n7, al\r
671         adc di, 0\r
672         sub di, bx\r
673         mov offset6, di\r
674         mov di, offset7\r
675         ror al, 1\r
676         adc di, bx\r
677         mov offset7, di\r
678 \r
679 ; do you realize the entire function has been set up around this little jot?\r
680 ; keep in mind that radii values are 2 per pixel\r
681 @@FilledCircleCalc:\r
682         add cx, 2           ; x += 1\r
683         mov di, error\r
684         add di, cx          ; error += (2 * x) + 1\r
685         inc di\r
686         jl @@FilledCircleNoError\r
687         cmp cx, si          ; x > y?\r
688         ja @@FleeFlyFlowFum\r
689         sub si, 2           ; y -= 1\r
690         sub di, si          ; error -= (2 * y)\r
691         mov error, di\r
692         mov jump_vector, offset @@Advance\r
693         jmp @@PlotLines\r
694 @@FilledCircleNoError:\r
695         mov error, di\r
696         mov jump_vector, offset @@NoAdvance\r
697         jmp @@PlotLines\r
698 \r
699 @@FleeFlyFlowFum:\r
700         pop di\r
701         pop si\r
702         mov sp,bp\r
703         pop bp\r
704 \r
705         ret\r
706 \r
707 _x_filled_circle endp\r
708 \r
709         end\r
710 \r