29 views

Skip to first unread message

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

to

How do you draw a circle in ASM?

I think I understand it.

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

to bobb...@www.the-link.net

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:

\ return address.

\ 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

Add ax,y

Push ax

Mov ax,yc

Sub ax,x

Push ax

Push c

Call PSet ; octant 1

Mov ax,xc

Add ax,x

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

Add ax,x

Push ax

Push c

Call PSet ; octant 5

Mov ax,xc

Sub ax,x

Push ax

Mov ax,yc

Add ax,y

Push ax

Push c

Call PSet ; octant 6

Mov ax,xc

Add ax,x

Push ax

Mov ax,yc

Add ax,y

Push ax

Push c

Call PSet ; octant 7

Mov ax,xc

Add ax,y

Push ax

Mov ax,yc

Add ax,x

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:

; return address.

; 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

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

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

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]

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu