# circles in ASM

29 views

### Robert McNulty

Nov 29, 1997, 3:00:00 AM11/29/97
to

How do you draw a circle in ASM?
I think I understand it.

### Jim Neil

Nov 29, 1997, 3:00:00 AM11/29/97

Robert McNulty wrote:
Hi-

> How do you draw a circle in ASM?
> I think I understand it.

Here is a circle routine coded in TERSE along with the .ASM
generated by the TERSE compiler. It should get you started.

I hope this helps...

Jim Neil ___ ___/ ____/ ___ / ____/ ____/
Creator of The / / / / / /
TERSE Programming Language / ___/ ___/ ____ / ___/
http://www.terse.com / / / \ / /
jim-...@digital.net __/ ______/ __/ __\ ______/ ______/ TM
ISBN: 0-9652660-0-1

---------------------------------- Terse
--------------------------------------
\\\\\\\\\\
\ CIRCLE \
\\\\\\\\\\
\
\
\ Draw a cricle using the Neil-Routh Medthod.
\
\ Entry Conditions:
\ ax = scratch.
\ xc = x-coord of center of the circle.
\ yc = y-coord of center of the circle.
\ r = radius of the circle.
\ c = color of the circle.
\ x = scratch.
\ y = scratch.
\ p = scratch.
\ q = scratch.
\
\
\

CIRCLE Proc Near; \ procedure to draw circle.

p = 0; x = 0; q = y = ax = r ? <> \ initialization.
{ \ do if r is non-zero.
=.Pixel; \ Pixel();
ax = x+; x = ax; \ x++;
ax < 1-; p + ax; \ p += ( 2 * x - 1 );
ax = p - q ? =>> \ if ( p => q )
{ \ {
ax = y-; y = ax; \ y--;
ax < 1; q + ax; \ q += ( 2 * y );
}; \ }
ax = x - y ? \
}<<=, \ while ( x <= y );
{
=xc; =yc; =c; =.PSet; \ else, plot degenerate circle.
};

.=; \ return.....................

CIRCLE EndP; \ end procedure to draw circle.

\\\\\\\\\
\ Pixel \
\\\\\\\\\
\
\
\ Utility routine for drawing a cricle using Bresenham's Medthod.
\
\
\ Entry Conditions:
\ ax = scratch.
\ xc = x-coord of center of the circle.
\ yc = y-coord of center of the circle.
\ r = radius of the circle.
\ c = color of the circle.
\ x = relative x-coord.
\ y = relative y-coord.
\
\

Pixel Proc Near;

ax = xc + y; =ax; ax = yc - x; =ax; =c; =.PSet; \ octant 1
ax = xc + x; =ax; ax = yc - y; =ax; =c; =.PSet; \ octant 2
ax = xc - x; =ax; ax = yc - y; =ax; =c; =.PSet; \ octant 3
ax = xc - y; =ax; ax = yc - x; =ax; =c; =.PSet; \ octant 4
ax = xc - y; =ax; ax = yc + x; =ax; =c; =.PSet; \ octant 5
ax = xc - x; =ax; ax = yc + y; =ax; =c; =.PSet; \ octant 6
ax = xc + x; =ax; ax = yc + y; =ax; =c; =.PSet; \ octant 7
ax = xc + y; =ax; ax = yc + x; =ax; =c; =.PSet; \ octant 8
.=; \ return.

Pixel EndP;

\\\\\\\\
\ PSet \
\\\\\\\\
\
\
\ PSet sets the specified VGA pixel to the specified color (0-255).
\
\ Calling Sequence:
\ =xpos =ypos =color; =.PSet;
\
\ Entry Conditions:
\ Stack Frame contains:
\ pc (pixel color).
\ yi (y input).
\ xi (x input).
\
\ Exit Conditions:
\ Stack Frame removed:
\ All Registers are perserved.
\
\

xi Equ [bp][8]; \ x input.
yi Equ [bp][6]; \ y input.
pc Equ [bp][4]; \ pixel color.
n_parms = 3;

data Segment;

" xo =0, yo =0; \ save locs for last coords.

data EndS;

VGA_RAM Equ 0A000h; \ start segment for VGA text RAM.
GL Equ 320; \ number of bytes in line of graphics.

PSet Proc Near;

=bp; bp = sp; \ save bp & set-up stk frame.
=ax =dx =di; \ save regs.

{ \ do...
ax = yi - Y ? =>>; \ ax = yi, exit if clipped.
dx = GL; **dx; di = ax; \ di = row address.
ax = xi - X ? =>>; \ ax = xi, exit if clipped.
di + ax; \ di = byte address in GRAM.
al = pc; \ al = color to plot.
bp = ds; ds = dx = VGA_RAM; \ save ds, ds = screen segment address.
[di] = al; \ draw the pixel.
ds = bp; \ restore ds.
}; \ od...

bp= ax= dx= di=; \ restore registers.
.=n_parms*2; \ return with clean stack......

PSet EndP;

-------------------------------- .ASM
-----------------------------------------

;;;;;;;;;;
; CIRCLE ;
;;;;;;;;;;
;
;
; Draw a cricle using the Neil-Routh Medthod.
;
; Entry Conditions:
; ax = scratch.
; xc = x-coord of center of the circle.
; yc = y-coord of center of the circle.
; r = radius of the circle.
; c = color of the circle.
; x = scratch.
; y = scratch.
; p = scratch.
; q = scratch.
;
;
;
CIRCLE Proc Near ; procedure to draw circle.
Mov p,0
Mov x,0
Mov ax,r
Test ax,ax
Mov y,ax
Mov q,ax ; initialization.
Jz ?Els0001
?Top0001: ; do if r is non-zero.
Call Pixel ; Pixel();
Mov ax,x
Inc ax
Mov x,ax ; x++;
Shl ax,1
Dec ax
Add p,ax ; p += ( 2 * x - 1 );
Mov ax,p
Cmp ax,q ; if ( p => q )
Jb ?Els0002
?Top0002: ; {
Mov ax,y
Dec ax
Mov y,ax ; y--;
Shl ax,1
Add q,ax ; q += ( 2 * y );
?Els0002:
?End0002: ; }
Mov ax,x
Cmp ax,y ;
; while ( x <= y );
Jbe ?Top0001
Jmp Short ?End0001
?Els0001:
?Top0003:
Push xc
Push yc
Push c
Call PSet ; else, plot degenerate circle.
?Els0003:
?End0001:
Ret ; return.....................
CIRCLE EndP ; end procedure to draw circle.
;;;;;;;;;
; Pixel ;
;;;;;;;;;
;
;
; Utility routine for drawing a cricle using Bresenham's Medthod.
;
;
; Entry Conditions:
; ax = scratch.
; xc = x-coord of center of the circle.
; yc = y-coord of center of the circle.
; r = radius of the circle.
; c = color of the circle.
; x = relative x-coord.
; y = relative y-coord.
;
;
Pixel Proc Near
Mov ax,xc
Push ax
Mov ax,yc
Sub ax,x
Push ax
Push c
Call PSet ; octant 1
Mov ax,xc
Push ax
Mov ax,yc
Sub ax,y
Push ax
Push c
Call PSet ; octant 2
Mov ax,xc
Sub ax,x
Push ax
Mov ax,yc
Sub ax,y
Push ax
Push c
Call PSet ; octant 3
Mov ax,xc
Sub ax,y
Push ax
Mov ax,yc
Sub ax,x
Push ax
Push c
Call PSet ; octant 4
Mov ax,xc
Sub ax,y
Push ax
Mov ax,yc
Push ax
Push c
Call PSet ; octant 5
Mov ax,xc
Sub ax,x
Push ax
Mov ax,yc
Push ax
Push c
Call PSet ; octant 6
Mov ax,xc
Push ax
Mov ax,yc
Push ax
Push c
Call PSet ; octant 7
Mov ax,xc
Push ax
Mov ax,yc
Push ax
Push c
Call PSet ; octant 8
Ret ; return.
Pixel EndP
;;;;;;;;
; PSet ;
;;;;;;;;
;
;
; PSet sets the specified VGA pixel to the specified color (0-255).
;
; Calling Sequence:
; Push xpos
; Push ypos
; Push color
; Call PSet
;
; Entry Conditions:
; Stack Frame contains:
; pc (pixel color).
; yi (y input).
; xi (x input).
;
; Exit Conditions:
; Stack Frame removed:
; All Registers are perserved.
;
;
xi Equ [bp][8] ; x input.
yi Equ [bp][6] ; y input.
pc Equ [bp][4] ; pixel color.
n_parms = 3
data Segment
xo dw 0
yo dw 0 ; save locs for last coords.
data EndS
VGA_RAM Equ 0A000h ; start segment for VGA text RAM.
GL Equ 320 ; number of bytes in line of graphics.
PSet Proc Near
Push bp
Mov bp,sp ; save bp & set-up stk frame.
Push ax
Push dx
Push di ; save regs.
?Top0004: ; do...
Mov ax,yi
Cmp ax,Y
Jae ?End0004 ; ax = yi, exit if clipped.
Mov dx,GL
Mul dx
Mov di,ax ; di = row address.
Mov ax,xi
Cmp ax,X
Jae ?End0004 ; ax = xi, exit if clipped.
Add di,ax ; di = byte address in GRAM.
Mov al,pc ; al = color to plot.
Mov bp,ds
Mov dx,VGA_RAM
Mov ds,dx ; save ds, ds = screen segment address.
Mov [di],al ; draw the pixel.
Mov ds,bp ; restore ds.
?Els0004:
?End0004: ; od...
Pop di
Pop dx
Pop ax
Pop bp ; restore registers.
Ret n_parms*2 ; return with clean stack......
PSet EndP

### George C. Lindauer

Nov 30, 1997, 3:00:00 AM11/30/97
to

Robert McNulty (bobb...@www.the-link.net) wrote:
> How do you draw a circle in ASM?
> I think I understand it.

just get a graphics circle algorithm (there is one similar to
bresenham's line formulat) and code it in assembly.

David

### Mike

Nov 30, 1997, 3:00:00 AM11/30/97
to

Robert McNulty <bobb...@www.the-link.net> wrote in article
<34815859...@news.magicnet.net>...
: How do you draw a circle in ASM?

: I think I understand it.

Try a web search for Hardenburgh+circle.

Mike

m.fere...@remove.this.btinternet.com

### Hal Hardenbergh

Dec 3, 1997, 3:00:00 AM12/3/97
to

(This is an old email, I forget to whom but he was in Africa IIRC.)

>I read Abrash's book on Zen of Graphics programming>

Good.

>he mentioned that you had a routine for drawing circles and
>ellipses

I went to Michael with an algorithm that was as simple as I
could figure out (I think it used one multiply at the start)
and Michael simplified _that_!

>I asked him for the routine, but said that you never got
>round to publishing it.

True... but Michael did. It's the algorithms in his book.
Look, there are two ways to publish an algorithm. One is to
write pseudocode that is machine-independent. Obviously,
this will not run on any machine! For a skilled programmer
whose skills relate to machine X, that algorithm can be
reduced to practice - it can be made to run on machine X.

What I had done was devise algorithms for the 68000-based
Atari ST. In 1989 Michael and I were both writing for the
late Programmer's Journal. Mike knew how to program x86s
and VGAs in assy (to say the least!) and I didn't. As Mike
explains in his book, I approached him to collaborate on an
article, but as it turned out, Mike wrote the articles
(plural) alone, giving me credit for the original algorithm
(which Michael improved).

So, Michael _did_ make our algorithm run on machine X (X =
IBM PC/AT).

I later wrote up the circle algorithm in pseudocode form. I
forget what I did with the ellipse stuff, but Mike published
both the circle and the ellipse stuff in IBM PC/AT form.

Here's my circle pseudocode:

15 Jan 1990
HOW TO PLOT CIRCLES USING NO MULTIPLIES,
DIVIDES, SQUARE ROOTS, OR TRIG FUNCTIONS

THE INPUT PARAMETERS

The center coordinates, Xc and Yc, and the radius R are
required to be integer values, with no fractional parts.

THE ENVIRONMENT

It is assumed that we are using a normal CRT or 300 DPI
laser printer. In either case the radius can be greater
than 256 but is a heck of a lot less than 65536. This
determines the size of the integers we will use for
calculating the pixels to be plotted.

LOOKUP TABLES

Using lookup tables is too easy, and is considered cheating.
We will not use lookup tables here. Lookup tables will only
be used by people who want to run fast, and we have it on
good authority that nobody is interested in running fast
these days.

PLOTTING X,Y COORDINATES

How to do this depends on the details of the hardware and of
the "display" memory map. We will concentrate here on the
circle algorithm, which is mostly not hardware dependent.
Admittedly, some microprocessors do conditional branches
more gracefully than others. We will plot the initial 4
coordinate points, and subsequently use 8-way symmetry. You
are expected to know how to do this.

GETTING ON WITH IT:

Begin

Set 2Y = R + R: Set 2X = 1: Set Yt = R: 4-way PLOT(X,Y)

Label 1: Yt = Yt - 2X: 2X = 2X + 2: If Yt >= 0 Goto Label 2

If 2X >= 2Y Goto End

2Y = 2Y - 2: Yt = Yt + Y

Label 2: 8-way PLOT(X,Y): Goto Label 1

End

AN APOLOGY

The management (Hal Hardenbergh and Michael Abrash) wish to
apologize for the complexity ofthe above algorithm.

>Is there any way that I can get my hands on this routine.

You just did.

Hal Hardenbergh [not Hardenburgh]