I have read all the Texas Instruments (TI) Signal Processing Resource (SPR) documents (and videos) I could find about C28 Direct Addressing.
It has been written that Direct Addressing is supposed to be better and swifter than Indirect Addressing but it appears to be, to me, and most importantly, potentially dangerous.
For Direct Addressing, one should first load the Data Page Pointer (DP) for the variable, which consumes one cycle, to then access the CORRECT variable. If one does not first load DP and assumes that DP is currently correct for a particular variable, it could have disastrous consequences.
For Indirect Addressing, one MUST first load the complete address of the variable, which also consumes one cycle, and there is no need to be concerned if the CORRECT variable is being accessed because it has no association with the current DP value.
Refer to the conversation at: http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/320270.aspx?pi269061=1
It also appears to be impossible to reliably (and swiftly) confirm that the DP register is currently loaded CORRECTLY, unless one does reload it each and every time each variable is accessed.
Also, because any added, deleted, or changed software variables (or elements of any variable) between compiles could place various variables in completely different Data Pages, one cannot GUARANTEE that the Data Page required for a variable will ALWAYS be the same for other supposedly associated variables (maybe in one compiled version but not in another where variables may have been added, deleted, or resized).
Also, one should always set the blocking flag to reset the page boundary when necessary as, for example:
VarA01: .usect ".ebss", 1, 1 ;blocking flag = 1 to reset page boundary
VarA02: .usect ".ebss", 1
VarA03: .usect ".ebss", 1
…
VarA60: .usect ".ebss", 1
VarB01: .usect ".ebss", 1, 1 ;blocking flag = 1 to reset page boundary
VarB02: .usect ".ebss", 1
VarB03: .usect ".ebss", 1
It is also evidently impossible to pass a pointer to a ‘C’ variable into a ‘C’ callable assembly function (via XAR4) to then set the Data Page for that variable. For example, the ‘C’ callable assembly function below:
short int Sum64Max(short int *words, unsigned short count);
will have the pointer to words in XAR4 but there is no instruction available to load the DP register using XAR4 as required such as:
MOVW DP, XAR4 ;set DP for page of given pointer. NO SUCH INSTRUCTION!!!
Also, it appears that there are no instructions available to allow one to access an array of variables of a Data Page. For example, there is no instruction available such as MOV @Var+AL, #0 in the code below:
VARSIZE: .set 64 ;maximum possible words in page
Var: .usect ".ebss", VARSIZE, 1 ;blocking flag = 1 to reset page boundary
_Test:
MOV AR5, #VARSIZE
MOV AL, #0
MOVW DP, #Var
LOOP64:
MOV @Var+AL, #0 ;write to location. NO SUCH INSTRUCTION!!!
ADD AL, #1 ;increment location
BANZ LOOP64, AR5--
LRETR
but one can execute an instruction such as:
MOV @Var+68, #0XFFFF ;valid instruction to write to location but is 4, not 68
One may also assume that one could use the instruction such as MOV @AL, AH, versus MOV @Var, AH, to access an array as in the code below:
VARSIZE: .set 64 ;maximum possible words in page
Var: .usect ".ebss", VARSIZE, 1 ;blocking flag = 1 to reset page boundary
_Test:
MOVW DP, #Var
MOV AL, #Var
AND AL, #0X3F
MOV AH, #0
MOV AR0, #VARSIZE
LOOP64:
MOV @AL, AH ;!!!@AL is not what is "at" AL but IS AL and is identical to MOV AL, AH
ADD AH, #1 ;increment value
ADD AL, #1 ;increment pointer
BANZ LOOP64, AR0--
LRETR
However, one quickly learns that MOV AL, AH and MOV @AL, AH are the same operation and MOV @AL, AH is nothing at all like the instruction MOV @Var, AH. And there is also no instruction such as MOV *AL, AH as there is MOV *XAR4, AH.
Fortunately, Indirect Addressing can be used as follows:
_Test:
MOVL XAR4, #Var
MOV AH, #0
MOV AR0, #VARSIZE-1
LOOP64:
MOV *XAR4++, AH ;move and increment pointer
ADD AH, #1 ;increment value
BANZ LOOP64, AR0--
LRETR
And, for initializing variables to the same value, how can Direct Addressing beat this?
_Test:
MOVL XAR4, #Var
MOV AH, #0
RPT #VARSIZE-1 || MOV *XAR4++, AH
LRETR
Also evidently, the only way to Direct Address variables is if each variable of the page has a name assigned to it and it is not an array. For example, instead of simply having an array of variables as:
Var: .usect ".ebss", 64, 1 ;blocking flag = 1 to reset page boundary
one must have each and every variable element named as, for example:
Var01: .usect ".ebss", 1, 1 ;blocking flag = 1 to reset page boundary
Var02: .usect ".ebss", 1
Var03: .usect ".ebss", 1
…
Var62: .usect ".ebss", 1
Var63: .usect ".ebss", 1
Var64: .usect ".ebss", 1
TI urges “Extreme caution” when utilizing asm inline code in ‘C’ code.
Evidently, TI should also urge “Extreme caution” when utilizing Direct Addressing.
Don’t you agree?
If there is additional information about Direct Addressing that I am not aware of, please do not hesitate to indicate so. Any information would be greatly appreciated.
Thank you,
Tim