
NEWLY ADDED FEATURES *** CC5X
-----------------------------

NOTE: the newly added features are listed first.


>> Version 3.4H released


>> Version 3.4E released


>> Version 3.4D released


>> Version 3.4C released


** Automatic search in installed directory for include files

   The compiler will automatically search in the installed directory
   for include files. This means that option
   -I"C:Program Files\bknd\CC5X" or similar is not required to
   include device header and math header files. The search in the
   installed directory is done after other directories specified
   using option -I have been searched.


>> Version 3.4B released


** PIC1xLF and PIC1xF devices use same header file

  The compiler will include the header file for the corresponding F
  device when working with a LF device. These header files are
  normally identical except for the device name. An option will
  disable this merging and allow a separate header file for the LF
  device:

    -csh : include separate chip header file for 'LF' devices


** Warning for read-modify-write sequences on the same PORT

  The compiler will check read-modify-write instruction sequences on
  the same PORT, and generate a warning if a failure may occur. Such
  sequences consist of a read-modify-write (or write) instruction
  immediate followed by a read-modify-write instruction on the same
  PORT. This may result in wrong output state on some PORT pins
  depending on CPU speed and capasitive load on the PORT pins. The
  problem (and warning) can be avoided by doing the last
  read-modify-write operation on the LATCH register instead of the
  PORT register (Enhanced 14 bit core devices have PORT latch
  registers). The warning can be removed by the following option:

    -wf : no warning for read-modify-write sequences on the same PORT


>> Version 3.4A released


>> Version 3.4 released


** The STANDARD edition now supports 32 bit integers


** Improved code generator

  The code generator has been enhanced for all devices. This means
  faster and more compact code for 24 and 32 bit operations. It also
  means better code for signed right shifts and some other special
  cases.

  Applications requiring compatibility with old compiler versions
  can use the following:

    -cl0 : option to use old code generator for whole application

    #pragma codeLevel 0
    // use old code generator in this region
    ..
    #pragma codeLevel 1


** Support for new Enhanced 14 bit Core

  New devices with Enhanced 14 bit core allow up to 32k words of code,
  4k RAM and SFR adressing, 16 level stack, linear RAM adressing,
  fast interrupt handling and several new instructions.

  See file DEMO-ENH.C for syntax examples.

  The symbol __EnhancedCore14__ is defined (equal to 1) when
  compiling code for devices using Enhanced Core 14.

  Symbol __CoreSet__ = 1410  : 14 bit enhanced core
                       1400  : 14 bit standard core
                       1200  : 12 bit core


** New internal function offsetof( struct_type, struct_member)

  Function offsetof() returns the offset to a structure member. The
  first argument must be a struct type, and the second a structure
  member. The function can also be used in a preprocessor
  expression.

    typedef struct sStx {
        char a;
        uns16 b;
    } Stx;

    x = offsetof( Stx, b);
    x = offsetof( struct sStx, a);
    x = offsetof( struct_x, member_n.sub2.q[3]);


** List file with no page formatting

  Option -Ln will produce a list file with no page formatting.


>> Version 3.3H released


** Support of the standard __LINE__ and __FILE__ macros


** Simplified state definition for multitasking

  Task states normally have to be enumerated from 1..N with no
  missing numbers in between. It is now possible to use an undefined
  symbol to represent the state without any state numbering
  conflicts. The compiler defines any unknown symbols and missing
  state numbers to the lowest unused state numbers. Defined state
  number can be mixed with unknown state numbers.

      enum { SA = 1, X_STATE = 3 };
      ..
      waitState(SA);        // defined state number (1)
      ..
      waitState(X_STATE);   // defined state number (3)
      ..
      waitState(ST_Z);      // state number defined by compiler (2)
      ..
      waitState();          // state number defined by compiler (4)
      ..
      changeState(ST_Z);    // return to state ST_Z


** Alternative assignment of command line symbols

  Symbols defined on the command line normally use '=' to separate
  the symbol and the symbol contents. It is now possible to use most
  ASCII token different from letters, numbers and '_' to mark the
  end of the symbol. This makes it easier to avoid command line
  interpretation conflicts. Examble:

      -DMY_SYMBOL:100   is equivalent to  #define MY_SYMBOL 100


>> Version 3.3A released


** Standard MPASM EQU symbols can define config settings

  Complete example setup is found in file CONFIG.TXT.

    #pragma config = _PWRTE_ON & _WDT_ON & _LP_OSC
    #pragma config reg2 = _WRT_256 & _BOR21V


** Multiple include paths can be separated by semicolons

  A single -I option may contain multiple include paths
  separated by semicolons (instead of using separate -I
  options).

    -Ic:\path\to\inc1;c:\path\to\inc2;\inc3;inc4


** Extended search for include files

  The compiler can search more directories for include files
  when using option -cif. Step 3) and 4) are the default
  search for include files that are performed without this option.

    1) in the directory that contains the file being compiled

    2) if the file being compiled was included from another file,
       then the directory containing this file is searched.
       This is repeated until the directory of the initial (root)
       file has been searched.

    3) in current directory (where the compiler was started).
       This step is NOT performed when using #include <file>
       or option -cxc.

    4) in include directories defined by the -I option


** Multiline comment allowed in #define

  A comment after #define may end at a following line:

    #define M1  1  /* This comment
                      is legal */


>> Version 3.3 released


** Stack allocation alternatives

  The stack for local variables, parameters and temporary
  variables is normally allocated separately in each bank
  and the shared RAM area. The bank is normally defined the
  same way as global variables through #pragma rambank or
  bank type modifiers. This makes it possible to split the
  stack into several independent stacks. Using a single
  stack is normally recommended, but sometimes this is not
  possible when the stack size is too large.

  The following pragma will define a single main stack. The
  main stack is not an additional stack, but tells the
  compiler where the main stack is located (which bank).

    #pragma mainStack 3 @ 0x20  // set lower main stack address

  Using this pragma means that local variables, parameters
  and temporary variables of size 3 bytes and larger
  (including tables and structures) will be stored in a
  single stack allocated no lower than address 0x20. Smaller
  variables and variables with a bank modifier will be
  stored according to the default/other rules. Using size 0
  means all variables including bit variables.

  Note that the bank defined by #pragma rambank is ignored
  for variables stored in the main stack. Address ranging
  from 0x20 to 0x6F/0x7F are equivalent to the bank0 type
  modifier.

  In some cases it will be efficient to use shared RAM or a
  specific bank for local variables up to a certain size.
  This is possible by using the following pragma:

    #pragma minorStack 2 @ 0x70

  In this case, local variables, parameters and temporary
  variables up to 2 bytes will be put in shared RAM from
  address 0x70 and upward. Larger variables and variables
  with a bank modifier will be stored according to the
  default/other rules. Using size 0 means bit variables
  only. This pragma can be used in combination with the main
  stack. The variable size defined by the minor stack have
  priority over the main stack.

  The most efficient RAM usage is to use a single stack.
  Separation into different stacks increase total RAM usage,
  and should be avoided if possible.


** Strongly improved SQRT rutine

  The new square root routine developed by Jim van Zee,
  Seattle, executes fast (1/3 of the time) and is small
  (save more than 50 % code). An additional benefit is
  improved accuracy. The routine is available for 24 and 32
  bit floating point. The new routine is automatically used
  when including "math24lb.h" or "math32lb.h".


** Address sorting in the HEX file

  The records in the HEX file are sorted according to the
  address. Option -chu will disable this sorting for
  backward compatibility with old compiler versions.


** Option for chip redefinition

  MPLAB supplies the option -p<chip> automatically.
  Sometimes this is not desirable. The new option -p- will
  clear any preceding -p<chip> to allow chip redefinition,
  either by a new -p<chip> or a #pragma chip statement.


>> Version 3.2N released


** Macros can be used in #include files

  The following examples show the possibilities. Note that this
  is not standard C.

     #include "file1"  ".h"    
     #define MAC1 "c:\project\"
     #include MAC1 "file2.h"
     #define MAC2  MAC1 ".h"
     #include MAC2
     #define MAC3 <file3.h>
     #include MAC3

  RULES:
    1. Strings using "" can be splitted, but not strings using <>
    2. Only the first partial string can be a macro
    3. Nested macros is possible
    4. Only one macro at each level is possible


** Support of CCINC and CCHOME

  Environment variables can be used to define include
  folders and primary folder:

  Variable CCINC is an alternative to the -I<path> option.
  The compiler will only read this variable (or specified
  variable) when using the following command line option:

    -li       : read default environment variable CCINC
    -li<ENVI> : read specific environment variable

  Variable CCHOME can be used to define the primary folder
  during compilation. The compiler will only read this
  variable (or specified variable) when using the following
  command line option:

    -lh       : read default environment variable CCHOME
    -lh<ENVP> : read specific environment variable


>> Version 3.2K released


>> Version 3.2I released


** New type modifier 'shadowDef'

  The 'shadowDef' type modifier allow local and global
  variables and function parameters to be assigned to
  specific addresses without affecting normal variable
  allocation. The compiler will ignore the presence of these
  variables when allocating global and local variable space.

    shadowDef char gx70 @ 0x70;  // global or local variable

  The above definition allow location 0x70 to be inspected and
  modified through variable 'gx70'.


** Assigning function parameters to specific locations

  Function parameters can be assigned to addresses. No other
  variables will be assigned by the compiler to these
  locations. Such manual allocation can be useful when
  reusing RAM locations manually.

    void writeByte(char addr @ 0x70, char value @ 0x71) { .. }

  This syntax is also possible on function prototypes.


** main() can reside in any codepage

  It is possible to locate main() in any codepage if the
  reset vector is omitted. This is done by a pragma statement.

    #pragma resetVector -

  Proper startup code must be inserted manually when removing
  the automatic reset vector, for example by cdata[] statements
  (cdata.txt).


>> Version 3.2G released


** Support for __config and __idlocs

  The compiler will use __config and __idlocs in the
  generated assembly file when #pragma config is used in the
  C source. The old assembly format is still available by
  using the command line option -cfc.


** Macros __DATE__ and __TIME__

  Macros for date and time are defined when compilation starts.

    Macro      Format          Example
    __TIME__   HOUR:MIN:SEC    "23:59:59"
    __DATE__   MONTH DAY YEAR  "Jan  1 2005"
    __DATE2__  DAY MONTH YEAR  " 1 Jan 2005"


>> Version 3.2F released


** Custom warnings and simple messages

  A custom warning or a simple message can be printed in the
  compiler output and to the .occ file. Option -S will suppress
  this. "warning" and "message" are not reserved keywords. Note
  that these directives are not standard C.

    #message This is message 1
    #message This is message 2
    #warning This is a warning

  The following output is produced:

    Message: This is message 1
    Message: This is message 2
    Warning test.c 7: This is a warning


>> Version 3.2A released


** Functions shared between independent call trees

  An error message is normally printed when the compiler detects
  functions that are called both from main() and during interrupt
  processing if this function contains local variables or
  parameters. This also applies to math library calls and const
  access functions. The reason for the error is that local variables
  are allocated statically and may be overwritten if the routine is
  interrupted and then called during interrupt processing.

  The error message will be changed to a warning by the following
  pragma statement. Note that this means that local variable and
  parameter overwriting must be avoided by careful code writing.

    #pragma sharedAllocation


** Improved inline assembly

   The following address operations is possible when the variable/
   struct/array set to a fixed address.

     char tab[5] @ 0x110;
     struct { char x; char y; } stx @ 0x120;
    #asm
     MOVLW tab
     MOVLW &tab[1]
     MOVLW LOW &tab[2]
     MOVLW HIGH &tab[2]
     MOVLW UPPER &tab[2]
     MOVLW HIGH (&tab[2] + 2)
     MOVLW HIGH (&stx.y)
     MOVLW &stx.y
     MOVLW &STATUS
    #endasm


** Output from preprocessor

   The compiler will write the output from the preprocessor
   to a file (.CPR) when using the -B command line option.
   Preprocessor directives are either removed or simplified.
   Macro identifiers are replaced by the macro contents.

     -B[pims]  : write output from preprocessor to <src>.cpr
        p  : partial preprocessing
        i  : .., do not include files
        m  : .., modify symbols
        s  : .., modify strings

   When using the alternative preprocessing formats (-Bpims),
   compilation will stop after preprocessing.


>> Version 3.2 released


** New math operator

   Applies to 8*8 signed multiplication:

     int 8 a, b;
     int16 r = (int16)a * b;

   The following operator is added to math16.h, math24.h and math32.h:

     int16 operator* _multS8x8( int8 arg1, int8 arg2);


** Direct coded instructions

   The file "hexcodes.h" contains C macros that allow direct coding
   of instructions.

   Note that direct coded instructions are different from inline
   assembly seen from the compiler. The compiler will view the
   instruction codes as values only and not as instructions. All
   high level properties are lost. The compiler will reset
   optimization, bank updating, etc. after a DW statement.

   Example usage:
     #include "hexcodes.h"
     ..
     // 1. In DW statements:
     #asm
     DW __DECF(__FSR,__F)         // Decrement FSR
     DW __BCF(__STATUS,__Carry)   // Clear Carry bit
     DW __GOTO(0)                 // Goto address 0
     #endasm
     ..
     // 2. In cdata statements:
     #pragma cdata[1] = __GOTO(0x3FF)


** RAM bank update settings

   #pragma updateBank can be used to instruct the bank update
   algorithm to do certain selections. These statements can only be
   used inside a function:

     #pragma updateBank entry = 0
     /* The 'entry' bank force the bank bits to be set
        to a certain value when calling this function */

     #pragma updateBank exit = 1
     /* The 'exit' bank force the bank bits to be set 
        to a certain value at return from this function */

     #pragma updateBank default = 0
     /* The 'default' bank is used by the compiler at
        loops and labels when the algorithm give up
        finding the optimal choice */


** Origin alignment

   It is possible to use #pragma origin to ensure that a computed
   goto inside a function does not cross a 256 word address
   boundary. However, this may require many changes during program
   development. An alternative is to use #pragma alignLsbOrigin to
   automatically align the least significant byte of the origin
   address. Note that this alignment is not possible when using
   relocatable assembly, and also that it does not apply to the 12
   bit core.

   Example: A function contain a computed goto. After inspecting the
   generated list file, there are 16 instructions between the
   function start and the first destination address (offset 0) right
   after the ADDWF PCL,0 instruction that perform the computed goto.
   The last destination address (offset 10) resides 10 instructions
   after the first destination. A fast a compact computed goto
   requires that the first and last destination resides on the same
   "byte page" (i.e. (address & 0xFF00) are identical for the two
   addresses). This is achieved with the statement:

     #pragma alignLsbOrigin -16 to 255 - 10 - 16

   The alignment pragma statement is not critical. The compiler will
   generate an error (option -GS) or a warning (-GW) if the computed
   goto cross a boundary because of a wrong alignment. An easier
   approach is to align the LSB to a certain value (as long as
   program size is not critical).

     #pragma alignLsbOrigin 0            // align on LSB = 0
     #pragma alignLsbOrigin 0 to 190     // [-255 .. 255]
     #pragma alignLsbOrigin -100 to 10


>> Version 3.1K released


** Easier storing of unpacked strings in EEPROM

   The compiler will normally store cdata strings as 2*7 bits
   packed data. This is now selectable.

     // Store strings packed by default
     #pragma cdata[0x800] = "Hello world!\0"

     #pragma packedCdataStrings 0
     // Store following strings unpacked
     #pragma cdata[0x2100] = "Hello world!\0"
     #pragma cdata[] = 1, 0x80
     // Next statement is legal, but EEPROM use 8 bit only
     //#pragma cdata[] = 0x3FFF

     #pragma packedCdataStrings 1
     // Store remaining strings packed


** Improved const data initialization

   Floating point constant expressions.

   Complex address calculations.

   Enum-symbols allowed.


** Extra config register supported

   Enabled in the header file (#pragma config_reg2 0x2008).

     #pragma config reg2 = 0x1 | 0x2

   See CONFIG.TXT


>> Version 3.1J released


** Improved integer math

   New math library functions for 16*16 and 32*16 bit
   multiplication, signed and unsigned.

     math24.h: int24 operator* _multS16x16( int16 arg1, int16 arg2);
     math24.h: int8  operator% _remS24_8( int24 arg1, int8 arg2);

     math32.h: uns32 operator* _multU16x16( uns16 arg1, uns16 arg2);
     math32.h: int32 operator* _multS16x16( int16 arg1, int16 arg2);
     math32.h: uns32 operator* _multU32x16( uns32 arg1, uns16 arg2);
     math32.h: int32 operator* _multS32x16( int32 arg1, int16 arg2);
     math32.h: int8  operator% _remS32_8( int32 arg1, int8 arg2);

   Inline multiplication will now optimize for speed instead of size
   for signed integer multiplication. Optimization for size on
   inline multiplication (signed and unsigned) can be forced by
   command line option -zZ.


** Improved integer math libraries

   Improved 16 * 16 bit multiplication.

     math24.h: int24 operator* _multS16x16( int16 arg1, int16 arg2);
     math24.h: int8  operator% _remS24_8( int24 arg1, int8 arg2);

     math32.h: uns32 operator* _multU16x16( uns16 arg1, uns16 arg2);
     math32.h: int32 operator* _multS16x16( int16 arg1, int16 arg2);
     math32.h: int8  operator% _remS32_8( int32 arg1, int8 arg2);


>> Version 3.1I released


** Switch statements of 16, 24 and 32 bit

   The switch statement now supports variables up to 32 bit. The
   generated code is more compact and executes faster than the
   equivalent 'if - else if' chain.


>> Version 3.1H released


** Macro stringification and concatenation

   The concatenation operator ## allows tokens to be merged while
   expanding macros. The stringification operator # allows a macro
   argument to be converted into a string constant.


>> Version 3.1G released


** Syntax improvements

   Multiple assignment:
     a = b = c;

   Allowing the increment operator on the left side of a statement:
     ++i;
     --x;

   Improved "increment" part of the 'for' statement :
     for (i=0; i<5; a.b[x]+=2) ..

   Better paranthesis support :
     *(p)
     (p)[0]
     &(l.a)

   Better 'enum' support :
     typedef enum ..
     enum con { Read_A, .. };
     enum con mm;
     mm = Read_A;


** Placing the interrupt routine anywhere

   The interrupt routine normally have to reside on address 4. The
   following pragma statement will allow the interrupt routine to be
   placed anywhere. Note that the compiler will NOT generate the
   link from address 4 to the interrupt routine.

     #pragma unlockISR


** Printing key info in the assembly file

   The compiler will print info at the end of the assembly file.
   Total code size, code size on each code page, maximum call level,
   RAM usage. In addition, the size of each function is printed.
   Command line option -Au removes this information.


>> Version 3.1F released


** Detailed multiline macro expansion in assembly file

   Single lines from multiline macros are printed in the generated
   assembly file when using command line option -AR. This is
   sometimes useful to improve readability when expanding very long
   macros.


** Recursive printing of errors in macros

   If there is a syntax error in a defined macro, then it may be
   difficult to decide what the problem actually is. This is
   improved by printing extra error messages which points to the
   macro definition, and doing this recursively when expanding
   nested macros.


** Automatic incrementing version number in file

   CC5X is able to automatically increment one or more version
   numbers for each compilation. Syntax supported:

   1.  Option : -ver#verfile.c
       #include "verfile.c"  // or <verfile.c>

   2.  Option : -ver
       #pragma versionFile   // next include is version file
       #include "verfile.c"  // or <verfile.c>

   3.  Option : -ver
       #pragma versionFile "verfile.c"  // or <verfile.c>

   Note that the command line option is required to make this
   increment happen. It is the decimal number found at end of
   the included file that is incremented. The updated file is
   written back before the file is compiled. No special syntax is
   assumed in the version file. Suggestions:

     #define MY_VERSION  20
     #define VER_STRING  "1.02.0005"
     /* VERSION : 01110 */

   If the decimal number is 99, then the new number will be 100 and
   the file length increases by 1. If the number is 099, then the
   file length remains the same. A version file should not be too
   large (up to 20k), otherwise an error is printed.

   Formats 2 and 3 above allows more than one version file. It is
   recommended to use conditional compilation to manage several
   editions of the same program.


>> Version 3.1E released


** Detection of REGISTER saving and restoring during interrupt

   CC5X will AUTOMATICALLY check that the registers W, STATUS,
   PCLATH and FSR are saved and restored during interrupt.

   The details about this is found in file 'int16Cxx.h'.

   The error and warning messages printed can be removed:

     #pragma interruptSaveCheck  n  // no warning or error
     #pragma interruptSaveCheck  w  // warning only
     #pragma interruptSaveCheck  e  // error and warning (default)


>> Version 3.1D released


** Better variable overlapping

   Variables can overlap parts of another variable, table or
   structure. Multiple levels of overlapping is allowed.

     char aa @ ttb[2];   // char ttb[10];
     bit  ab @ aa.7;     // a second level of overlapping
     bit  bb @ ttb[1].1;
     size2 char *cc @ da.a;  // 'da' is a struct
     char dd[3] @ da.sloi[1].pi.ncup;
     uns16 ee @ fx.mid16;  // float32 fx;
     TypeX ii @ tab;   // TypeX is a typedef struct


** Using expressions to define addresses

   An expression can now define the address of a variable. This
   makes it easier to move a collection of variables.

     char tty @ (50+1-1+2);
     bit  tt1 @ (50+1-1+2+1).3;
     bit  tt2 @ (50+1-1+2+1).BX1;   // enum { .., BX1, .. };


** Address operations

   The logic for checking address operations is enhanced. The
   supported operations are:

     ADR + EXPRESSION (VARIABLE/CONST)
     ADR - EXPRESSION (VARIABLE/CONST)
     ADR & 0xFF;   // LSB : least significant 8 bits
     ADR % 256;    // LSB : least significant 8 bits
     ADR >> 8;     // MSB : most significant bit(s)
     ADR / 256;    // MSB : most significant bit(s)

   Example:
     FSR = &table[3] & 0xFF;
     IRP = &table[3] >> 8;   // on devices using 9 bit address

   A warning is printed when using other address operations (for
   example &p | 3). This warning is changed to an error when using
   relocatable assembly (option -r).


** Combining inline integer math and library calls

   It is possible to force the compiler to generate inline integer
   math code after a math library is included. This may be useful
   when speed is critical or in the interrupt service routine.
   Functions with parameters or local variables are not reentrant
   because local variables are mapped to global addresses, and
   therefore the compiler will not allow calls from both main and
   the interrupt service routine to the same function.

     uns16 a, b, c;
     ..
     a = b * c;    // inline code is generated
     ..
    #include "math16.h"
     ..
     a = b * c;    // math library function is called
     ..
    #pragma inlineMath 1
     a = b * c;    // inline code is generated
    #pragma inlineMath 0
     ..
     a = b * c;    // math library function is called


** Inline type modifier on math operations

   It is possible to combine inline integer math and math library
   functions without making a special purpose math library. This is
   done by stating that the selected operations are inline BEFORE
   the standard math library is included. It is optimal to use
   inline code when there is only one operation of a certain type.

     inline uns24 operator * (uns24 arg1, uns24 arg2);
     #include "math24.h"

   The math prototypes are found in the beginning of the standard
   math libraries. Just remember to remove the operator name before
   adding the inline type modifier.

   A warning is printed when there is ONE call to a unsigned integer
   math library function. The warning can be disabled by the -wm
   command line option.

   NOTE that the inline type modifier is currently IGNORED, except
   for the math operations.


** Detection of multiple inline math integer operations

   The compiler will print a warning when detecting more than one
   inline math integer operation of the same type. Including a math
   library will save code, but execute slightly slower. Note that
   assembly code inspection and type casts are sometimes needed to
   reduce the number of library functions inserted.

   The warning can be disabled by the -wi command line option.


** Reading program memory on more devices

   The compiler will now read program memory directly on devices
   having the predefined registers:

     PMDATA, PMADR,  PMDATH, PMADRH : 16C925/926, 16F73/74/76/77
     PMDATL, PMADRL, PMDATH, PMADRH : 16C717/770/771, 16C781/782

   The compiler will use computed goto (more code, but faster)
   instead of direct program memory reading when using:

     #pragma wideConstData 8192


>> Version 3.1C released


** cdata outside legal program and eeprom space is disabled

   CODE:   0x0000 - upper program limit
   EEPROM: 0x2100 - 0x21FF : eeprom data space

   The error message can be changed to a warning by using the -cd
   command line option.


