Mercurial > public > mk2
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 |