; *************************************************************************** ; copyright : (C) 2026 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** ; * This file is part of the project "AqHome". * ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** #ifndef AVR_MOD_COM2WROUTER_RINGBUFFER_ASM #define AVR_MOD_COM2WROUTER_RINGBUFFER_ASM ; *************************************************************************** ; defines .equ COM2WR_RINGBUFFER_MAX_WORDS = 512 ; *************************************************************************** ; SDRAM data .dseg com2wRingbufferBegin: com2wRingbufferReadPos: .byte 2 com2wRingbufferWritePos: .byte 2 com2wRingbufferWordsInBuffer: .byte 2 com2wRingbufferData: .byte (2*COM2WR_RINGBUFFER_MAX_WORDS) com2wRingbufferEnd: ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine COM2WR_Ringbuffer_Reset @global ; ; @clobbers r16 COM2WR_Ringbuffer_Init: rjmp COM2WR_Ringbuffer_Reset ; @end ; --------------------------------------------------------------------------- ; @routine COM2WR_Ringbuffer_Reset @global ; ; @clobbers r16 COM2WR_Ringbuffer_Reset: clr r16 sts com2wRingbufferReadPos, r16 sts com2wRingbufferReadPos+1, r16 sts com2wRingbufferWritePos, r16 sts com2wRingbufferWritePos+1, r16 sts com2wRingbufferWordsInBuffer, r16 sts com2wRingbufferWordsInBuffer+1, r16 ret ; @end ; --------------------------------------------------------------------------- ; @routine COM2WR_Ringbuffer_WriteWord @global ; ; @return CFLAG set if data stored, cleared otherwise ; @param r16 low byte to add ; @param r17 high byte to add ; @clobbers xl, xh, r18, r19 COM2WR_Ringbuffer_WriteWord: lds xl, com2wRingbufferWordsInBuffer ; +2 lds xh, com2wRingbufferWordsInBuffer+1 ; +2 ldi r18, LOW(COM2WR_RINGBUFFER_MAX_WORDS) ; +1 ldi r19, HIGH(COM2WR_RINGBUFFER_MAX_WORDS) ; +1 cp xl, r18 ; +1 cpc xh, r19 ; +1 brcc COM2WR_Ringbuffer_WriteWord_ret ; +1 (+2 if jump) adiw xh:xl, 1 ; +1 sts com2wRingbufferWordsInBuffer, xl ; +2 sts com2wRingbufferWordsInBuffer+1, xh ; +2 lds xl, com2wRingbufferWritePos ; +2 lds xh, com2wRingbufferWritePos+1 ; +2 ldi r18, LOW(com2wRingbufferData) ; +1 ldi r19, HIGH(com2wRingbufferData) ; +1 add xl, r18 ; +1 adc xh, r19 ; +1 st X+, r16 ; +2 st X+, r17 ; +2 sub xl, r18 ; +1 sbc xh, r19 ; +1 andi xl, LOW((2*COM2WR_RINGBUFFER_MAX_WORDS)-1) ; +1 andi xh, HIGH((2*COM2WR_RINGBUFFER_MAX_WORDS)-1) ; +1 sts com2wRingbufferWritePos, xl ; +2 sts com2wRingbufferWritePos+1, xh ; +2 sec ; +1 COM2WR_Ringbuffer_WriteWord_ret: ret ; +4 = +41 = <3us at 16MHz ; @end ; --------------------------------------------------------------------------- ; @routine COM2WR_Ringbuffer_ReadWord @global ; ; @return CFLAG set if data available, cleared otherwise ; @return r16 low byte from buffer ; @return r17 high byte from buffer ; @clobbers xl, xh, r18 COM2WR_Ringbuffer_ReadWord: lds xl, com2wRingbufferWordsInBuffer lds xh, com2wRingbufferWordsInBuffer+1 mov r18, xl or r18, xh clc breq COM2WR_Ringbuffer_ReadWord_ret sbiw xh:xl, 1 sts com2wRingbufferWordsInBuffer, xl sts com2wRingbufferWordsInBuffer+1, xh lds xl, com2wRingbufferReadPos lds xh, com2wRingbufferReadPos+1 ldi r18, LOW(com2wRingbufferData) ; +1 ldi r19, HIGH(com2wRingbufferData) ; +1 add xl, r18 ; +1 adc xh, r19 ; +1 ld r16, X+ ld r17, X+ sub xl, r18 sbc xh, r19 andi xl, LOW((2*COM2WR_RINGBUFFER_MAX_WORDS)-1) andi xh, HIGH((2*COM2WR_RINGBUFFER_MAX_WORDS)-1) sts com2wRingbufferReadPos, xl sts com2wRingbufferReadPos+1, xh sec COM2WR_Ringbuffer_ReadWord_ret: ret ; @end #endif ; AVR_MOD_COM2WROUTER_RINGBUFFER_ASM