Page 1 of 1
Modules containing SFR

Posted:
Tue May 14, 2013 4:38 pm
by bitfogav
Hi, Ive noticed some of the Modules contain waddr0, *(waddr0), waddr1, *(waddr1), addr0. addr1, *(addr0), *(addr1). Are they special file registers (SFR) or what are there function, as I can't find any documentation on them?.
Re: Modules containing SFR

Posted:
Tue May 14, 2013 4:49 pm
by Jerry Messina
They're declared in library/sys.imports/SysVars.bas
They're "pointer" registers (the FW equivalent of the PIC18 FSR0/FSR1 registers) that allow you to do memory indirect operations with ram. They PIC24 can use any of the WREGx's to do this, unlike the PIC18.
Re: Modules containing SFR

Posted:
Tue May 14, 2013 5:20 pm
by bitfogav
Thanks Jerry

So whats is the difference between this below?, is the * symbol a pointer?.
- Code: Select all
addr0
and
- Code: Select all
*(addr0)
Re: Modules containing SFR

Posted:
Tue May 14, 2013 5:49 pm
by Jerry Messina
addr0 is an alias for WREG12. You load the address of the memory region into it, something like
addr0 = addressof(myarray)
The asterisk says "use the contents of the register as a pointer", so *(addr0) accesses the contents of myarray(0).
You'll also see operators mixed in with these, like *(addr0+) and *(addr0-)... these will access the location and increment/decrement the pointer automatically for you.
There's a lot of powerful instructions in the PIC24. You can see the others described in section 4.1.3 Register Indirect Addressing of the 16-bit Programmers Reference Manual (DS70157F)
Re: Modules containing SFR

Posted:
Tue May 14, 2013 6:02 pm
by David John Barker
I will just add that the reason I have implemented this (rather than using FSR or WREG) is to make it hardware independent. For example, if you look at the "strings" module you will see lots of reference to addr0, *(addr0) and so on. This module will build for 8, 16 and 32 bit architectures without any changes required, so it is very portable.
Re: Modules containing SFR

Posted:
Tue May 14, 2013 6:39 pm
by bitfogav
Thanks guys thats cleared up everything, Jerry you even answered my next question which was what "*(addr0+) and *(addr0-)" did! Thanks.

Just incase anyone wanted to check the Reference Manual (DS70157F) heres a link to it:
http://ww1.microchip.com/downloads/en/DeviceDoc/70157F.pdf
Re: Modules containing SFR

Posted:
Tue May 14, 2013 7:06 pm
by David John Barker
Here is a quick reference guide:
Byte Access (addr0, addr1 or baddr0, baddr1)- Code: Select all
addr = AddressOf(var) ' put address of var into addr
var = *(addr) ' get byte value at address
var = *(-addr) ' decrement address by one byte, then get byte value
var = *(+addr) ' increment address by one byte, then get byte value
var = *(addr-) ' get byte value, then decrement address by one byte
var = *(addr+) ' get byte value, then increment address by one byte
Word Access (waddr0, waddr1)- Code: Select all
waddr = AddressOf(var) ' put address of var into waddr
var = *(waddr) ' get word value at address
var = *(-waddr) ' decrement address by two bytes, then get word value
var = *(+waddr) ' increment address by two bytes, then get word value
var = *(waddr-) ' get word value, then decrement address by two bytes
var = *(waddr+) ' get word value, then increment address by two bytes
Re: Modules containing SFR

Posted:
Fri Jun 28, 2013 2:49 pm
by bitfogav
Hi,
I just thought I would quickly try this out, but I can't get the following code to work.. Am I missing something?
- Code: Select all
dim count as byte = 0
dim myArray(5) as byte = {1,2,3,4,5}
Sub Main()
dim myArrayData as ushort = nothing
addr1 = addressof(myArray)
Do
myArrayData = *(addr1+)
Console.Write("myArrayData = ",str(myArrayData),13,10)
count += 1
loop until count = 5
End Sub
Console output:
myArrayData = 1
myArrayData = 0
myArrayData = 0
myArrayData = 0
myArrayData = 0
Re: Modules containing SFR

Posted:
Fri Jun 28, 2013 3:18 pm
by David John Barker
You have to be really careful when using registers directly, as other subroutines may be using them. They are volatile in nature. In your code example, you are making calls to various other routines, for example Write() and Str(). If you examine the code for the console Write(), you see it touches addr0. If you examine the code for Str(), you will see it touches addr1 (and therefore corrupts it).
Using addrx is perfectly safe, but you it is only recommended when you can see explicitly that no other code will affect the contents of the register. For example, copying the contents of one ram location to another really quickly is a great example of when to use direct register access. If making subroutine calls between initialising a register, you must be confident it doesn't use the same register.
Re: Modules containing SFR

Posted:
Fri Jun 28, 2013 3:40 pm
by bitfogav
Thank you David for taking the time to explain that, and of course your right.. I totally forgot about other routines using the addr0 and addr1..
This was a quick test for something I was working towards and I was using the Console as a quick debug, totally my mistake!

Ive changed the Code to give an example:
- Code: Select all
dim count as byte = 0
dim myArray(5) as byte = {1,2,3,4,5}
dim myNewArray(5) as byte = {0,0,0,0,0}
Sub Main()
addr0 = addressof(myArray)
addr1 = addressof(myNewArray)
Do
*(addr1+) = *(addr0+)
count += 1
loop until count = 5
for i as byte = 0 to 4
Console.Write("myNewArray = ",str(myNewArray(i)),13,10)
next
End Sub
Console Output now:
myNewArray = 1
myNewArray = 2
myNewArray = 3
myNewArray = 4
myNewArray = 5