Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Dec 8th, 2004, 10:45 PM   #1
saxman
Newbie
 
Join Date: Dec 2004
Posts: 7
Rep Power: 0 saxman is on a distinguished road
I'm not new to x86 ASM, but I am new to the square-root-related instructions that Intel has provided. I don't know what I'm doing wrong in my program, but I get a divide overflow. Perhaps someone could take a look at my code and see what is causing this.

This program isn't finished yet, but it's going to draw a sphere. I am doing it purely out of experimental interest. Right now I am just trying to get it to draw pixels to the screen, but I won't know if my algorithms and such are right or not if I can't see anything but an error. I wonder if it's the way I've used the square-root. This is the first time I've made use of it in ASM, so I don't even know if I did it right or not.

Anyway, any help would be appreciated.

BTW: If you find the below code to be hard to read due to the lack of 'tabs' on these forums, you can download the source file -- http://shadowsoft-games.com/saxman/3D.ASM


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This program is designed to draw a sphere using the following:
;
; Ymax = (Ry/Rx) SQRT(Rx^2 - X^2)
; Zmax = (Rz/Ry) SQRT(Ry^2 - Y^2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

jmp	start



xpos* dw	?*; X position (0-319)
ypos* db	?*; Y position (0-199)
zpos* db	?*; Z position (0-255)
xrad* db	64*; X radius (0-255)
yrad* db	64*; Y radius (0-255)
zrad* db	64*; Z radius (0-255)
store1	dd	?*; Used to store a floating-point
ymax* db	?*; Ymax = (Ry/Rx) SQRT(Rx^2 - X^2)
zmax* db	?*; Zmax = (Rz/Ry) SQRT(Ry^2 - Y^2)
palette	db	00, 00, 00, 01, 01, 01, 02, 02, 02, 03, 03, 03
* db	04, 04, 04, 05, 05, 05, 06, 06, 06, 07, 07, 07
* db	08, 08, 08, 09, 09, 09, 10, 10, 10, 11, 11, 11
* db	12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15
* db	16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19
* db	20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23
* db	24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27
* db	28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31
* db	32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35
* db	36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39
* db	40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43
* db	44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47
* db	48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51
* db	52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55
* db	56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59
* db	60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63



start:
mov	ax, 13h* *; Setup 320x200 video mode
int	10h
mov	ax, 0a000h* *; Set the video address
mov	es, ax

write_palette:
mov	si, offset palette
mov	cl, 192* *; Read 192 color values (64 total colors)
mov	dx, 03c8h* *; Set the palette address
xor** al, al
out	dx, al
cld
inc	dx
rep	outsb

draw_setup:
mov	di, 16000* *; Start from the center of the screen
mov	dx, 63* *; DX is our color selection
call	calculate_ymax



draw_y:
;mov	dx, 63
mov	es:[di], dx
inc	ypos
sub	di, 320
mov	al, ymax
cmp	ypos, al
jl	draw_y

inc	xpos
mov	di, 16000
add	di, xpos
call	calculate_ymax
mov	ax, word xrad
cmp	xpos, ax
jl	draw_y



calculate_ymax:
; Ymax = (Ry/Rx) SQRT(Rx^2 - X^2);
push	ax
push	dx
mov	ax, word yrad
div	xrad
mov	bx, ax* *; BX acts as (Ry/Rx)
mov	ax, word xrad
mul	xrad
push	ax
mov	ax, xpos
mul	xrad
pop	dx
sub	ax, dx
mov	word store1, ax
; (Ry/Rx)
fld	store1* *; Load X
fld	st(0)* **; Duplicate X on TOS
fsqrt* * *; Computer SQRT(X**2 + Y**2)
fst	store1* *; Store away result in Z
mov	ax, word store1
mul	bx
mov	ymax, al
pop	dx
pop	ax
ret
;
saxman is offline   Reply With Quote
Old Dec 9th, 2004, 12:09 PM   #2
kurifu
Expert Programmer
 
kurifu's Avatar
 
Join Date: Jul 2004
Location: Halifax, Nova Scotia (Canada)
Posts: 784
Rep Power: 5 kurifu is on a distinguished road
Send a message via ICQ to kurifu Send a message via MSN to kurifu
When you divide with asm this is what happens.

You take usually a 32bit value (though it can be 16bit, or 8bit) perform the division and store both the result and the remainder (no decimal values here) into the same block of data we performed the operation on.

Which means dividing a 32bit value results in that 32bit value being broken into a 16bit result and a 16bit remainder. I am sure you can see where this goes wrong now...

What happens if you take a 32bit value, which requires all 32 bits and divide that value by 1? Well as you can imagine the result WILL NOT fit in the 16 bit register in which it is supposed to fit. One of your flags should be raised for this exception, probably OF, you will need to verify that and start checking that flag to make sure that the division occured without error and deal with the error when it occures appropriatly.
__________________
Clifford Matthew Roche <geek@cliffordroche.com>
Web Hosting: http://www.crd-hosting.com
Consulting: http://www.crdev-consulting.com
kurifu is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 9:42 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC