; ***************************************************************************
; 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.   *
; ***************************************************************************


.equ RINGBUFFERY_OFFS_MAXSIZE  = 0
.equ RINGBUFFERY_OFFS_USED     = 1
.equ RINGBUFFERY_OFFS_READPOS  = 2
.equ RINGBUFFERY_OFFS_WRITEPOS = 3
.equ RINGBUFFERY_OFFS_DATA     = 4
.equ RINGBUFFERY_SIZE          = 4



; ---------------------------------------------------------------------------
; @routine RingBufferY_Init
;
; @param R16 size of ringbuffer
; @param Y   base address of ringbuffer struct
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17

RingBufferY_Init:
  std Y+RINGBUFFERY_OFFS_MAXSIZE, r16
  rjmp RingBufferY_Reset
; @end



; ---------------------------------------------------------------------------
; @routine RingBufferY_WriteByte
;
; @param R16 byte to write
; @param Y   base address of ringbuffer struct
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17, R18, X

RingBufferY_WriteByte:
  m_ringbuffer_y_writebyte \
    RINGBUFFERY_OFFS_MAXSIZE, \
    RINGBUFFERY_OFFS_USED, \
    RINGBUFFERY_OFFS_READPOS, \
    RINGBUFFERY_OFFS_WRITEPOS, \
    RINGBUFFERY_OFFS_DATA
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RingBufferY_ReadByte
;
; @param  Y     base address of ringbuffer struct
; @return CFLAG set if okay, cleared on error (i.e. buffer empty)
; @return R16 byte read
; @clobbers R17, R18, X

RingBufferY_ReadByte:
  m_ringbuffer_y_readbyte \
    RINGBUFFERY_OFFS_MAXSIZE, \
    RINGBUFFERY_OFFS_USED, \
    RINGBUFFERY_OFFS_READPOS, \
    RINGBUFFERY_OFFS_WRITEPOS, \
    RINGBUFFERY_OFFS_DATA
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RingBufferY_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 empty)
; @return R16 byte read
; @clobbers R17, R18, X

RingBufferY_PeekByte:
  m_ringbuffer_y_peekbyte \
    RINGBUFFERY_OFFS_MAXSIZE, \
    RINGBUFFERY_OFFS_USED, \
    RINGBUFFERY_OFFS_READPOS, \
    RINGBUFFERY_OFFS_WRITEPOS, \
    RINGBUFFERY_OFFS_DATA
  ret
; @end



; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_reset
;
; @param Y   base address of ringbuffer struct
; @clobbers R17

RingBufferY_Reset:
  m_ringbuffer_y_reset \
    RINGBUFFERY_OFFS_MAXSIZE, \
    RINGBUFFERY_OFFS_USED, \
    RINGBUFFERY_OFFS_READPOS, \
    RINGBUFFERY_OFFS_WRITEPOS, \
    RINGBUFFERY_OFFS_DATA
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RingBufferY_ReadByteGuarded
;
; @return CFLAG on success, cleared on error
; @return r16 byte read
; @param Y  base address of ringbuffer struct
; @clobbers R17, R18, X

RingBufferY_ReadByteGuarded:
  push r15
    in r15, SREG
    cli
    rcall RingBufferY_ReadByte                  ; R17, R18, X
    brcc RingBufferY_ReadByteGuarded_error
    out SREG, r15
  pop r15
  sec
  ret
RingBufferY_ReadByteGuarded_error:
    out SREG, r15
  pop r15
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RingBufferY_PeekByteGuarded
;
; @return CFLAG on success, cleared on error
; @param r16 byte to write
; @param Y pointer to start of interface data
; @clobbers R17, R18, X

RingBufferY_PeekByteGuarded:
  push r15
    in r15, SREG
    cli
    rcall RingBufferY_PeekByte                  ; R17, R18, X
    brcc RingBufferY_PeekByteGuarded_error
    out SREG, r15
  pop r15
  sec
  ret
RingBufferY_PeekByteGuarded_error:
    out SREG, r15
  pop r15
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RingBufferY_WriteByteGuarded
;
; @return CFLAG on success, cleared on error
; @param r16 byte to write
; @param Y pointer to start of interface data
; @clobbers R17, R18, X

RingBufferY_WriteByteGuarded:
  push r15
    in r15, SREG
    cli
    rcall RingBufferY_WriteByte                  ; R17, R18, X
    brcc RingBufferY_WriteByteGuarded_error
    out SREG, r15
  pop r15
  sec
  ret
RingBufferY_WriteByteGuarded_error:
    out SREG, r15
  pop r15
  clc
  ret
; @end



