This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LX51 - what code changes are needed to access 128K of memory

I have a board with a DS80C310. I have been using Keil tools for years. We are considering expanding from 48K of RAM to 128K RAM. I was reading the Keil newsletter which discusses the new LX51 Extended Linker product. This sounds like it will do the trick.

What do I have to do to take advantage of this capability (other than buy the upgrade)? Do I need to make any hardware changes? Do I need to define the memory as FAR instead of XDATA? Is accessing memory in the first 64K different than in the upper 64K? Can I transparently access one large array that starts in the lower 64K and runs up into the upper 64K?

  • The place to start is to take a look at the XBANKING.A51 file in the LIB directory. This is where you configure the far memory.

    The C51 Compiler uses 3-byte generic pointers to access far memory areas. far variables are placed in the HDATA memory class and far const variables are placed in the HCONST memory class.

    The LX51 linker/locater allows you to locate HDATA and HCONST in the logical 16 MBYTE CODE or 16 MBYTE XDATA spaces.

    The memory access itself is performed via eight different subroutines that are configured in XBANKING.A51. These routines are:


    * ?C?CLDXPTR and ?C?CSTXPTR: Load and store BYTE (char) in extended memory.

    * ?C?ILDXPTR and ?C?ISTXPTR: Load and store WORD (int) in extended memory.

    * ?C?PLDXPTR and ?C?PSTXPTR: Load and store 3-BYTE PTR in extended memory.

    * ?C?LLDXPTR and ?C?LSTXPTR: Load and store DWORD (long) in extended memory.


    Note that XBANKING.A51 provides examples for these routines.

    Each function receives a parameter which is the 3-byte memory address. Registers R1, R2, and R3 contain the pointer. R3 contains the memory type as shown in the following table:

    R3 Value | Memory Type | Memory Class | Address Range
    -----------------------+--------------+------------------------------------
       00    | data/idata  | DATA/IDATA   | I:0x00     - I:0xFF
       01    | xdata       | XDATA        | X:0x0000   - X:0xFFFF
     02-7F   | far         | HDATA        | X:0x010000 - X:0x7E0000
     80-FD   | far const   | HCONST       | C:0x800000 - C:0xFD0000 (see note)
       FE    | pdata       | XDATA        | One 256-byte page in XDATA memory
       FF    | code        | CODE         | C:0x0000   - C:0xFFFF

    Note: the far const memory area is mapped into the banked memory areas.

    The R3 values 00, 01, FE, and FF are already handled by the C51 run-time library. So, you don't need to write any special code for them. Only the values 02-FE are passed to the XPTR access functions.

    The AX51 macro assembler provides the MBYTE operator that calculates the R3 value to pass to the XPTR access function. For example:

    MOV  R1,#LOW   (variable)   ; gives LSB address byte of variable
    MOV  R2,#HIGH  (variable)   ; gives MSB address byte of variable
    MOV  R3,#MBYTE (variable)   ; gives memory type byte of variable
    CALL ?C?CLDXPTR             ; load BYTE variable into A

    Obviously, the address lines A16 and up must come from somewhere. If you are using a standard 8051-type device, you'll have to get them from P1 or P3 for A16, A17, A18, and so on.

    You must write the code for the XPTR routines to set these bits (from R3) when you do a memory access via XDATA or CODE (using the MOVX or MOVC instructions).

    One caveat is that the size of an individual object is limited to 64K. So, you can't create 8 megabyte arrays. Note that you CAN, however, use a pointer to an 8 megabyte array! You'll just have to be sure that nothing else uses that memory (that's easy to do if you use XDATA for all your other variables.)

    Hopefully, this info helps.

    Jon