bdata space on 80C51

  • A3B

    A3B - 2006-10-06

    I was previously user of Keil C51 compiler where use of bdata space ( union of data and bit fields) was as simple as:
    bdata unsigned char MASCMD;
    sbit SUBADD= MASCMD^0;
    sbit RPSTRT= MASCMD^1;
    sbit SETMRQ= MASCMD^2;
    MASCMD was instanced in bdata (0x20-0x2F) - say 0x20 - and bits
    were at 20.0, 20.1,20.2.
    I could use it simply :
        MASCMD = I2CSTA; // get I2C port status
        if(SUBADD==1) ... // test individual bits

    Apparently, SDCC doesn't accept bdata space definition.
    It says that bdata is not known and if I write:
    data unsigned char MASCMD;
    sbit SUBADD= MASCMD^0;
    sbit RPSTRT= MASCMD^1;
    sbit SETMRQ= MASCMD^2;
    It says that MASCMD initialiser is not constant.

    I found a way to do it (from bitfields.c) :
    data union {
        struct {
              unsigned int SUBADD:1; // bit 0
              unsigned int RPSTRT:1;
              unsigned int SETMRQ:1;
              unsigned int bit3:1;
              unsigned int bit4:1;
              unsigned int bit5:1;
              unsigned int bit6:1;
              unsigned int bit7:1; // bit 7
        unsigned char MASCMD;
    } REG_I2C;
    This is not similar because the union REG_I2C is instanced anywhere in data space : not particularly in bdata addressing space.
    The use of this also is a bit more complex:
       if(REG_I2C.SUBADD == 1) ...

    How could I do to have something close to the Keil C51 in terms of using bdata space ?

    • Raphael Neider

      Raphael Neider - 2006-10-06

      To place your union at a specific location you can use the __at(address) keyword as in
      data union {...} __at(0x20) REG_I2C;

      For ease of access, use macros:
      #define MASCMD    REG_I2C.MASCMD
      #define SUBADD    REG_I2C.SUBADD
      // more to follow

      Define these AFTER you defined your union, otherwise the fields will get expanded too, resulting in invalid code...


    • A3B

      A3B - 2006-10-06

      but if I use thoses bits from ASM file could i use it as simply as :
        / byte RPSTRT defined in such a union UCHAR_BITS
          JNB RPSTRT,MTxStop2


    • A3B

      A3B - 2006-10-09

      Also may I do the following so that bits could be addressable from ASM:
      data OCTET __at 0x24 MASCMD;
      sbit __at 0x32 SUBADD;
      sbit __at 0x33 RPSTRT;
      sbit __at 0x34 SETMRQ;

    • Maarten Brock

      Maarten Brock - 2006-10-12

      If you intend to use asm, declare the byte variable in an absolute segment in asm and use .equ to declare the bits.

      When you use C beware that currently variables located with __at are not allocated by the linker so others can be given the same address.

    • A3B

      A3B - 2006-10-13

      Many thanks for help