Modules containing SFR

Discuss the Firewing language

Modules containing SFR

Postby bitfogav » Tue May 14, 2013 4:38 pm

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?.
User avatar
bitfogav
 
Posts: 75
Joined: Sat Nov 17, 2012 11:46 am
Location: UK

Re: Modules containing SFR

Postby Jerry Messina » Tue May 14, 2013 4:49 pm

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.
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Modules containing SFR

Postby bitfogav » Tue May 14, 2013 5:20 pm

Thanks Jerry :)

So whats is the difference between this below?, is the * symbol a pointer?.

Code: Select all
addr0

and
Code: Select all
*(addr0)
User avatar
bitfogav
 
Posts: 75
Joined: Sat Nov 17, 2012 11:46 am
Location: UK

Re: Modules containing SFR

Postby Jerry Messina » Tue May 14, 2013 5:49 pm

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)
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Modules containing SFR

Postby David John Barker » Tue May 14, 2013 6:02 pm

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.
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: Modules containing SFR

Postby bitfogav » Tue May 14, 2013 6:39 pm

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
User avatar
bitfogav
 
Posts: 75
Joined: Sat Nov 17, 2012 11:46 am
Location: UK

Re: Modules containing SFR

Postby David John Barker » Tue May 14, 2013 7:06 pm

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
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: Modules containing SFR

Postby bitfogav » Fri Jun 28, 2013 2:49 pm

Hi,

I just thought I would quickly try this out, but I can't get the following code to work.. Am I missing something? :roll:

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
User avatar
bitfogav
 
Posts: 75
Joined: Sat Nov 17, 2012 11:46 am
Location: UK

Re: Modules containing SFR

Postby David John Barker » Fri Jun 28, 2013 3:18 pm

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.
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: Modules containing SFR

Postby bitfogav » Fri Jun 28, 2013 3:40 pm

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! :oops:

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
User avatar
bitfogav
 
Posts: 75
Joined: Sat Nov 17, 2012 11:46 am
Location: UK


Return to Language

Who is online

Users browsing this forum: No registered users and 6 guests

x