# Codebase64 wiki

### Site Tools

base:circle_routine

# Circle Routine

Circle routine, on the bitmap screen, based on algorithm at: http://ffd2.com/fridge/chacking/c=hacking9.txt. Draws the Circle with 8 symmetric arcs.

```_Vic = \$d000
_Vmem= \$2000
pY = \$2
pX = \$3
pX1 = \$5
pY1 = \$52
pXR = \$a8
pYR = \$a6
dA  = \$a3
wOffs = \$fb

; ************************************************
;
;       Circle
;
;       input: pX1 (word 0-319**), center x-coord
;              pY1 (byte 0-199**), center y-coord
;              pXR (word 0-320**), radius
;       **values can in fact be larger: Y can be up to 255
;       while X and R can be up to 65535 (X in 0-32767 for
;       circles centered outside the video on the right,
;       32768-65535 for circles outside on the left)
;
;
; 0       circle (x0, y0, r)
; 1           x=r;
; 2           y=0;
; 3           a=x;
; 4           while (true) {
; 5                plot(x0+x,y0+y);
; 6                plot(x0+x,y0-y);
; 7                plot(x0-x,y0-y);
; 8                plot(x0-x,y0+y);
; 9                plot(x0+y,y0+x);
; 10               plot(x0+y,y0-x);
; 11               plot(x0-y,y0-x);
; 12               plot(x0-y,y0+x);
; 13             if (x>y) break;
; 14             y=y+1;
; 15             a=a-y;
; 16             if (a<0) {
; 17                x=x-1;
; 18                a=a+x;
; 19             }
; 20          }
;
;       algo: http://ffd2.com/fridge/chacking/c=hacking9.txt
;       draws the circle plotting 8 arcs
;                         arc8 - - arc1
;                       arc7 /     \ arc2
;                       arc6 \     / arc3
;                         arc5 - - arc4
;
; ************************************************

xoPx= \$61 ; byte 0,0
xoPy= \$63 ; byte 0,0
xoMx= \$65 ; byte 0,0
xoMy= \$69 ; byte 0,0
yoPx= \$6b ; byte 0
yoPy= \$6c ; byte 0
yoMx= \$6d ; byte 0
yoMy= \$6e ; byte 0

_Circle
lda #0          ; ****** 2. YR=0
sta pYR
sta pYR+1
lda pXR         ; ****** 3. dA=X (=R)
sta dA
lda pXR+1
sta dA+1
; ****** 5-12: preparation
_cb     clc        ;x0+x
lda pXR
sta xoPx
lda pXR+1
sta xoPx+1

sec        ;x0-x
lda pX1
sbc pXR
sta xoMx
lda pX1+1
sbc pXR+1
sta xoMx+1

clc        ;x0+y
lda pYR
sta xoPy
lda pYR+1
sta xoPy+1

sec        ;x0-y
lda pX1
sbc pYR
sta xoMy
lda pX1+1
sbc pYR+1
sta xoMy+1

clc        ;y0+x
lda pXR
bcs _noY1       ; if Y+XR>255 then won't plot it
sta yoPx
lda pXR+1
beq _2yoMX
_noY1   lda #201        ; if outside the video, sets Y=201
sta yoPx

_2yoMX  sec        ;y0-x
lda pY1
sbc pXR
bcc _noY2       ; if XR > Y then it's outside the video
sta yoMx
lda pXR+1
beq _2yoPy
_noY2   lda #201        ; if outside the video, sets Y=201
sta yoMx

_2yoPy  clc        ;y0+y
lda pYR
bcs _noY3       ; if Y+YR>255 then won't plot it
sta yoPy
lda pYR+1
beq _2yoMy
_noY3   lda #201        ; if outside the video, sets Y=201
sta yoPy

_2yoMy  sec        ;y0-y
lda pY1
sbc pYR
bcc _noY4       ; if YR > Y then it's outside the video
sta yoMy
lda pYR+1
beq Plot8
_noY4   lda #201        ; if outside the video, sets Y=201
sta yoMy

Plot8   lda xoPx        ; ****** 5. ESE, arc 3
sta pX
lda xoPx+1
sta pX+1
lda yoPy
sta pY
jsr CheckPlot

lda yoMy        ; ****** 6. ENE, arc 2
sta pY
jsr CheckPlot

lda xoMx        ; ****** 7. WNW, arc 7
sta pX
lda xoMx+1
sta pX+1
jsr CheckPlot

lda yoPy        ; ****** 8. WSW, arc 6
sta pY
jsr CheckPlot

lda xoPy        ; ****** 9. SSE, arc 4
sta pX
lda xoPy+1
sta pX+1
lda yoPx
sta pY
jsr CheckPlot

lda yoMx        ; ****** 10. NNE, arc 1
sta pY
jsr CheckPlot

lda xoMy        ; ****** 11. NNW, arc 8
sta pX
lda xoMy+1
sta pX+1
jsr CheckPlot

lda yoPx        ; ****** 12. SSW, arc 5
sta pY
jsr CheckPlot

lda pYR         ; ****** 13. y<=x ?
cmp pXR
lda pYR+1
sbc pXR+1
bcc over        ; if YR<=XR go on
rts             ; end
over    inc pYR         ; ****** 14. YR=YR+1
bne noYRhi
inc pYR+1
noYRhi  sec             ; ****** 15. dA=dA-YR
lda dA
sbc pYR
sta dA
lda dA+1
sbc pYR+1
sta dA+1
bpl noX         ; ****** 16. dA<0 ?
lda pXR         ; ****** 17. XR=XR-1
bne noXRhi
dec pXR+1
noXRhi  dec pXR
clc             ; ****** 18. dA=dA+XR
lda dA
sta dA
lda dA+1
sta dA+1
noX     jmp _cb

; ************************************************
;
;       Plot
;
;       input: pX (word 0-319**)
;              pY (byte 0-200**)
;       **boundary check via CheckPlot
;
; offset = BaseAddr + 320*int(Y/8)+(Y and 7) + 8*int(X/8)
; pixel  = 2^(7-(X and 7))
;
; ************************************************
CheckPlot
lda pY
cmp #200
bcs _CPRet      ; <
lda pX
cmp #<320
lda pX+1
sbc #>320
bcs _CPRet
;       jmp _Plot

_Plot
ldy #0          ; 2     ; comput. dY
sty wOffs       ; 3     ; reset lobyte
lda pY          ; 3
lsr             ; 2
lsr             ; 2
lsr             ; 2     ; int(Y/8)
sta wOffs+1     ; 3     ; 256*int(Y/8) hibyte (lobyte=0)
lsr             ; 2
ror wOffs       ; 5
lsr             ; 2     ; 64*int(Y/8)  hibyte
ror wOffs       ; 5     ; 64*int(Y/8)  lobyte  (= 320*int(Y/8) lobyte)
adc wOffs+1     ; 3     ; 256*int(Y/8) + 64*int(Y/8)  hibyte
sta wOffs+1     ; 3     ; =320*int(Y/8) hibyte
lda pY          ; 3     ; add (Y and 7)
and #7          ; 2
ora wOffs       ; 3     ; lobyte [xx000xxx]
sta wOffs       ; 3  48

lda pX          ; 3     ; dX + dY + BaseAddr
and #248        ; 2
adc wOffs       ; 3
sta wOffs       ; 3
lda wOffs+1     ; 3
adc pX+1        ; 3
adc #>_Vmem     ; 2
sta wOffs+1     ; 3  22

lda pX          ; 3     ; set pixel-bit
and #7          ; 2
tax             ; 2
lda (wOffs),y   ; 5
ora ortab,x     ; 4
sta (wOffs),y   ; 6  22

_CPRet  rts

ortab
byte 128, 64, 32, 16, 8, 4, 2, 1```
base/circle_routine.txt · Last modified: 2020-04-19 19:24 by verz