| Getting some extra near constants (NCONST) in Keil C166 |
By default the C166 compiler allows 16kb of near fast access constants. It is possible to extend this to 32kb via the DPPUSE control in the linker. A common requirement though is to have two quite distinct fast constants areas. In many control systems, there is a large area for calibration data which is either preprogrammed at build time or is in FLASH and updated periodically over time. There is also often the need for a second area which holds "system" constants that are typically scale factors, offsets etc. and will never be updated during the lifetime of the product.
There is no obvious way to support two near constant areas in C166 but we have come up with the following trick which you could use!
The method relies on the fact that in most external ROM C167 designs, there is ROM in the 0xC000-0xDFFF area that in fact lies in the range of DPP3. Usually this region will contain just code however this trick allows fast access constants to be placed there. As they are within the DPP3 area, they can be addressed as if they were in the normal near constant area, i.e. with one instruction. We will refer to this area as a the "extra const" region!
The constants destined for the large 16kb or 32kb calibration data area are declared in the usual way.
unsigned short const normal_const = 0xaaaa ; // Create a normal nearConstants destined for the extra const area are declared in a special module which contains nothing else.
#pragma RENAMECLASS(FCONST=EXTRA) // A constant declared as far but externally referenced // as sdata. The linker does not quibble over the mismatch // but this is not really desirable unsigned short const far extra = 1 ;The far keyword is used in the declaration to stop the compiler trying to lump this constant data together with the normal constants in the NCONST class. The resulting FCONST class is renamed to something more appropriate such as EXTRA. In fact all this module does is create a table of constant values. This table is located at 0xC000, using a new line in the linker control file:
CLASSES(ICODE(0200H), NCODE(0200H), NCONST(0200H), // Normal near constant area NORMAL(0200H), HCONST(0200H), NDATA(08000H), NDATA0(08000H), FDATA(08000H), FDATA0(08000H), HDATA(08000H), HDATA0(08000H), EXTRA(0xC000-0xDFFF)) & // Extra near constant areaThe trick is in the module that contains the code that makes use of the extra constants. Strictly speaking, the external reference to the extra constants should match exactly the original declaration. However by substituting the "sdata" keyword for the original "far", the compiler will treat the constant as is it were a normal sdata object an use DPP3 to get at it.
// A constant declared as huge but externally referenced as sdata // The sdata keyword tells C166 to use DPP3 addressing extern unsigned short const sdata extra ;Here is how the constants are now accessed, seen in the HiTOP instruction window:

This method relies on the fact that the linker only spots mismatches in type across program modules. Implementation-specific location keywords like far and sdata are not checked.
Using this method on an external ROM C167CR will allow another 8k of near constants to be created. You can get a copy of an example program by requesting our "Programming Examples Disk" to be emailed to you!
Send me more information on the above