comparison src/fps.s @ 83:a492441bfc56

Add utility multiply and divide by 10 routines Add a fast multiply by 10 routine for both integer and floating point (shift left twice, add original, shift left). Also add a simple call to divide by 10 for both though there is no fast shortcut for that.
author William Astle <lost@l-w.ca>
date Sat, 07 Oct 2023 15:17:44 -0600
parents 9a4e2364a966
children 663d8e77b579
comparison
equal deleted inserted replaced
82:9a4e2364a966 83:a492441bfc56
68 std fpa0+fps.sig+1 68 std fpa0+fps.sig+1
69 ldd 2,x ; and the final byte and extra precision 69 ldd 2,x ; and the final byte and extra precision
70 sta fpa0+fps.sig+3 70 sta fpa0+fps.sig+3
71 stb fpa0extra 71 stb fpa0extra
72 jmp fps_add10 ; go normalize the result and return 72 jmp fps_add10 ; go normalize the result and return
73 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
74 ; Fast multiply (X) by 10, in place.
75 ;
76 ; * first, save original value
77 ; * then, shift left by 2 bits (add 2 to exponent)
78 ; * then, add original value
79 ; * then, shift left one more (add 1 to exponent)
80 ;
81 ; This should be faster than multiplying by 10.
82 fps_mul10 leas -fps.size,s ; make a temporary to hold original value
83 ldd ,x ; copy original value
84 std ,s
85 ldd 2,x
86 std 2,s
87 ldd 4,x
88 std 4,s
89 lda fps.exp,x ; bump original exponent by 2 (times 4)
90 adda #2
91 bcc fps_mul10b ; brif it overflowed
92 fps_mul10a jmp OVERROR ; raise overflow
93 fps_mul10b sta fps.exp,x
94 leay ,x
95 leau ,s
96 bsr fps_add ; add original value (times 5)
97 leas fps.size,s ; clean up temporary
98 inc fps.exp,y ; bump exponent (times 10) in result
99 beq fps_mul10a ; brif it overflowed
100 rts
73 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 101 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
74 ; Unary negation - negate (X) to (Y) 102 ; Unary negation - negate (X) to (Y)
75 fps_neg ldd 2,x ; copy to output and keep exponent in A 103 fps_neg ldd 2,x ; copy to output and keep exponent in A
76 std 2,y 104 std 2,y
77 ldd 4,x 105 ldd 4,x
333 ror fpa0extra7 361 ror fpa0extra7
334 ror fpa0extra ; and into the extra precision bits 362 ror fpa0extra ; and into the extra precision bits
335 clra ; clear carry - so shift above will terminate 363 clra ; clear carry - so shift above will terminate
336 bra fps_mul6 ; go do another bit 364 bra fps_mul6 ; go do another bit
337 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366 ; Divide (X) by 10 in place
367 fps_const10 fcb 0x83,0xa0,0x00,0x00,0x00,0x00 ; single precision unpacked constant 10
368 fps_div10 ldu #fps_const10 ; point to constant 10
369 leay ,x ; put output in input
370 ; fall through to regular division
371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
338 ; Single precision division (X) ÷ (U) -> (Y) 372 ; Single precision division (X) ÷ (U) -> (Y)
339 ; 373 ;
340 ; This is basically the same algorithm used in the Color Basic ROM 374 ; This is basically the same algorithm used in the Color Basic ROM
341 fps_div lda fps.exp,u ; is divisor 0? 375 fps_div lda fps.exp,u ; is divisor 0?
342 bne fps_div0 376 bne fps_div0