;------------------------------
; Bresenham's circle algorithm 
; by Stephane JANTZEN
; Stephane.Jantzen@scinfo.u-nancy.fr
;
; first release : 07/15/95
; last modified : 01/29/96
;------------------------------
;
; Optimized implementation of
; Bresenham's circle algorithm
;
; * parameters : 
;    - D : x coordinate of center
;    - E : y coordinate of center
;    - B : radius - allow djnz's              
;
; * code size : 116 bytes
;

#include "ti-85.h"

        .org    0
        .db     "Circle",0

;------------------------------
; test procedure
;------------------------------

Start:                          
        ld      A,4
        out     (5),A
        ROM_CALL(CLEARLCD)
        ld      DE,$4020                ;coordinates of center
        ld      B,$15                   ;radius
LoopE:
        CALL_(Circle)
        djnz    LoopE
Wait:
        call    GET_KEY
        or      A
        ret     NZ
        jr      Wait

;------------------------------
; beginning of circle
;------------------------------

Circle:                         
        push    BC              ;can be removed
        push    DE              ;can be removed              
        ld      H,0
        ld      L,B
        rlc     B
        ld      A,$03
        sub     B
        push    AF
Loop:
        ld      A,D             ;Point #1
        add     A,H
        ld      B,A
        ld      A,E
        add     A,L
        ld      C,A
        CALL_(PointOn)
        
        ld      A,E             ;Point #2
        sub     L
        ld      C,A
        CALL_(PointOn)
        
        ld      A,D             ;Point #4
        sub     H
        ld      B,A
        CALL_(PointOn)
        
        ld      A,E             ;Point #3
        add     A,L
        ld      C,A
        CALL_(PointOn)
        
        ld      A,D             ;Point #5
        add     A,L
        ld      B,A
        ld      A,E
        add     A,H
        ld      C,A
        CALL_(PointOn)
        
        ld      A,E             ;Point #6
        sub     H
        ld      C,A
        CALL_(PointOn)
        
        ld      A,D             ;Point #8
        sub     L
        ld      B,A
        CALL_(PointOn)
        
        ld      A,E             ;Point #7
        add     A,H
        ld      C,A
        CALL_(PointOn)
        
        ld      A,H             ;is the circle finished ?
        sub     L
        jr      NC,EndCircle     ;yes
        pop     AF
        ld      B,A
        ld      A,H
        bit     7,B
        jr      Z,Pos
Neg:                            ;case d<0
        rla
        rla
        add     A,B
        add     A,$06
        push    AF
        jr      EndC
Pos:                            ;case d>=0
        sub     L
        rla
        rla
        add     A,B
        add     A,$0A
        push    AF
        dec     L
EndC:                           ;one loop has been performed
        inc     H
        jr      Loop            
EndCircle:
        pop     AF              ;MUST NOT BE REMOVED
        pop     DE              ;can be removed
        pop     BC              ;can be removed
        ret

;------------------------------
; End of circle
;------------------------------

PointOn:
        push    HL              ;MUST NOT BE REMOVED
        push    DE              ;MUST NOT BE REMOVED
        ROM_CALL(FIND_PIXEL)
        ld      DE,$FC00
        add     HL,DE
        or      (HL)
        ld      (HL),A
        pop     DE              ;MUST NOT BE REMOVED
        pop     HL              ;MUST NOT BE REMOVED
        ret

        .end

