gnupic@linuxhacker.org

gnupic@linuxhacker.org


Subject: Re: gputils 11.0 default behavior of Access bit
From: Scott Dattalo
Date: Sat, 22 Mar 2003 16:21:43 -0800 (PST)


Craig and I are having a brief discussion wrt the default setting of
banksel bit for the 18f instructions

On Sat, 22 Mar 2003, Craig Franklin wrote:
> 
> Scott Dattalo wrote:
> > 
> > Craig,
> > 
> > I noticed that the default value for the access bit in the 18F
> > instructions has changed in 11.0. The new version is consistant with the
> > data sheet but inconsistent with MPASM (the version of MPASM distributed
> > with pre 6.xx of MPLAB). I don't want to call this a "bug report", because
> > I really don't know what should be the default value of the access bit.
> > 
> > Regards,
> > Scott
> 
> It actually changed in version 0.10.6.  I discovered the difference when
> I added the test files for the new banksel directive.  I think the file
> is:
> 
> /gputils/gpasm/testsuite/gpasm.project/asmfile/banksel4.asm
> 
> When the default hex output changed for gpasm, I had to re-assemble the
> test files.  I used the current version of MPASM at that time, 3.20.  I
> am not sure which version of MPLAB it comes with.
> 
> I didn't run the test on any older version of MPASM, because this new
> version of MPASM was behaving as documented.  I changed gpasm's default
> access bit to match.
> 
> This only effects the default behavior when the access bit is not
> specified.  It would probably be a good idea to always specify the
> access bit in the command, then the default wouldn't matter.
> 
> Maybe the list should know about this.  If you like, forward this
> message to the list, so everyone knows about the change.  It is only
> briefly mentioned on line 71 of the ChangeLog.



Okay, I dug into this a little more and found this in directive.c at
around line 2824:

          /* Default access (use the BSR unless access is to special
             registers) */
          if ((file < 0x60) || (file > 0xf5f)) {
            a = 0;
          } else {
            a = 1;
          }
          
In the pre-11.0 versions we had this:  

          int a = 0; /* Default access (don't use the BSR) */

In my code, I clear BSR at the beginning so that any access to address 0
through 0xff will always go to physical addresses 0 through 0xff. What got
me was that an access to a variable at address 0x64 was causing the 'a'
bit to get set. But accesses below 0x60 were not. I don't know why the
directive.c uses 0x60 as the decision line for using the BSR or not.
Instead it should be like this:

          if ((file < 0x80) || (file > 0xf7f)) {
            a = 0;
          } else {
            a = 1;
          }

But the default behavior of the "a" bit is ambiguous. Early versions of   
MPASM are the opposite of the data sheet.

For example, here's the description of the ANDWF instruction for the
18f452:

The contents of W are AND ed with register 'f'. If 'd' is 0, the result is
stored in W. If 'd' is 1, the result is stored back in register 'f' 
(default). If a is 0, the Access Bank will be selected. If a is 1, the BSR
will not be overridden (default). 

However, I know that the default is in fact a=0.

So, it might be better to do something like this:
           
        { 
          /* If the access bank is not specified, then let the default
             value be controlled by 'default_bank_select'
          
          int a = default_bank_select;

          /* Don't use BSR for special function registers or for
             the beginning of memory */

          if (!override_default_BSR && ((file < 0x80) || (file > 0xf7f)) {
            a = 0;
          }
          
          ....
          
        }
           
Then define a new command line option:

   --default_BSR [0|1]  - if the A bit is not specified in an 18F
                          instruction then it's default value can be
                          selected here. The default is 0.


Now, there probably should be a warning generated for code like this:

"some_reg" is at address 0x123 which is the second bank.

    MOVF  some_reg,W,A

Here we're saying *not* to use the BSR, yet our register can only be
accessed if BSR =1 and we use:
          
B   EQU   (A^1)

    MOVF  some_reg,W,B

(as an aside, I've toyed with the idea of adding a simulator assertion so
that you could write:
             
             
    assert BSR=(some_reg>>8)
    movf   some_reg,W,B
            
)

Scott


gnupic@linuxhacker.org