EDIT: I have tested this on WinAPE and so far it seems to work.
EDIT 2: I can get it to work for rotating right, but not left...
Imagine memory address &1000 - &1003 contain the following, in order: &23, &45, &67, &89.
Code: Select all
LD HL,&1000
LD A,(HL) ;A = &23
PUSH HL
Code: Select all
RRD ;A = &23, &1000 = &32 &45 &67 &89
INC HL
RRD ;A = &25, &1000 = &32 &34 &67 &89
INC HL
RRD ;A = &27, &1000 = &32 &34 &56 &89
INC HL
RRD ;A = &29, &1000 = &32 &34 &56 &78
POP HL
PUSH HL
RRD ;A = &22, &1000 = &93 &34 &56 &89
INC HL
RRD ;A = &24, &1000 = &93 &23 &56 &78
INC HL
RRD ;A = &26, &1000 = &93 &23 &45 &78
INC HL
RRD ;A = &28, &1000 = &93 &23 &45 &67
POP HL
RRD ;A = &23, &1000 = &89 &23 &45 &67
This test worked for a 4 byte long range, but it seems like it can be generalized with the following (untested) code:
Code: Select all
RRCA_Range:
;input:
;B = total size of memory range to rotate (measured in bytes)
;HL = address of zeroth element of the range.
LD A,(HL) ;ACCUMULATOR NEEDS TO EQUAL THE FIRST BYTE OF THE RANGE FOR THIS TO WORK
PUSH HL
PUSH BC
loop_RRCA_Range_firstloop:
RRD
INC HL
DJNZ loop_RRCA_Range_firstloop
POP BC
POP HL
PUSH HL
PUSH BC
loop_RRCA_Range_secondloop:
RRD
INC HL
DJNZ loop_RRCA_Range_secondloop
POP BC
POP HL
RRD
RET
Code: Select all
macro rrca_MemoryRange,addr,count
LD HL,\addr
LD b,count
call RRCA_Range ;the above subroutine
endm