Обнаружение границ и сброс кругового указателя буфера в обоих направлениях
Я работаю с микроконтроллером 8051, но мой вопрос более специфичен для алгоритма.
Я создал круговой буфер в памяти для случайных поступающих данных из внешних источников. Предположим, размер буфера составляет 32 байта, и я получил 34 байта данных. Да, я справлюсь с тем, что два байта отброшены, но если я захочу прочитать последние 5 байтов, мне придется как-то снова обернуться до конца буфера, чтобы прочитать более 2 байтов.
Вот пример кода 8051 того, чего я пытаюсь достичь:
BUFFER equ 40h ;our buffer = 40-5Fh (32 bytes)
BUFFERMASK equ 5Fh ;Mask so buffer doesn't go past 32nd byte
initialization:
mov R1,#BUFFER ;R1=our buffer pointer
mov @R1,#xxh ;Add some incoming data
inc R1
anl R1,#BUFFERMASK
mov @R1,#xxh ;Add some incoming data
inc R1
anl R1,#BUFFERMASK
...
mov @R1,#xxh ;Add some incoming data
inc R1
anl R1,#BUFFERMASK
;At this point we filled a large chunk of the buffer with data.
;Lets assume the buffer wrapped around and address is 41h
;and we want to read the data in reverse
mov A,@R1 ;Get last byte at 41h
dec R1
??? R1,??? (anl won't work here :( )
mov A,@R1 ;Get byte at 40h
dec R1
??? R1,??? (anl won't work here :( )
mov A,@R1 ;Get byte at 5Fh (how do we jump with a logic statement?)
dec R1
??? R1,??? (anl won't work here :( )
Я понимаю, что мог бы обойтись без CJNE (сравнить и перейти, если не равен), но недостатками этого оператора являются: 1.) необходимость в метке для каждого CJNE, 2.) и флаг переноса, изменяемый после выполнения и 3.) дополнительный тактовый цикл теряется, если граница достигнута.
Есть ли способ, которым я мог бы осуществить это с простой логикой anl/orl (И или ИЛИ)? Я готов изменить адрес памяти циклического буфера, если это создает преимущество в моей ситуации.