comparison code_part1/OSTC_code_asm_part1/math.asm @ 0:96a35aeda5f2

Initial setup
author heinrichsweikamp
date Tue, 12 Jan 2010 15:05:59 +0100
parents
children a1ccb92b59cd
comparison
equal deleted inserted replaced
-1:000000000000 0:96a35aeda5f2
1 ; OSTC - diving computer code
2 ; Copyright (C) 2008 HeinrichsWeikamp GbR
3
4 ; This program is free software: you can redistribute it and/or modify
5 ; it under the terms of the GNU General Public License as published by
6 ; the Free Software Foundation, either version 3 of the License, or
7 ; (at your option) any later version.
8
9 ; This program is distributed in the hope that it will be useful,
10 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ; GNU General Public License for more details.
13
14 ; You should have received a copy of the GNU General Public License
15 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18 ; Math routines
19 ; written by: Matthias Heinrichs, info@heinrichsweikamp.com
20 ; written: 10/30/05
21 ; last updated: 06/21/07
22 ; known bugs:
23 ; ToDo: clean up!
24
25 convert_time: ; converts hi:lo in minutes to hours (hi) and minutes (lo)
26 movff lo,xA+0 ; divide by 60...
27 movff hi,xA+1 ;
28 movlw d'60' ;
29 movwf xB+0 ;
30 clrf xB+1 ;
31 rcall div16x16 ; xA/xB=xC with xA as remainder
32 movff xC+0,hi ; Hours
33 movff xA+0,lo ; =remaining minutes (0.....59)
34 return
35
36 div16:
37 ; divA=divA/2^divB (divB: 8Bit only!)
38 bcf STATUS,C
39 rrcf divA+1
40 rrcf divA
41 decfsz divB
42 bra div16
43 return
44
45 div32:
46 ; xC=xC(32Bit)/2^divB (divB: 8Bit only!)
47 bcf STATUS,C
48 rrcf xC+3
49 rrcf xC+2
50 rrcf xC+1
51 rrcf xC+0
52 decfsz divB
53 bra div32
54 return
55
56 invert_xC:
57 movf xC+1, w ; inverses xC+0:xC+1
58 sublw 0xFF
59 movwf xC+1
60 movf xC+0, w
61 bcf STATUS,C
62 sublw 0xFF
63 movwf xC+0
64 return
65
66
67 sub16:
68 ; sub_c = sub_a - sub_b
69 bcf neg_flag
70 movf sub_b+0, w ; Get Value to be subtracted
71 subwf sub_a+0, w ; Do the High Byte
72 movwf sub_c+0
73 movf sub_b+1, w ; Get the Value to be Subbed
74 subwfb sub_a+1, w
75 movwf sub_c+1
76 btfss STATUS,N
77 return ; result positve
78 ; sub_c = sub_a - sub_b
79 bsf neg_flag ; result negative
80 movff sub_c+0,sub_b+0
81 movff sub_c+1,sub_b+1
82 setf sub_a
83 setf sub_a+1
84 movf sub_b+0, w ; Get Value to be subtracted
85 subwf sub_a+0, w ; Do the High Byte
86 movwf sub_c+0
87 movf sub_b+1, w ; Get the Value to be Subbed
88 subwfb sub_a+1, w
89 movwf sub_c+1
90 return
91
92
93 mult16x16:
94 ;xA*xB=xC
95 clrf xC+2 ; Clear the High-Order Bits
96 clrf xC+3
97 movf xA, w ; Do the "L" Multiplication first
98 mulwf xB
99 movf PRODL, w ; Save result
100 movwf xC
101 movf PRODH, w
102 movwf xC+1
103 movf xA, w ; Do the "I" Multiplication
104 mulwf xB+1
105 movf PRODL, w ; Save the Most Significant Byte First
106 addwf xC+1, f
107 movf PRODH, w
108 addwfc xC+2, f ; Add to the Last Result
109 movf xA+1, w ; Do the "O" Multiplication
110 mulwf xB
111 movf PRODL, w ; Add the Lower Byte Next
112 addwf xC+1, f
113 movf PRODH, w ; Add the High Byte First
114 addwfc xC+2, f
115 btfsc STATUS, C ; Add the Carry
116 incf xC+3, f
117 movf xA+1, w ; Do the "F" Multiplication
118 mulwf xB+1
119 movf PRODL, w
120 addwf xC+2, f
121 movf PRODH, w
122 addwfc xC+3, f
123 return
124
125
126 div16x16: ;xA/xB=xC with xA as remainder
127 ;uses divB as temp variable
128 clrf xC+0
129 clrf xC+1
130 MOVF xB+0,W ; Check for zero
131 IORWF xB+1,W ;
132 BTFSC STATUS,Z ; Check for zero
133 RETLW H'FF' ; return 0xFF if illegal
134 MOVLW 1 ; Start count at 1
135 MOVWF divB ; Clear Count
136 div16x16_1
137 BTFSC xB+1,7 ; High bit set ?
138 bra div16x16_2 ; Yes then continue
139 INCF divB,F ; Increment count
140
141 bcf STATUS,C
142 rlcf xB+0,F
143 rlcf xB+1,F
144 bra div16x16_1
145 div16x16_2:
146 ; Shift result left
147 bcf STATUS,C
148 rlcf xC+0,F
149 rlcf xC+1,F
150
151 ; Reduce Divisor
152
153 MOVF xB,W ; Get low byte of subtrahend
154 SUBWF xA,F ; Subtract DST(low) - SRC(low)
155 MOVF xB+1,W ; Now get high byte of subtrahend
156 BTFSS STATUS,C ; If there was a borrow, rather than
157 INCF xB+1,W ; decrement high byte of dst we inc src
158 SUBWF xA+1,F ; Subtract the high byte and we're done
159
160
161 BTFSC STATUS, C ; Did it reduce?
162 bra div16x16_3 ; No, so it was less than
163
164 movf xB+0,W ; Reverse subtraction
165 addwf xA+0,F
166 movf xB+1,W
167 addwfc xA+1,F
168
169 bra div16x16_4 ; Continue the process
170 div16x16_3:
171 BSF xC+0,0 ; Yes it did, this gets a 1 bit
172 div16x16_4:
173 DECF divB,F ; Decrement N_COUNT
174 BTFSC STATUS,Z ; If its not zero then continue
175 return
176
177 bcf STATUS,C
178 rrcf xB+1,F
179 rrcf xB+0,F
180
181 bra div16x16_2 ; Next bit.
182
183 div32x16: ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
184 ; Setup
185 movlw .32 ; setup shift counter
186 movwf divB
187 movf xC+3,W ; move ACCb to ACCf
188 movwf xA+1
189 movf xC+2,W
190 movwf xA+0
191 movf xC+1,W ; move ACCc to ACCe
192 movwf sub_a+1
193 movf xC+0,W
194 movwf sub_a+0
195 clrf xC+3
196 clrf xC+2
197 clrf xC+1
198 clrf xC+0
199 clrf sub_b+1
200 clrf sub_b+0
201 div32x16_2
202 bcf STATUS,C
203 rlcf sub_a+0,F
204 rlcf sub_a+1,F
205 rlcf xA+0,F
206 rlcf xA+1,F
207 rlcf sub_b+0,F
208 rlcf sub_b+1,F
209 movf xB+1,W
210 subwf sub_b+1,W ; check if a>d
211 btfss STATUS,Z
212 goto div32x16_3
213 movf xB+0,W
214 subwf sub_b+0,W ; if msb equal then check lsb
215 div32x16_3
216 btfss STATUS,C ; carry set if d>a
217 goto div32x16_4
218 movf xB+0,W ; d-a into d
219 subwf sub_b+0,F
220 btfss STATUS,C
221 decf sub_b+1,F
222 movf xB+1,W
223 subwf sub_b+1,F
224 bsf STATUS,C ; shift a 1 into b (result)
225 div32x16_4
226 rlcf xC+0,F
227 rlcf xC+1,F
228 rlcf xC+2,F
229 rlcf xC+3,F
230 decfsz divB,F ; loop until all bits checked
231 goto div32x16_2
232 return
233
234
235 isr_div16:
236 ; divA=divA/2^divB (divB: 8Bit only!)
237 bcf STATUS,C
238 rrcf isr_divA+1
239 rrcf isr_divA
240 decfsz isr_divB
241 bra isr_div16
242 return
243
244 isr_div32:
245 ; xC=xC(32Bit)/2^divB (divB: 8Bit only!)
246 bcf STATUS,C
247 rrcf isr_xC+3
248 rrcf isr_xC+2
249 rrcf isr_xC+1
250 rrcf isr_xC+0
251 decfsz isr_divB
252 bra isr_div32
253 return
254
255 isr_invert_xC:
256 movf isr_xC+1, w ; inverses xC+0:xC+1
257 sublw 0xFF
258 movwf isr_xC+1
259 movf isr_xC+0, w
260 bcf STATUS,C
261 sublw 0xFF
262 movwf isr_xC+0
263 return
264
265
266 isr_sub16:
267 ; sub_c = sub_a - sub_b
268 bcf neg_flag_isr
269 movf isr_sub_b+0, w ; Get Value to be subtracted
270 subwf isr_sub_a+0, w ; Do the High Byte
271 movwf isr_sub_c+0
272 movf isr_sub_b+1, w ; Get the Value to be Subbed
273 subwfb isr_sub_a+1, w
274 movwf isr_sub_c+1
275 btfss STATUS,N
276 return ; result positve
277 ; sub_c = sub_a - sub_b
278 bsf neg_flag_isr ; result negative
279 movff isr_sub_c+0,isr_sub_b+0
280 movff isr_sub_c+1,isr_sub_b+1
281 setf isr_sub_a
282 setf isr_sub_a+1
283 movf isr_sub_b+0, w ; Get Value to be subtracted
284 subwf isr_sub_a+0, w ; Do the High Byte
285 movwf isr_sub_c+0
286 movf isr_sub_b+1, w ; Get the Value to be Subbed
287 subwfb isr_sub_a+1, w
288 movwf isr_sub_c+1
289 return
290
291
292 isr_mult16x16:
293 ;xA*xB=xC
294 clrf isr_xC+2 ; Clear the High-Order Bits
295 clrf isr_xC+3
296 movf isr_xA, w ; Do the "L" Multiplication first
297 mulwf isr_xB
298 movf PRODL, w ; Save result
299 movwf isr_xC
300 movf PRODH, w
301 movwf isr_xC+1
302 movf isr_xA, w ; Do the "I" Multiplication
303 mulwf isr_xB+1
304 movf PRODL, w ; Save the Most Significant Byte First
305 addwf isr_xC+1, f
306 movf PRODH, w
307 addwfc isr_xC+2, f ; Add to the Last Result
308 movf isr_xA+1, w ; Do the "O" Multiplication
309 mulwf isr_xB
310 movf PRODL, w ; Add the Lower Byte Next
311 addwf isr_xC+1, f
312 movf PRODH, w ; Add the High Byte First
313 addwfc isr_xC+2, f
314 btfsc STATUS, C ; Add the Carry
315 incf isr_xC+3, f
316 movf isr_xA+1, w ; Do the "F" Multiplication
317 mulwf isr_xB+1
318 movf PRODL, w
319 addwf isr_xC+2, f
320 movf PRODH, w
321 addwfc isr_xC+3, f
322 return
323