Mercurial > hg > index.cgi
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 |