; ***************************************************************************
; copyright   : (C) 2025 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.   *
; ***************************************************************************



; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_writebyte
;
; @param R16 byte to write
; @param Y   base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17, R18, X

.macro m_ringbuffer_y_writebyte
  ldd r18, Y+@0 ; maxBytes
  ldd r17, Y+@1 ; usedBytes
  cp r17, r18
  brcc l_end    ; out-of-range
  inc r17
  std Y+@1, r17 ; usedBytes
  ldd r17, Y+@3 ; writePos
  mov xl, yl
  mov xh, yh
  adiw xh:xl, @4
  add xl, r17
  adc xh, r17
  sub xh, r17
  st X, r16
  inc r17
  cp r17, r18
  brcs l_store
  clr r17
l_store:
  std Y+@3, r17 ; writePos
  sec
l_end:
.endmacro
; @end



; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_readbyte
;
; @param Y   base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @return R16 byte read
; @clobbers R17, R18, X

.macro m_ringbuffer_y_readbyte
  ldd r18, Y+@0 ; maxBytes
  ldd r17, Y+@1 ; usedBytes
  tst r17
  clc
  breq l_end
  dec r17
  std Y+@1, r17 ; usedBytes
  ldd r17, Y+@2 ; readPos
  mov xl, yl
  mov xh, yh
  adiw xh:xl, @4
  add xl, r17
  adc xh, r17
  sub xh, r17
  ld r16, X
  inc r17
  cp r17, r18
  brcs l_store
  clr r17       ; wrap-around
l_store:
  std Y+@2, r17 ; readPos
  sec
l_end:
.endmacro
; @end



; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_peekbyte
;
; @param Y   base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @return R16 byte read
; @clobbers R17, R18, X

.macro m_ringbuffer_y_peekbyte
  ldd r18, Y+@0 ; maxBytes
  ldd r17, Y+@1 ; usedBytes
  tst r17
  clc
  breq l_end
  ldd r17, Y+@2 ; readPos
  mov xl, yl
  mov xh, yh
  adiw xh:xl, @4
  add xl, r17
  adc xh, r17
  sub xh, r17
  ld r16, X
  std Y+@2, r17 ; readPos
  sec
l_end:
.endmacro
; @end



; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_reset
;
; @param Y   base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @clobbers R17

.macro m_ringbuffer_y_reset
  clr r17
  std Y+@1, r17 ; usedBytes
  std Y+@2, r17 ; readPos
  std Y+@3, r17 ; writePos
l_end:
.endmacro
; @end




