home *** CD-ROM | disk | FTP | other *** search
- ;Figure 2 from "Graphics in 3-D". Micro Cornucopia Magazine Issue #41
-
- ;34010 Multiplication and Division.
-
- fxPt equ 16 ;define fixed point position.
- One equ 10000H ;our representation of the number one.
-
- fxMultiply:
- ;Out: a0 = a0 * a1
- mpys a1, a0 ;signed integer multiplication
- sla 32-fxPt, a0 ;line up high order bits
- srl fxPt, a1 ;line up low order bits
- or a1, a0 ;combine them
- rets
-
- fxDivide:
- ;Out: a0 = a0 / a1
- move a1, a2 ;save divisor
- move a0, a1 ;build dividend in 64 bit register,
- ;with fxPt shift
- sra 32-fxPt, a0 ;high order bits
- sll fxPt, a1 ;low order bits
- divs a2, a0 ;signed integer division
- rets
-
- ;END OF LISTING
-
-
-
-
- ;Figure 3 from "Graphics in 3-D". Micro Cornucopia Magazine Issue #41
-
- ;Fixed Point Square Root
-
- fxSqRoot:
- ;compute square root of a by iterating x = (x + a / x) / 2
- ;out: a0 = sqrt( a0 )
- mmtm sp, a4, a5, a6 ;save registers which hold intermediate values.
- btst 31, a0 ;test for negative argument
- jrnz fs_00 ;if negative, refuse to compute square root.
- movi 10, a6 ;Iteration limit, we'll be
- ;done long before this.
- move a0, a4 ;Starting interation value
- move a0, a5 ;Remember what number we're square rooting
- fs_01: ;Start of iteration loop
- move a5, a0 ;Get a
- move a4, a1 ;and current x
- callr fxDivide ;a0 = a / x
- add a0, a4 ;a4 = x + a / x
- sra 1, a4 ;a4 = ( x + a / x ) / 2
- sub a4, a0 ;compare with old x (sort of)
- sra 1, a0 ;give or take a bit
- dsjne a6, fs_01 ;if not stable repeat
- move a4, a0 ;result to a0
- fs_00:
- mmfm sp, a4, a5, a6 ;restore some registers.
- rets
-
- ;END OF LISTING
-
-
-
-
-
- ;Figure 4 from "Graphics in 3-D". Micro Cornucopia Magazine Issue #41
-
- ;Basic Vector Arithmetic
-
- .data
- vTemp0 .space 60H ;for intermediate values
-
- .text
- vMove:
- ;Out: a9 = a8
- move *a8(px), a0, 1
- move a0, *a9(px), 1
- move a8(py), a0, 1
- move a0, *a9(py), 1
- move *a8(pz), a0, 1
- move a0, *a9(pz), 1
- rets
-
- vAdd:
- ;Out: a10 = a8 + a9
- move *a8(px), a0, 1
- move *a9(px), a1, 1
- add a1, a0
- move a0, *a10(px), 1
- move *a8(py), a0, 1
- move *a9(py), a1, 1
- add a1, a0
- move a0, *a10(py), 1
- move *a8(pz), a0, 1
- move *a9(pz), a1, 1
- add a1, a0
- move a0, *a10(pz), 1
- rets
-
- vSub:
- ;Out: a10 = a8 - a9
- move *a8(px), a0, 1
- move *a9(px), a1, 1
- sub a1, a0
- move a0, *a10(px), 1
- move *a8(py), a0, 1
- move *a9(py), a1, 1
- sub a1, a0
- move a0, *a10(py), 1
- move *a8(pz), a0, 1
- move *a9(pz), a1, 1
- sub a1, a0
- move a0, *a10(pz), 1
- rets
-
- vDot:
- ;Out: a0 = a8 . a9
- mmtm sp, a4
- move *a8, a0, 1 ;Multiply x components
- move *a9, a1, 1
- calla fxMultiply
- move a0, a4 ;start accumulating sum
- move *a8(py), a0, 1
- move *a9(py), a1, 1
- calla fxMultiply ;Multiply y components
- add a0, a4 ;add to sum
- move *a8(pz), a0, 1
- move *a9(pz), a1, 1
- calla fxMultiply ;Multiply z components
- add a4, a0 ;return sum of products
- mmfm sp, a4
- rets
-
- vScale:
- ;Out: a10 = a9 * a8 (a9=scalar, a8=vector)
- move *a8(px), a0, 1
- move a9, a1
- calla fxMultiply ;scale x component
- move a0, *a10(px), 1
- move *a8(py), a0, 1
- move a9, a1
- calla fxMultiply ;scale y component
- move a0, *a10(py), 1
- move *a8(pz), a0, 1
- move a9, a1
- calla fxMultiply ;scale z component
- move a0, *a10(pz), 1
- rets
-
- vCalibrate:
- ;Out: a0 = a8 projected onto and calibrate by the unit vector a9
- mmtm sp, a4, a8
- callr vDot ;a9.a8
- move a0, a4
- move a9, a8
- callr vDot ;a8.a8
- move a0, a1
- move a4, a0
- calla fxDivide ;a0=(a9.a8)/(a8.a8)
- mmfm sp, a4, a8
- rets
-
- vProjection:
- ;Out: a10 = projection of a8 onto a9
- mmtm sp, a8, a9
- callr vCalibrate ;get projection multiplier
- move a9, a8
- move a0, a9
- callr vScale ;scale a9
- mmfm sp, a8, a9
- rets
-
- vPerpendicular:
- ;Out: a10 = component of a8 perpendicular to a9
- mmtm sp, a4, a8, a9, a10
- move a10, a4
- movi vTemp0, a10
- callr vProjection ;temp = projection
- move a10, a9
- move a4, a10
- callr vSub ;subtract projection to get
- perpendicular
- mmfm sp, a4, a8, a9, a10
- rets
-
- vNormalize:
- ;Out: a9 = normalized a8
- mmtm sp, a8, a9, a10
- move a9, a10
- move a8, a9
- callr vDot ;a8.a8 = square of size
- calla fxSqRoot ;size to a0
- move a0, a1
- movi One, a0
- calla fxDivide ;invert size
- move a0, a9
- callr vScale ;then scale
- mmfm sp, a8, a9, a10
- rets
-
- ;END OF LISTING