I have done some research on this over the weekend too. It looks like the
compiler treats sfr as byte, volatile, and copies the "initializer" value to be
the absolute address (if specified and at not specified) in the data address
space 0x80-0xFF. For a test I declared "sfr at 0x80 P0;" and "data at 0x80 P1;"
and I believe from the linker map that they were at the same location. There
was certainly no error excluding access to data space above 0x80. In addition I
declared some bitfield structures "data at 0x80 struct {unsigned i :3; unsigned
:2; unsigned j:3) P0" and likewise for sfr. Neither got a syntax error about
the structure field definitions, but the one in data space had to be accessed as
an aggregate and the one in sfr space could not be accessed as an aggregate. I
think is boils down to the noun being STRUCT vs. SFR, but I don't understand
bison well enough yet to be sure.
My quest was to find an easier way to handle the bits in those sfrs that are not
at a mod 8 address (ie not bit addressable)
so we could have "sfr at 0x99 struct {unsigned lsbfield : 1; unsigned :7} JUNK;"
be accessed as JUNK.lsbfield = 0; rather than JUNK &= (^_lsbfield_define); or
some such. I'm not worring about the sbits in the bit address space. Although
they could be accessed both ways, as bits in the bit address space or as
bitfields of the bytes in the sfr address space. This might be convenient for
things like the register bank select which is a two bit field or some of the
timer mode control fields which are 3 bits.
I'm not sure whether bit fields can really be restricted to a single byte or
whether they always expand to sizeof(int).
In any case, it seems strange/broken that a bitfield structure definition in sfr
space is silently ignored on the declaration but does not result in an aggregate
object being created. It looks like declaring something in data space above
0x80 using the at syntax rather than the initial value syntax and making it a
volatile byte is equivalent to declaring it to be an sfr except that the data
space declaration can be a structure while the sfr space declaration can not.
Sandeep Dutta wrote:
>
> Hi Steven,
>
> There can be no "data" variables in the 0x80-0xff range. This range
> overlaps with the "sfr" space. The 0x80-0xff address range maps onto
> different address spaces depending on direct or indirect addressing.
> Direct addressing it maps to the SFR space indirect addressing will map
> to IDATA space.
> The compiler generates indirect addressing for bit fields, so that makes
> it impossible to define the "sbits" as bit fields.
> If you declare them as "sbits" however you can twiddle away using the
> standard C syntax.
>
> sbit SB1 at xxx
> sbit SB2 at yyy
>
> foo() {
> ...
> SB1 ^= SB2;
> ...
> }
>
> is perfectly valid.
>
> Sandeep
|