comparison src/int.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
32 sbcb val.int+1,u 32 sbcb val.int+1,u
33 sbca val.int,u 33 sbca val.int,u
34 std val.int,y 34 std val.int,y
35 bvs OVERROR2 ; raise overflow if needed 35 bvs OVERROR2 ; raise overflow if needed
36 int32_add0 rts 36 int32_add0 rts
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 ; Fast multiply 32 bit at (X) by 10
39 ;
40 ; This will work for signed because the left shift will double it even if it is negative and V is set correctly after
41 ; left shifts. The add will have the same sign so the magnitude will still increase, not decrease.
42 uint32_mul10 ldd val.int,x ; make copy of original
43 ldu val.int+2,x
44 pshs d,u ; save original
45 lsl val.int+3,x ; shift left (times 2)
46 rol val.int+2,x
47 rol val.int+1,x
48 rol val.int,x
49 bvs OVERROR2 ; brif overflow
50 lsl val.int+3,x ; shift left (times 4)
51 rol val.int+2,x
52 rol val.int+1,x
53 rol val.int,x
54 bvs OVERROR2 ; brif overflow
55 ldd val.int+2,x ; add original (times 5)
56 addd 2,s
57 std val.int+2,x
58 puls d,u ; (get upper word and clean stack)
59 adcb val.int+1,x
60 adca val.int,x
61 std val.int,x
62 bvs OVERROR2 ; brif overflow
63 lsl val.int+3,x ; shift left again (times 10)
64 rol val.int+2,x
65 rol val.int+1,x
66 rol val.int,x
67 bvs OVERROR2 ; brif overflow
68 rts
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 69 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 ; Signed 32 bit integer multiply (X) * (U) -> (Y), overflow if exceeds signed 32 bit range 70 ; Signed 32 bit integer multiply (X) * (U) -> (Y), overflow if exceeds signed 32 bit range
39 int32_mul ldd val.int+2,x ; copy left operand to temporary 71 int32_mul ldd val.int+2,x ; copy left operand to temporary
40 std fpa0+fps.sig+2 72 std fpa0+fps.sig+2
41 ldd val.int,x 73 ldd val.int,x
225 ldb #0 257 ldb #0
226 adcb fpa0extra 258 adcb fpa0extra
227 stb fpa0extra 259 stb fpa0extra
228 rts 260 rts
229 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 261 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
262 ; Integer divide (X) by 10 *in place*
263 int32_const10 fqb 10 ; integer constant 10
264 int32_div10 ldu #int32_const10 ; point to integer constant 10
265 leay ,x ; point to output location
266 ; fall through to integer division
267 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
230 ; 32 bit division, integer only, truncate fraction without rounding. Note that there is exactly one case where integer 268 ; 32 bit division, integer only, truncate fraction without rounding. Note that there is exactly one case where integer
231 ; division can overflow: dividing -0x80000000 by -1 which yields 0x80000000. All other cases reduce the magnitude. 269 ; division can overflow: dividing -0x80000000 by -1 which yields 0x80000000. All other cases reduce the magnitude.
232 int32_div ldd val.int+2,x ; copy left operand to temporary 270 int32_div ldd val.int+2,x ; copy left operand to temporary
233 std fpa0+fps.sig+2 271 std fpa0+fps.sig+2
234 ldd val.int,x 272 ldd val.int,x