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 adc pX1 sta xoPx lda pXR+1 adc pX1+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 adc pX1 sta xoPy lda pYR+1 adc pX1+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 adc pY1 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 adc pY1 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 adc pXR sta dA lda dA+1 adc pXR+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