y1 y0 *x1 x0 Calculation Range k=(y1-y0)*(x1-x0) +-FE01 l=y1*x1 0-FE01 m=y0*x0 0-FE01 n=l+m-k 0-1FC02 l+m 0-1FC02 l-k or m-k +-FE01 x*y=l*65536+n*256+m (for 8 bit Xn/Yn) Example (16x16 bits): y1 y0 ->$20 10 *x1 x0 40 30 k=(20-10)*(40-30)=100 l=20*40=800 m=10*30=300 n=800+300-100=a00 llll0000 -> 08000000 nnnnn00 00a0000 mmmm 0300 ---------------- 2010*4030 = 080a0300 x*y=l*4294967296+n*65536+m (for 16 bit Xn/Yn) example with 16-bit values: 2000 1000 4000 3000 k=1000*1000=0100 0000 l=2000*4000=0800 0000 m=1000*3000=0300 0000 n=00A00 0000 800 0000 0000 0000 a00 0000 0000 300 0000 ------------------ 800 0a00 0300 0000 If multiplies are expensive, this is faster. Estimating 32x32=64; 3x umult16 ~585 adds ~94 total ~679
;set multiplier as mier lda mier ;3 sta p_sqr_lo ;3 (often published as f(x)) sta p_sqr_hi ;3 eor #$ff ;2 sta p_negsqr_lo ;3 (also known as g(x)) sta p_negsqr_hi ;3; 3+3+3+2+3+3 = 17 cycles and ;set multiplicand ldy mand ;3
start xy order 00 01 10 11 xy 01 00 01 10 11 01 00 11 10 11 10 01 00 10 11 00 01 10 00 01 10 11 10 11 00 01 11 10 01 00 01 00 11 10 The gray code sequence can be best understood by following these values in a circle; with a starting point and a direction of clockwise or counter-clockwise: 01 00 11 10 there's two ways to end with the high bytes; start with x0*y1 and change y first, or start with x1*y0 and change x first. The reason I want to end with the high bytes is to return them in registers, and these bytes are most useful if you only want 16x16=16. x0*y0 x0*y1 ;change y first i.e. ldy y1 x1*y1 ;change x with +set_mier x1 x1*y0 x0 y0 x1 y0 ;change x first x1 y1 x0 y1 x0 y1 x0 y0 ;change y first x1 y0 x1 y1 x0 y1 x1 y1 ;change x first x1 y0 x0 y0 x1 y0 x1 y1 ;change y first x0 y1 x0 y0 x1 y0 x0 y0 ;change x first x0 y1 x1 y1 x1 y1 x1 y0 ;change y first x0 y0 x0 y1 x1 y1 x0 y1 ;change x first x0 y0 x1 y0
aaa bbb ccc dd_
n x1 x2 0 0 0 1 1 1 2 2 2 3 0 3 4 1 4 5 2 0 6 0 1 7 1 2 8 2 3 9 0 4 10 1 0 11 2 1 12 0 2 13 1 3 14 2 4
Address Description ------- ----------- $de00 256 bytes of data (See $dfc0-$dfc3 for more information) $df7e write to this location to activate the RAMLink hardware $df7f write to this location to deactivate the RAMLink hardware. $dfa0 lo byte of requested RAMCard memory page $dfa1 hi byte of requested RAMCard memory page $dfc0 write to this location to show RL variable RAM at $de00 (default) $dfc1 write to this location to show RAMCard memory at $de00 $dfc2 write to this location to show the RAM Port device $de00 page at $de00 $dfc0 write to this location to show Pass-Thru Port dev. $de00 page at $de00 ;8bit mult, of x*y to z0;z1 rl_page=$de00 rl_sel_ramcard=$dfc1 rl_lo=$dfa0 rl_hi=$dfa1 rl_activate=$df7e rl_deactivate=$df7f sta rl_activate;4 stx rl_lo;4 lda #0;2 sta rl_hi;4 sta rl_sel_ramcard;4 lda rl_page,x;5? sta z0;3 inc rl_hi;is this r/w? 6 lda rl_page,x;5 sta z1;3 sta rl_deactivate;4 rts
x cos(x) -pi/2 0 0 1 pi/2 0 pi -1 3pi/2 0 2pi 1