* *``````````````````````````````* * TCIRCLE (NATHAN RIGGS) * * * * INPUT: * * * * ZPW1 = X CENTER POS * * ZPW2 = Y CENTER POS * * ZPB1 = RADIUS * * ZPB2 = FILL CHARACTER * * * * OUTPUT: * * * * USES BRESENHAM'S CIRCLE * * ALGORITHM TO DRAW A CIRCLE * * TO THE 40-COLUMN TEXTMODE * * SCREEN. * * * * DESTROY: NZCIDV * * * * * * CYCLES: 601+ * * SIZE: 371 BYTES * * * * SUBSTANTIAL DEBT IS OWED TO * * MARC GOLOMBECK AND HIS GREAT * * IMPLEMENTATION OF THE * * BRESENHAM CIRCLE ALGORITHM * * IN 6502 AND APPLESOFT, WHICH * * IS BASED ON THE GERMAN LANG * * VERSION OF WIKIPEDIA'S ENTRY * * ON THE ALGORITHM THAT HAS A * * BASIC PSEUDOCODE EXAMPLE. * * THAT EXAMPLE, WITH CHANGED * * VARIABLE NAMES, IS INCLUDED * * BELOW. * *,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,* * ]XC EQU ZPW1 ; X CENTER POSITION ]YC EQU ZPW2 ; Y CENTER POSITION ]R EQU ZPB1 ; RADIUS ]F EQU ZPB2 ; FILL CHAR * ]Y EQU ZPW3 ; CENTER YPOS ]X EQU ZPW3+1 ; CENTER XPOS ]DY EQU ZPW4 ; CHANGE IN Y ]DX EQU ZPW4+1 ; CHANGE IN X ]ERR EQU ZPW5 ; ERROR VALUE ]DIAM EQU ZPW5+1 ; DIAMETER ]XT EQU ZPW6 ; INVERTED X VALUE ]YT EQU ZPW6+1 ; INVERTED Y VALUE * ******************************** * * * BASIC PSEUDOCODE * * * ******************************** * * X = R * Y = 0 * ERROR = R * SETPIXEL XC + X, YC + Y * WHILE Y < X * DY = Y * 2 + 1 * Y = Y + 1 * ERROR = ERROR - DY * IF ERROR < 0 THEN * DX = 1 - X * 2 * X = X - 1 * ERROR = ERROR - DX * END IF * SETPIXEL XC + X, YC + Y * SETPIXEL XC - X, YC + Y * SETPIXEL XC - X, YC - Y * SETPIXEL XC + X, YC - Y * SETPIXEL XC + Y, YC + X * SETPIXEL XC - Y, YC + X * SETPIXEL XC - Y, YC - X * SETPIXEL XC + Y, YC - X * WEND * ******************************** * TCIRCLE * ** FIRST, INITIALIZE VARIABLES * LDA #0 ; {2C2B} CLEAR YPOS {NZ} STA ]Y ; {4C3B} LDA ]R ; {4C3B} LOAD RADIUS {NZ} STA ]X ; {4C3B} X = RADIUS STA ]ERR ; {4C3B} ERROR = RADIUS ASL ; {2C1B} R * 2 {NZC} STA ]DIAM ; {4C3B} STORE DIAMETER * ** NOW DRAW FIRST PART OF CIRCLE * ** CALCULATE -X AND -Y * LDA ]X ; {4C3B} GET XPOS {NZ} NEGA ; {6C5B} {NZCV} STA ]XT ; {4C3B} STORE NEGATED IN XT LDA ]Y ; {4C3B} GET YPOS {NZ} NEGA ; {6C5B} {NZCV} STA ]YT ; {4C3B} STORE NEGATED IN YT * ** PLOT XC+X,YC * LDA ]XC ; {4C3B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]X ; {4C3B} ADD CURRENT XPOS {NZCV} TAY ; {2C1B} TRANSER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {4C3B} LOAD CIRCLE CENTER YPOS {NZ} JSR GBCALC ; {43C3B} GET X,Y SCREEN MEMORY POS LDA ]F ; {4C3B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {5C3B} STORE IN SCREEN MEMORY * ** PLOT XC-X,YC * LDA ]XC ; {4C3B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]XT ; {4C3B} ADD NEGATED CURRENT XPOS {NZCV} TAX ; {2C1B} TRANSFER TO .X {NZ} TAY ; {2C1B} AND .Y {NZ} LDA ]YC ; {4C3B} LOAD CIRCLE CENTER YPOS {NZ} JSR GBCALC ; {43C3B} GET X,Y SCREEN MEMORY POS LDA ]F ; {4C3B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {5C3B} STORE IN SCREEN MEMORY * ** PLOT XC,YC+X * LDA ]XC ; {4C3B} LOAD CIRCLE CENTER XPOS {NZ} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {4C3B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]X ; {4C3B} ADD CURRENT XPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN MEMORY POS LDA ]F ; {4C3B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {5C3B} STORE IN SCREEN MEMORY * ** PLOT XC,YC-X * LDA ]XC ; {4C3B} LOAD CIRCLE CENTER XPOS {NZ} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {4C3B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]XT ; {4C3B} ADD NEGATED CURRENT XPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN MEMORY POS LDA ]F ; {4C3B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {5C3B} STORE IN SCREEN MEMORY * ** NOW LOOP UNTIL CIRCLE IS FINISHED * :LOOP * ** CHECK IF CIRCLE FINISHED * LDA ]Y ; {4C3B} IF Y > X {NZ} CMP ]X ; {4C3B} {NZC} BCC :LPCONT ; {3C2B} CONTINUE LOOPING JMP :EXIT ; {3C3B} OTHERWISE, CIRCLE DONE :LPCONT :STEPY ; STEP THE Y POSITION LDA ]Y ; {4C3B} LOAD YPOS {NZ} ASL ; {2C1B} MULTIPLY BY 2 {NZC} *CLC ADC #1 ; {3C2B} ADD +1 {NZCV} STA ]DY ; {4C3B} STORE CHANGE OF Y INC ]Y ; {6C3B} INCREASE YPOS {NZ} LDA ]DY ; {3C2B} NEGATE {NZ} NEGA ; {6C5B} {NZCV} ADC ]ERR ; {4C3B} ADD ERR {NZCV} STA ]ERR ; {4C3B} ERR = ERR - DY BPL :PLOT ; {3C2B} IF ERR IS +, SKIP TO PLOT :STEPX LDA ]X ; {3C2B} LOAD XPOS {NZ} ASL ; {2C1B} MULTIPLY BY 2 {NZC} NEGA ; {6C5B} NEGATE {NZCV} ADC #1 ; {3C2B} (X*2) + 1 {NZCV} STA ]DX ; {4C3B} STORE CHANGE OF X DEC ]X ; {6C3B} DECREASE YPOS {NZ} LDA ]DX ; {3C2B} NEGATE {NZ} NEGA ; {6C5B} {NZCV} ADC ]ERR ; {4C3B} ADD ERR {NZCV} STA ]ERR ; {4C3B} ERR = ERR - DX * :PLOT * ** NOW CALCULATE -X AND -Y * LDA ]X ; {3C2B} {NZ} NEGA ; {6C5B} NEGATE {NZCV} STA ]XT ; {4C3B} LDA ]Y ; {3C2B} {NZ} NEGA ; {6C5B} NEGATE {NZCV} STA ]YT ; {4C3B} * ** NOW PLOT CIRCLE OCTANTS * ** PLOT XC+X,YC+Y * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]X ; {4C3B} ADD CURRENT XPOS {NZCV} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]Y ; {4C3B} ADD CURRENT YPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC-X,YC+Y * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]XT ; {4C3B} ADD NEGATED CURRENT XPOS {NZCV} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND TO .X {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]Y ; {4C3B} ADD CURRENT YPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC-X,YC-Y * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]XT ; {4C3B} ADD NEGATED CURRENT XPOS {NZCV} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]YT ; {4C3B} ADD NEGATED CURRENT YPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHARACTER {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC+X,YC-Y * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]X ; {4C3B} ADD CURRENT XPOS {NZCV} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]YT ; {4C3B} ADD NEGATE CURRENT YPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC+Y,YC+X * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]Y ; {4C3B} ADD CURRENT YPOS {NZCV} TAX ; {2C1B} TRANSFER TO .X {NZ} TAY ; {2C1B} AND .Y {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]X ; {4C3B} ADD CURRENT XPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC-Y,YC+X * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]YT ; {4C3B} ADD NEGATED CURRENT YPOS {NZCV} TAX ; {2C1B} TRANSFER TO .X {NZ} TAY ; {2C1B} AND .Y {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]X ; {4C3B} ADD CURRENT XPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC-Y,YC-X * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]YT ; {4C3B} ADD NEGATED CURRENT YPOS {NZCV} TAX ; {2C1B} TRANSFER TO .X {NZ} TAY ; {2C1B} AND .Y {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]XT ; {4C3B} ADD NEGATED CURRENT XPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS * ** PLOT XC+Y,YC-X * LDA ]XC ; {3C2B} LOAD CIRCLE CENTER XPOS {NZ} CLC ; {2C1B} CLEAR CARRY {C=0} ADC ]Y ; {4C3B} ADD CURRENT YPOS {NZCV} TAY ; {2C1B} TRANSFER TO .Y {NZ} TAX ; {2C1B} AND .X {NZ} LDA ]YC ; {3C2B} LOAD CIRCLE CENTER YPOS {NZ} CLC ; {2C1B} {C=0} ADC ]XT ; {4C3B} ADD NEGATED CURRENT XPOS {NZCV} JSR GBCALC ; {43C3B} GET X,Y SCREEN ADDRESS {NZCV} LDA ]F ; {3C2B} LOAD FILL CHAR {NZ} STA (GBPSH),Y ; {6C2B} STORE AT SCREEN ADDRESS JMP :LOOP ; {3C3B} LOOP UNTIL FINISHED :EXIT RTS ; {6C1B}