A85: Cube
[Prev][Next][Index][Thread]
A85: Cube
I know I am really reinventing the wheel here, but I'm attempting to
write an asm program to rotate a cube in space. I'm going to need to use
trig a lot so if anyone could explain the trig routines below that I got
off of ticalc.org I would really appreciate it. Thanks in advance.
Sorry for posting all of this.
; Date: Wed, 15 May 1996 22:27:55 -0400 (EDT); From: Jingyang Xu
[br00416@bingsuns.cc.binghamton.edu]; Subject: LZ: Trig Routines:
SIN/COS/TAN; Someone asked me about these and here are the bug-free
version of my; sin/cos/tan routines:; Note that sin and cos uses the same
table and tan uses its own table.; The arguments to sinx and cosx are:
a=multiplier bc=angle; and the return is now in bc: b=integer part
c=fractional part.; So bc is a 16 bit signed number, the key here is
signed - if the high bit; of b is set, that means bc is the twos
complement of the positive value; of bc.; For the tangent routine. de is
the multiplier (this is a 16 bit; multiplier) and hl is the angle. I
think it returns the result in hl, in; the same format as that for
bc.AdjustAngleinBC: xor a cp b jr
z,Alldone ld h,b ld l,c ld
bc,360 and a sbc hl,bc jr
nc,AAHalfDone add hl,bcAAHalfDone: ld
b,h ld c,l jr
AlldoneAlldone: retsinx: push af ;save
argument ld d,1 ;d=1, use for later ld
hl,180 and a ;clear carry sbc
hl,bc jr nc,LessE180 ;is angle greater than 180
degrees?Great180: ld h,b ; ld
l,c ;load bc into hl ld bc,180
; and a ; bc=bc-180 sbc hl,bc
; ld b,h ; ld c,l
;load hl into bc inc d ; d=2, remember
negatedLessE180: ;0<=bc<=180 -> 0 is in b and
0<=c<=180 ld a,d ;save d ld
de,(PROGRAM_ADDR) ld hl,Trig_Look_Up ;hl=addr of
table add hl,de ld d,a ;restore
d ld a,c ;load angle into accumulator cp
90 ;is it 90 degrees? jr nz,not90 ld
a,128 ;if 90 degrees, sin90=1 jr
sinloadednot90: sub 90 jr nc,Greater90 ;is
angle less than or greater than 90Less90: add hl,bc
;if less than, go directly to table ld a,(hl) jr
sinloadedGreater90: ld a,180 ;if greater,
sin(x)=sin(180-x) sub c ;subtract from
180 ld c,a add hl,bc ;read from
table ld a,(hl)sinloaded: ;x/128 is in
a, d will determine sign ld b,a ;save
result pop af ;get multiplicand back bit
7,a ;test to see if a is negative jr
z,apositive neg ;if negative,
negate inc d ;store negative memory in
dapositive: ;now we want a*b/128 ld e,a
;save a ld a,b ; cp 0
;see if e=0 jr z,multiplyby0 ; ld
c,0 xor asinmultiplyloop: add a,e jr
nc,nocarry ;multipy a by b inc c ;16bit
result in canocarry: djnz sinmultiplyloop rl
a ;shift ca to the left rl c
;ca/128 now in c ld b,c ld c,a dec d
jr z,sinxend and a ld hl,0 sbc
hl,bc ld b,h ld c,l dec d jr
z,sinxend and a ld hl,0 sbc hl,bc
ld b,h ld c,l dec d jr
z,sinxendmultiplyby0: ld
bc,0sinxend: retcosx: ld hl,90 add
hl,bc ld b,h ld c,l ld
d,a CALL_(AdjustAngleinBC) ld
a,d CALL_(sinx) ret Trig_Look_Up: .db
0,2,4,6,8,11,13,15,17,20 .db
22,24,26,28,30,33,35,37,39,41 .db
43,45,47,50,52,54,56,58,60,62 .db
64,65,67,69,71,73,75,77,78,80 .db
82,83,85,87,88,90,92,93,95,96 .db
98,99,100,102,103,104,106,107,108,109 .db
110,111,113,114,115,116,116,117,118,119 .db
120,121,121,122,123,123,124,124,125,125 .db
126,126,126,127,127,127,127,127,127,127tanx:
;multiplier in de, angle in hl push de push de
;save multiplier ld b,h
;make another copy of angle in bc ld c,l
; ld de,180 ;subtract 180
from and a ;angle to see if it is
sbc hl,de ;greater than 180 jr
c,tanLess180 ;if not, goto tanless180 ld
b,h ;if greater than 180, load angle ld
c,l ;minus 180 into bctanLess180:
;bc has the semi-reference inc d
;load 1 into d ld hl,90 ;subtract angle
from 90 and a ;to see if it is less than
sbc hl,bc ;90 jr nc,tanLess90
;if so, jump to tanless90 ld hl,180
;if greater, load 180 into hl and a
;subtract angle from it sbc hl,bc ;
inc d ;load 2 into d ld b,h
;save final reference in bc ld c,l
;tanLess90: ;already has reference
angle sla c ;multiply bc by 2 rl
b ; ld a,d
;preserves d ld de,(PROGRAM_ADDR) ;reference the table
ld hl,Tan_Table ; add hl,de
; add hl,bc ; ld d,(hl)
; inc hl ;load result into
de ld e,(hl) ; ld h,a
;whatever we had in d before dec h
;see if h=1 or 2 jr z,tanNotNegative ;if 1,
positive set 7,d ;if result negative, then
tell it sotanNotNegative: ;guess what pop
hl ;get multiplier CALL_(MulDEbyHL)
;multiply the result by the multiplier push af
ld h,c ld l,d bit 7,e jr
z,TanRoundDown inc hlTanRoundDown: pop af jr
z,ResPositive ex de,hl ld hl,0 and
a sbc hl,de pop de retResPositive:
pop de retMulDEbyHL: ld
ix,TempLine bit 7,d jr z,DEPositive res
7,d bit 7,h jr z,HLPositive res 7,h
jr DEPositiveHLPositive: set 7,hDEPositive: ld
(ix+0),h ld (ix+1),l ld b,8 xor a
ld c,a ld hl,0MulLoop1: rrc
(ix+1) jr nc,NoAdd1 add hl,de adc
a,cNoAdd1: sla e rl d rl c djnz
MulLoop1 ld b,7 ld e,d ld d,c
ld c,0 rl c ld (ix+5),l ld l,h
ld h,a xor aMulLoop2: rrc
(ix+0) jr nc,NoAdd2 add hl,de adc
a,cNoAdd2: sla e rl d rl c djnz
MulLoop2 ld b,a ld c,h ld d,l
ld e,(ix+5) bit 0,(ix+0) ret Tan_Table:
.db 0,0,0,4,0,9,0,13,0,18,0,22,0,27,0,31,0,36,0,41 .db
0,45,0,50,0,54,0,59,0,64,0,69,0,73,0,78,0,83,0,88 .db
0,93,0,98,0,103,0,109,0,114,0,119,0,125,0,130,0,136,0,142 .db
0,148,0,154,0,160,0,166,0,173,0,179,0,186,0,193,0,200,0,207 .db
0,215,0,223,0,231,0,239,0,247,1,0,1,9,1,19,1,28,1,38 .db
1,49,1,60,1,72,1,84,1,96,1,110,1,124,1,138,1,154,1,170 .db
1,187,1,206,1,225,1,246,2,13,2,37,2,63,2,91,2,122,2,155 .db
2,191,2,231,3,20,3,69,3,125,3,187,4,3,4,85,4,180,5,37 .db
5,172,6,80,7,30,8,37,9,132,11,110,14,77,19,21,28,163,57,74
_____________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]