annotate src/number.s @ 78:718f9b7381b3

Slight improvements to some floating point code
author William Astle <lost@l-w.ca>
date Sun, 10 Sep 2023 20:05:47 -0600
parents eb2681108660
children df86e6d64ce2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
76
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
1 *pragmapush list
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
2 *pragma list
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
4 ; Arithmetic package
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
5 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
6 ; This section contains routines that handle floating point and integer arithmetic.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
7 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
8 ; Most routines take a pointer to a value accumulator in X. Some take two pointers with the second in U.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
10 ; Match operands for a numeric calculation. This works as follows:
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
11 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
12 ; * If both operands are the same, ensure the type is numeric and return
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
13 ; * If one operand is floating point, convert the other to floating point, as long as it is numeric
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
14 ; * If one or both oeprands are not numeric, raise a type mismatch
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
15 ; The operands are in (X) and (U)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
16 val_matchtypes ldb val.type,x ; get the type of first argument
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
17 cmpb #valtype_int ; is it integer?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
18 beq val_matchtypes0 ; brif so
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
19 cmpb #valtype_float ; is it floating point?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
20 beq val_matchtypes1 ; brif so
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
21 TMERROR ldb #err_tm ; raise a type mismatch
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
22 jmp ERROR
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
23 val_matchtypes0 ldb val.type,u ; get type of second operand
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
24 cmpb #valtype_int ; is it integer?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
25 bne val_matchtypes2 ; brif not
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
26 val_matchtypes3 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
27 val_matchtypes2 cmpb #valtype_float ; is it floating point?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
28 bne TMERROR ; brif not - raise error
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
29 pshs u ; save pointer to second operand
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
30 bsr val_int32tofp ; convert first argument to floating point
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
31 puls u,pc ; restore second operand pointer and return
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
32 val_matchtypes1 ldb val.type,u ; get second argument type
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
33 cmpb #valtype_float ; is it floating point?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
34 beq val_matchtypes3 ; brif so - we're good
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
35 cmpb #valtype_int ; is it integer?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
36 bne TMERROR ; brif not - invalid type combination
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
37 pshs x,u ; save value pointers
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
38 leax ,u ; convert (U) to floating point
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
39 bsr val_int32tofp
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
40 puls x,u,pc ; restore argument pointers and return
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
41 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
42 ; Negate the 32 bit integer (for fp mantissa) at (X)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
43 val_negint32 ldd zero ; subtract integer value from zero
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
44 subd val.int+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
45 std val.int+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
46 ldd zero
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
47 sbcb val.int+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
48 sbca val.int,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
49 std val.int,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
50 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
52 ; Convert integer value at (X) to floating point value at (X). Enter at val_uint32tofp to treat the 32 bit value as
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
53 ; unsigned. Otherwise enter at val_int32tofp to treat it as signed.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
54 val_uint32tofp clr val.fpsign,x ; for positive sign
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
55 bra val_int32tofpp ; go process as positive
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
56 val_int32tofp ldb val.int,x ; get sign to A
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
57 sex
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
58 sta val.fpsign,x ; set sign of result
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
59 bpl val_int32tofpp ; brif positive - don't need to do a two's complement adjustment
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
60 bsr val_negint32 ; negate the integer value
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
61 val_int32tofpp ldb valtype_float ; set result to floating point
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
62 stb val.type,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
63 ldb #0xa0 ; exponent to have binary point to the right of the mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
64 stb val.fpexp,x ; set the exponent
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
65 clrb ; clear out extra precision bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
66 ; fall through to normalize the value at (X)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
68 ; Normalize floating point value at (X); this will shift the mantissa until there is a one in the leftmost
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
69 ; bit of the mantissa. The algorithm is as follows:
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
70 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
71 ; 1. Shift the mantissa left until a 1 bit is found in the high bit of the mantissa.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
72 ; 1a. If more than 40 bits of left shifts occur, determine that the value is zero and return
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
73 ; 2. Adjust exponent based on number of shifts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
74 ; 2a. If new exponent went below -127, then underflow occurred and zero out value
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
75 ; 2b. If new exponent went above +127, raise an overflow
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
76 ; 3. If bit 7 of the extra precision byte is clear, return the resulting value
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
77 ; 4. Add one to the mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
78 ; 5. If a carry in (4) occurred, then set high bit of mantissa and bump exponent
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
79 ; 6. If new exponent carries, then raise overflow
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
80 ; 7. Return result.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
81 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
82 ; Note that if we carried in (4), the only possible result is that the mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
83 ; rolled over to all zeroes so there is no need to shift the entire mantissa right
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
84 ; nor is there any reason to check for additional rounding.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
85 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
86 ; The above algorithm has some optimizations in the code sequence below.
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
87 fp_normalize pshs b ; save extra bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
88 clrb ; set shift counter/exponent adjustment
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
89 fp_normalize0 lda val.fpmant,x ; set flags on high word of mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
90 bne fp_normalize2 ; brif we don't have a full byte to shift
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
91 addb #8 ; account for a while byte of shifts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
92 ldu val.fpmant+1,x ; shift mantissa left 8 bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
93 stu val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
94 lda val.fpmant+3,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
95 sta val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
96 lda ,s ; and include extra bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
97 sta val.fpmant+3,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
98 clr ,s ; and blank extra bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
99 cmpb #40 ; have we shifted 40 bits?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
100 blo fp_normalize0 ; brif not - keep shifting
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
101 bra fp_normalize7 ; go zero out the value
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
102 fp_normalize1 incb ; account for one bit of shifting
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
103 lsl ,s ; shift mantissa and extra bits left (will not be more than 7 shifts)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
104 rol val.fpmant+3,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
105 rol val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
106 rol val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
107 rol val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
108 fp_normalize2 bpl fp_normalize1 ; brif we have to do a bit shift
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
109 pshs b ; apply exponent counter to exponent
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
110 lda val.fpexp,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
111 suba ,s+
78
718f9b7381b3 Slight improvements to some floating point code
William Astle <lost@l-w.ca>
parents: 76
diff changeset
112 bls fp_normalize6 ; brif we underflowed to zero; overflow is impossible
76
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
113 fp_normalize3 lsl ,s+ ; set C if the high bit of extra precision is set
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
114 bcs fp_normalize5 ; brif bit set - we have to do rounding
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
115 fp_normalize4 rts ; return if no rounding
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
116 fp_normalize5 ldu val.fpmant+2,x ; add one to mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
117 leau 1,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
118 stu val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
119 bne fp_normalize4 ; brif low word doesn't carry
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
120 ldu val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
121 leau 1,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
122 stu val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
123 bne fp_normalize4 ; brif high word doesn't carry
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
124 ror val.fpmant,x ; shift right C in to high bit of mantissa (already set to get here)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
125 inc val.fpexp,x ; bump exponent for a right shift
78
718f9b7381b3 Slight improvements to some floating point code
William Astle <lost@l-w.ca>
parents: 76
diff changeset
126 bne fp_normalize4 ; brif it doesn't overflow (> +127)
718f9b7381b3 Slight improvements to some floating point code
William Astle <lost@l-w.ca>
parents: 76
diff changeset
127 OVERROR2 jmp OVERROR ; raise overflow
76
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
128 fp_normalize6 clr val.fpmant,x ; clear mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
129 clr val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
130 clr val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
131 clr val.fpmant+3,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
132 fp_normalize7 clr val.fpexp,x ; clear exponent and sign
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
133 clr val.fpsign,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
134 puls b,pc ; clean up stack and return
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
135 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
136 ; Addition and subtraction of values; must enter with values of matching types
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
137 ;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
138 ; Calculates (X) + (U) -> (Y) (addition)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
139 ; Calculates (X) - (U) -> (Y) (subtraction)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
140 val_add ldb val.type,x ; get type of left operand
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
141 stb val.type,y ; set result type
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
142 cmpb #valtype_float ; is it float?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
143 beq fp_add ; brif so
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
144 ldd val.int+2,x ; do the addition
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
145 addd val.int+2,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
146 std val.int+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
147 ldd val.int,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
148 adcb val.int+1,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
149 adca val.int,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
150 std val.int,y
78
718f9b7381b3 Slight improvements to some floating point code
William Astle <lost@l-w.ca>
parents: 76
diff changeset
151 bvs OVERROR2 ; brif calculation overflowed
76
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
152 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
153 val_sub ldb val.type,x ; get type of left operand
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
154 stb val.type,y ; set result type
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
155 cmpb #valtype_float ; floating point?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
156 beq fp_sub ; brif so
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
157 ldd val.int+2,x ; do the subtraction
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
158 subd val.int+2,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
159 std val.int+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
160 ldd val.int,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
161 sbcb val.int+1,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
162 sbca val.int,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
163 std val.int,y
78
718f9b7381b3 Slight improvements to some floating point code
William Astle <lost@l-w.ca>
parents: 76
diff changeset
164 bvs OVERROR2 ; brif overflow
76
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
165 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
166 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
167 ; FP subtraction: just invert the sign of the second operand and add; operands must be writable and they should be
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
168 ; considered to be clobbered
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
169 fp_sub com val.fpsign,u ; negate right operand
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
170 ; fall through to addition
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
171 ; FP addition: this requires that *both operands* are writable and they may be clobbered
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
172 fp_add ldb val.fpexp,u ; is the second operand zero?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
173 beq fp_add0 ; brif so - it's a no-op - copy the left operand to the output
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
174 lda val.fpexp,x ; is left operand zero?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
175 bne fp_add1 ; brif not - we have to do the add
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
176 leau ,x ; copy the right operand to the output
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
177 fp_add0 ldd ,u ; copy the value across
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
178 std ,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
179 ldd 2,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
180 std 2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
181 ldd 4,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
182 std 4,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
183 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
184 fp_add1 subb val.fpexp,x ; get difference in exponents
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
185 beq fp_add6 ; brif they're the same - no denormalizing is needed
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
186 bhi fp_add2 ; brif second one is bigger, need to right-shift the mantissa of first
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
187 exg x,u ; swap the operands (we can do that for addition)l second is now biggest
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
188 negb ; invert the shift count
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
189 fp_add2 cmpb #32 ; are we shifting more than 32 bits?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
190 blo fp_add0 ; brif so - we're effectively adding zero so bail out
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
191 fp_add3 cmpb #8 ; have 8 bits to move?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
192 bhs fp_add5 ; brif not
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
193 lda val.fpmant+2,x ; shift 8 bits right
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
194 sta val.fpmant+3,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
195 lda val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
196 sta val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
197 lda val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
198 sta val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
199 clr val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
200 subb #8 ; account for 8 shifts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
201 bra fp_add3 ; see if we have a whole byte to shift
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
202 fp_add4 lsr val.fpmant,x ; shift right one bit
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
203 ror val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
204 ror val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
205 ror val.fpmant+3,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
206 fp_add5 decb ; done all shifts?
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
207 bmi fp_add4 ; brif not - do a shift
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
208 fp_add6 ldb val.fpexp,u ; set exponent of result
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
209 stb val.fpexp,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
210 ldb val.fpsign,u ; fetch sign of larger value
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
211 stb val.fpsign,y ; set result sign
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
212 cmpb val.fpsign,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
213 bne fp_add8 ; brif not - need to subtract the operands
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
214 ldd val.fpmant+2,u ; add the mantissas
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
215 addd val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
216 std val.fpmant+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
217 ldd val.fpmant,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
218 adcb val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
219 adca val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
220 std val.fpmant,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
221 clrb ; clear extra precision bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
222 bcc fp_add7 ; brif no carry
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
223 ror val.fpmant,y ; shift carry into mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
224 ror val.fpmant+1,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
225 ror val.fpmant+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
226 ror val.fpmant+3,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
227 rorb ; keep bits for founding
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
228 inc val.fpexp,y ; bump exponent to account for shift
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
229 lbeq OVERROR ; brif it overflowed
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
230 fp_add7 leax ,y ; point to result
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
231 jmp fp_normalize ; go normalize the result
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
232 fp_add8 ldd val.fpmant+2,u ; subtract operands
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
233 subd val.fpmant+2,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
234 std val.fpmant+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
235 ldd val.fpmant,u
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
236 sbcb val.fpmant+1,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
237 sbca val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
238 std val.fpmant,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
239 bcc fp_add7 ; brif we didn't carry - no need to fix up
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
240 ldd zero ; negate the mantissa bits since we use sign+magnitude
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
241 subd val.fpmant+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
242 std val.fpmant+2,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
243 ldd zero
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
244 sbcb val.fpmant+1,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
245 sbca val.fpmant,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
246 std val.fpmant,y
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
247 neg val.fpsign,y ; invert sign of result since we went past zero
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
248 clrb ; clear extra precision bits
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
249 bra fp_add7 ; go normalize the result and return
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
250 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
251 ; Pack a floating point value at (X)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
252 fp_packval ldb val.fpsign,x ; get sign
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
253 bmi fp_packval ; brif negative - the default 1 bit will do
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
254 ldb val.fpmant,x ; clear high bit of mantissa for positive
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
255 andb #0x7f
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
256 stb val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
257 fp_packval0 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
258 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
259 ; Unpack a floating point value at (X)
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
260 fp_unpackval0 ldb val.fpmant,x ; get high byte of mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
261 sex ; now A is value for sign byte
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
262 sta val.fpsign,x ; set sign
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
263 orb #0x80 ; set high bit of mantissa
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
264 stb val.fpmant,x
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
265 rts
eb2681108660 Split some code into separate files for easier management (4)
William Astle <lost@l-w.ca>
parents:
diff changeset
266 *pragmapop list