]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/circularbytebuffer-asm.S
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / test_src / circularbytebuffer-asm.S
1 /* circularbytebuffer-asm.S */
2 /*
3     This file is part of the AVR-circularbytebuffer.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 /**
20  * \file     circularbytebuffer-asm.S
21  * \email    bg@nerilex.org
22  * \author   Daniel Otte 
23  * \date     2009-07-25
24  * \license  GPLv3 or later
25  * \ingroup  circularbytebuffer
26  * \brief    declaration for circular byte buffer
27  */
28 /* 
29  typedef struct {
30          uint8_t buffer_size;
31          uint8_t fillcount;
32          uint8_t *buffer;
33          uint8_t *head;
34          uint8_t *tail;
35          uint8_t *top;
36 } circularbytebuffer_t;
37 */
38
39 #include "config.h"
40
41 #define BUFFER_SIZE_OFFSET 0
42 #define FILLCOUNT_OFFSET   1
43 #define BUFFER_OFFSET      2
44 #define HEAD_OFFSET        4
45 #define TAIL_OFFSET        6
46 #define TOP_OFFSET         8
47
48 #ifndef CIRCULARBYTEBUFFER_NO_MALLOC
49 #  define CIRCULARBYTEBUFFER_NO_MALLOC 0
50 #endif
51
52 #ifndef CIRCULARBYTEBUFFER_NO_INIT2
53 #  define CIRCULARBYTEBUFFER_NO_INIT2 0
54 #endif
55
56 #if CIRCULARBYTEBUFFER_NO_MALLOC==0
57
58 /******************************************************************************/
59 /*
60  *      uint8_t circularbytebuffer_init(uint8_t buffersize, circularbytebuffer_t *cb){
61  *              cb->buffer_size = buffersize;
62  *              cb->buffer = malloc(buffersize);
63  *              cb->head = cb->tail = cb->buffer;
64  *              cb->top = cb->buffer + cb->buffer_size;
65  *              cb->fillcount = 0;
66  *              if(cb->buffer)
67  *                      return 1; / * success * /
68  *              return 0; / * malloc failed * / 
69  *      }
70  * 
71  * param buffersize:  r24
72  * param cb:          r22:r23
73  */
74 .global circularbytebuffer_init
75 circularbytebuffer_init:
76         push r28
77         push r29
78         movw r28, r22
79         std Y+0, r24 /* set buffer_size */
80         std Y+1, r1  /* set fillcount to 0 */
81         clr r25
82         call malloc
83         adiw r24, 0
84         brne 10f
85         clr r24
86         rjmp 99f
87 10:
88         std Y+2, r24
89         std Y+3, r25
90         std Y+4, r24
91         std Y+5, r25
92         std Y+6, r24
93         std Y+7, r25
94         ld r22, Y
95         add r24, r22
96         adc r25, r1
97         std Y+8, r24
98         std Y+9, r25
99         ldi r24, 1      
100 99:
101         clr r25
102         pop r29
103         pop r28
104         ret
105
106 /******************************************************************************/
107 /*
108  *      void circularbytebuffer_free(circularbytebuffer_t *cb){
109  *              free(cb->buffer);
110  *      }
111  *
112  * param cb:  r24:r25
113  */
114 .global circularbytebuffer_free 
115 circularbytebuffer_free:
116         movw r30, r24
117         ldd r24, Z+BUFFER_OFFSET
118         ldd r25, Z+BUFFER_OFFSET+1
119         jmp free
120
121 #endif /* CIRCULARBYTEBUFFER_NO_MALLOC==0 */
122
123 #if CIRCULARBYTEBUFFER_NO_INIT2==0
124
125 /******************************************************************************/
126 /*
127  *      void circularbytebuffer_init2(uint8_t buffersize, circularbytebuffer_t *cb, void *buffer){
128  *              cb->buffer_size = buffersize;
129  *              cb->buffer = buffer
130  *              cb->head = cb->tail = cb->buffer;
131  *              cb->top = cb->buffer + cb->buffer_size;
132  *              cb->fillcount = 0;
133  *      }
134  * 
135  * param buffersize:  r24
136  * param cb:          r22:r23
137  * param buffer:      r20:r21
138  */
139 .global circularbytebuffer_init2
140 circularbytebuffer_init2:
141         movw r30, r22
142         std Z+0, r24 /* set buffer_size */
143         std Z+1, r1  /* set fillcount to 0 */
144         std Z+2, r20
145         std Z+3, r21
146         std Z+4, r20
147         std Z+5, r21
148         std Z+6, r20
149         std Z+7, r21
150         add r20, r24
151         adc r21, r1
152         std Z+8, r20
153         std Z+9, r21
154         ret
155
156 #endif /* CIRCULARBYTEBUFFER_NO_INIT2==0 */
157
158 /******************************************************************************/
159 /*
160  *      uint8_t circularbytebuffer_cnt(circularbytebuffer_t *cb){
161  *              return (cb->fillcount);
162  *      }
163  *
164  * param cb:  r24:r25
165  */
166 .global circularbytebuffer_cnt
167 circularbytebuffer_cnt:
168         movw r30, r24
169         ldd r24, Z+FILLCOUNT_OFFSET
170         clr r25
171         ret
172         
173 /******************************************************************************/
174 /*
175  *      uint16_t circularbytebuffer_get_lifo(circularbytebuffer_t *cb){
176  *              uint8_t ret;
177  *              if(cb->fillcount==0)
178  *                      return 0xffff;
179  *              --cb->fillcount;
180  *              ret=*(cb->tail);
181  *              cb->tail = (uint8_t*)(cb->tail) + 1;
182  *              if(cb->tail>=cb->top)   
183  *                      cb->tail = (uint8_t*)(cb->tail) - cb->buffer_size;
184  *              return ret;     
185  *      }
186  * param cb:  r24:r25
187  */
188 .global circularbytebuffer_get_lifo
189 circularbytebuffer_get_lifo:
190         movw r30, r24
191         ldd r23, Z+FILLCOUNT_OFFSET
192         tst r23
193         brne 10f
194         ser r24
195         ser r25
196         ret
197 10: 
198         dec r23
199         std Z+FILLCOUNT_OFFSET, r23
200         ldd r26, Z+TAIL_OFFSET
201         ldd r27, Z+TAIL_OFFSET+1
202         ld r24, X+
203         clr r25
204         ldd r22, Z+TOP_OFFSET
205         ldd r23, Z+TOP_OFFSET+1
206         cp  r26, r22
207         cpc r27, r23
208         brlo 20f
209         ldd r22, Z+BUFFER_SIZE_OFFSET
210         sub r26, r22
211         sbc r27, r1
212 20:     
213         std Z+TAIL_OFFSET, r26
214         std Z+TAIL_OFFSET+1, r27
215         ret     
216
217 /******************************************************************************/
218 /*
219  *      uint16_t circularbytebuffer_get_fifo(circularbytebuffer_t *cb){
220  *              uint8_t ret;
221  *              if(cb->fillcount==0)
222  *                      return 0xffff;
223  *              --cb->fillcount;
224  *              ret=*(cb->head);
225  *              cb->head = (uint8_t*)(cb->head) - 1;
226  *              if(cb->head<cb->buffer) 
227  *                      cb->head = (uint8_t*)(cb->head) + cb->buffer_size;
228  *              return ret;
229  *      }
230  *
231  * param cb:  r24:r25
232  * return:    r24
233  * modifys:   r22-r27,r30,r31
234  */
235 .global circularbytebuffer_get_fifo
236 circularbytebuffer_get_fifo:
237         movw r30, r24
238         ldd r23, Z+FILLCOUNT_OFFSET
239         tst r23
240         brne 10f
241         ser r24
242         ser r25
243         ret
244 10: 
245         dec r23
246         std Z+FILLCOUNT_OFFSET, r23
247         ldd r26, Z+HEAD_OFFSET
248         ldd r27, Z+HEAD_OFFSET+1
249         ld r24, X
250         clr 25
251         sbiw r26, 1
252         ldd r22, Z+BUFFER_OFFSET
253         ldd r23, Z+BUFFER_OFFSET+1
254         cp  r26, r22
255         cpc r27, r23
256         brge 20f
257         ldd r22, Z+BUFFER_SIZE_OFFSET
258         add r26, r22
259         adc r27, r1
260 20:     
261         std Z+HEAD_OFFSET, r26
262         std Z+HEAD_OFFSET+1, r27
263         ret     
264
265 /******************************************************************************/
266 /*
267  *      uint8_t circularbytebuffer_append(uint8_t elem, circularbytebuffer_t *cb){
268  *              if(cb->fillcount==cb->buffer_size)
269  *                      return 1;
270  *              cb->fillcount++;        
271  *              cb->tail = cb->tail - 1;
272  *              if(cb->tail<cb->buffer) 
273  *                      cb->tail = (uint8_t*)(cb->tail) + cb->buffer_size;
274  *              if(cb->fillcount==1)
275  *                      cb->head = cb->tail;
276  *              *(cb->tail) = elem;
277  *              return 0;
278  *      }
279  *
280  * param elem:  r24
281  * param cb:    r22:r23
282  */     
283 .global circularbytebuffer_append
284 circularbytebuffer_append:
285         movw r30, r22
286         ldd r22, Z+FILLCOUNT_OFFSET
287         ldd r23, Z+BUFFER_SIZE_OFFSET
288         cp r22, r23
289         brne 10f
290 5:
291         ldi r24, 1
292         ret
293 10:
294         clt
295         tst r22
296         brne 11f
297         set
298 11:     
299         inc r22
300         std Z+FILLCOUNT_OFFSET, r22
301         ldd r26, Z+TAIL_OFFSET
302         ldd r27, Z+TAIL_OFFSET+1
303         sbiw r26, 1
304         ldd r22, Z+BUFFER_OFFSET
305         ldd r23, Z+BUFFER_OFFSET+1
306         cp  r26, r22
307         cpc r27, r23
308         brge 20f
309         ldd r22, Z+BUFFER_SIZE_OFFSET
310         add r26, r22
311         adc r27, r1     
312 20:
313         std Z+TAIL_OFFSET, r26
314         std Z+TAIL_OFFSET+1, r27
315         brtc 30f
316         std Z+HEAD_OFFSET, r26
317         std Z+HEAD_OFFSET+1, r27
318 30:
319         st X, r24
320         clr r24
321         ret     
322
323 /******************************************************************************/
324 /*
325  *      uint8_t circularbytebuffer_push(uint8_t elem, circularbytebuffer_t *cb){
326  *              if(cb->fillcount==cb->buffer_size)
327  *                      return 1;
328  *              cb->fillcount++;        
329  *              cb->head = cb->head + 1;
330  *              if(cb->head>=cb->top)   
331  *                      cb->head = (uint8_t*)(cb->head) - cb->buffer_size;
332  *              if(cb->fillcount==1)
333  *                      cb->tail = cb->head;
334  *              *(cb->head) = elem;
335  *              return 0;
336  *      }
337  * 
338  * param elem:  r24
339  * param cb:    r22:r23
340  */
341 .global circularbytebuffer_push
342 circularbytebuffer_push:
343         movw r30, r22
344         ldd r22, Z+FILLCOUNT_OFFSET
345         ldd r23, Z+BUFFER_SIZE_OFFSET
346         cp r22, r23
347         brlo 10f
348         rjmp 5b
349 ;       ldi r24, 1
350 ;       ret
351 10:
352 ;       clt
353 ;       tst r22
354 ;       brne 11f
355 ;       set
356 11:     
357         inc r22
358         std Z+FILLCOUNT_OFFSET, r22
359         ldd r26, Z+HEAD_OFFSET
360         ldd r27, Z+HEAD_OFFSET+1
361         adiw r26, 1
362         ldd r22, Z+TOP_OFFSET
363         ldd r23, Z+TOP_OFFSET+1
364         cp  r26, r22
365         cpc r27, r23
366         brlo 20f
367         ldd r22, Z+BUFFER_SIZE_OFFSET
368         sub r26, r22
369         sbc r27, r1     
370 20:
371         std Z+HEAD_OFFSET, r26
372         std Z+HEAD_OFFSET+1, r27
373 ;       brtc 30b
374 ;       std Z+TAIL_OFFSET, r26
375 ;       std Z+TAIL_OFFSET+1, r27
376         rjmp 30b