C6805 Product News
The following sections describe new features in Byte Craft Limited Products.
The printed manual has an in-depth view of device header files. See section 2.6.
The environment variables LIBRARY and INCLUDE can be used to specify library and include file directories. For example, to specify that the folder C:\C6805\include be used as the search path for include files type:
SET INCLUDE=C:\C6805\include
LIBRARY and INCLUDE can be set in your AUTOEXEC.BAT file to ensure that they are set every time on start up. For additional information on DOS commands refer to your DOS user guide.
C6805 includes new #pragma directives which support the organized and efficient use of memory resources.
-
Named address space allows you to group variables at specific memory locations.
-
Special address space allows you to declare variables at special memory locations such as external devices or internal EEPROM.
-
Local address space allows you to direct the placement of local variables. You can pass multiple arguments to functions by declaring local variable space.
-
Stack space can be defined using the #pragma memory stack directive.
For more information, see section 10.2.5 of the printed manual.
#pragma memory LOCAL [size] @location;
The LOCAL extension to the #pragma memory directive allows you to direct the placement of local variables. This directive allocates a block of memory for local variable placement, and enables local variable optimization. If this local variable space is declared, then the two byte argument passing limit will no longer apply and multiple arguments can be passed to functions.
The declaration must be for a contiguous block of RAM. The memory space declared for local variables cannot be declared for any other use. Only one #pragma memory LOCAL declaration may be present in a source program.
If no #pragma memory LOCAL directive is used, then local variables will be allocated from global space.
The [size] specified determines the amount of space allocated for local variables. If the size specified is 0, then the compiler determines the amount of space to allocate for local variables. It allocates space equal to the maximum space required for local variables at any given time. The local variable space builds down from the specified location.
Any size other than 0 allocates that amount of space for local variables. The size can be any value between 0 and 128. The local variables space builds up from location.
For more information, see section 10.2.5.3 of the printed manual.
C6805 now supports bit fields in structures. Each bit field contains a user-specified number of bits. A bit field is a member of a structure and is named and accessed like any other structure member.
Bit fields are declared using the following syntax: int name : size; where name is the name of the bit field and size is the number of bits. Bit fields may cross byte boundaries.
The following example shows how to define and access structure bit fields:
struct band { char a;
char ab[3];
int b : 2;
int c : 3;
int d : 2;
int e : 2;
int f;
0054 0006 } abc;
void main (void){ 0100 A6 06 LDA #$06 abc.ab[4] = 6;
0102 B7 59 STA $59 0104 B6 58 LDA $58 abc.c = 7;
0106 AA 1C ORA #$1C 0108 B7 58 STA $58 010A A6 4D LDA #$4D j = 77;
010C B7 51 STA $51 abc.c = i;
010E B6 50 LDA $50 0110 A4 07 AND #$07 0112 48 LSLA 0113 48 LSLA 0114 B7 5A STA $5A 0116 B6 58 LDA $58 0118 A4 E3 AND # 011A BA 5A ORA $5A 011C B7 58 STA $58 011E B6 50 LDA $50 0120 BB 51 ADD $51 0122 A4 07 AND #$07 0124 48 LSLA 0125 48 LSLA 0126 B7 5A STA $5A 0128 B6 58 LDA $58 012A A4 E3 AND # 012C BA 5A ORA $5A 012E B7 58 STA $58 0130 44 LSRA k = abc.c;
0131 44 LSRA 0132 A4 07 AND #$07 0134 B7 52 STA $52 0136 81 RTS } For more information, see section 8.7.3.1 of the printed manual.
The _Bool data type declares a single bit at a specific location in memory. The general syntax is:
_Boolname@address.bitnumber;
For example, the syntax _Bool b @ 0x34.6; declares a single _Bool data type with the name b representing bit 6 at address 0x34.
0034 0006 _Bool b@0x34.6;
0050 char j;
0005 #define bit5 5 0050 0005 _Bool bj@&j.bit5;
0050 0005 _Bool bj1@j.bit5;
void main(void){ 0200 1C 34 BSET 6,$34 b=1;
0202 1B 50 BCLR 5,$50 bj=0;
0204 1A 50 BSET 5,$50 bj1=1;
0206 0D 34 02 BRCLR 6,$34,$020B if (b==1) 0209 1D 34 BCLR 6,$34 b=0;
020B B6 50 LDA $50 b=(j==1)?0:1;
020D A1 01 CMP #$01 020F 26 03 BNE $0214 0211 4F CLRA 0212 20 02 BRA $0216 0214 A6 01 LDA #$01 0216 4D TSTA 0217 26 04 BNE $021D 0219 1D 34 BCLR 6,$34 021B 20 02 BRA $021F 021D 1C 34 BSET 6,$34 021F 81 RTS } Section 8.3.1 of the printed manual describes the data type bit, which is the previous single-bit data type in Code Development Systems. bit is deprecated in favour of _Bool.
The int24 and int32 data types declare variables holding 24 and 32 bit values, respectively. Both declarations may take an @ sign and specific location for the variable. The general syntax is:
int24 variable [@ address];
int32 variable [@ address];
where address must be a constant. Both types may be specified as unsigned.
When you declare variables of these types, the compiler will link in a math library to perform 24 and 32 bit operations. As the 6805 architecture has no 24 or 32 bit registers, the compiler will also declare two pairs of pseudo-registers, __int32ac and __32arg, and __int24ac and __24arg. The 24 bit pseudo-registers overlay the 32 bit pseudo-registers, but the compiler will declare both even in a program using only 24 bit variables.
To save two bytes of RAM when using only 24 bit values, declare the 24 bit pseudo-registers explicitly:
int24 __int24ac, __24arg;
To ensure the pseudo-registers appear in zero-page memory, declare all of them explicitly, as early as possible in your source program:
int32 __int32ac; int24 __32arg; int24 __int24ac @ &__int32ac + 1; int24 __24arg @ &__32arg + 1;
There are two special data types which are used for declaring variables to access C6805 registers. Using a variable declaration has the same effect as using the equivalent #pragma directive.
An important difference between using the data type declaration and the #pragma statement is that names declared with #pragma directives cannot be used in function declarations while those declared as type registera or registerx can.
| Declaration | Register | #pragma directive equivalent |
|---|---|---|
| registera name | Accumulator | #pragma regac name |
| registerx name | X register | #pragma regix name |
The following example accesses registers using the registera and registerx data types.
0000 registera ac;
0000 registerx rx;
0050 0051 char var, mem;
0004 #define n 4;
void main(void){ 0200 A6 04 LDA #$04 ac=n;
0202 AB 04 ADD #$04 ac+=n;
0204 4A DECA ac--;
0205 4F CLRA ac=0;
0206 A1 04 CMP #$04 if (ac==n){NOP(); NOP();} 0208 26 02 BNE $020C 020A 9D NOP 020B 9D NOP 020C A6 04 LDA #$04 mem=n;
020E B7 51 STA $51 0210 F7 STA ,X *(rx)=ac;
0211 F6 LDA ,X ac=*(rx++);
0212 5C INCX do{ 0213 9D NOP NOP();
0214 5A DECX }while (--rx);
0215 26 FC BNE $0213 0217 81 RTS } For more information, see section 8.3.3 of the printed manual.
C6805 now supports the use of sizeof() with arrays and structures. The compiler evaluates the sizeof( function at compile time to determine the number of bytes allocated to a variable or data type. The parentheses around name)name are optional.
void main(void){ 0050 int size;
0051 000A char ra[10];
enum months {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
struct date{ int day;
enum months month;
int year;
};
005B 0003 struct date today;
0200 A6 01 LDA #$01 size=sizeof(ra[]);
0202 B7 50 STA $50 0204 A6 03 LDA #$03 size=sizeof(today);
0206 B7 50 STA $50 0208 4A DECA size=sizeof(long);
0209 B7 50 STA $50 020B 81 RTS } For more information, see section 8.6.2 of the printed manual.
An enumerated type lets the programmer describe objects in familiar terms. In C6805 variables declared as type enum are also single byte integers. C6805 supports the initialization of enum members, enum as a function parameter, and arrays in enum declarations.
0050 void test_func (enum h){ 0200 B7 50 STA $50 0051 int i;
0202 B7 51 STA $51 i = h;
0204 81 RTS } void main(void){ char test_ch = 10;
0052 0205 A6 0A LDA #$0A 0207 B7 52 STA $52 0209 0053 0007 char test_array[7];
enum first_months {Jan=1, Feb, Mar, Apr, May, Jun} first=Jan;
005A 0209 A6 01 LDA #$01 020B B7 5A STA $5A 020D 005B 000A enum last_months {Jul=7, Aug, Sep, Oct, Nov, Dec}mo[10], last=Dec;
0065 020D A6 0C LDA #$0C 020F B7 65 STA $65 0211 44 LSRA test_array[test_ch] = Jun;
0212 BE 52 LDX $52 0214 E7 53 STA $53,X 0216 A6 02 LDA #$02 test_func(Feb);
0218 AD E6 BSR $0200 021A A6 0A LDA #$0A mo[test_ch] = Oct;
021C BE 52 LDX $52 021E E7 5B STA $5B,X 0220 81 RTS } For more information, see section 8.7.2 of the printed manual.
-
When variables are declared and initialized simultaneously, the compiler generates code to load the variables with the values. For static local variables this is done once at the beginning of the program. Further calls to the function do not reinitialize the variables, thus preserving their values.
-
When used with the linker static limits the scope of global variables to the module in which the variable is declared.
0006 #define DUMMY_VALUE -1 void ReadPortOnce(){ 0030 static long portvalue=DUMMY_VALUE;
0180 B6 31 LDA $31 if (portvalue==(DUMMY_VALUE)) 0182 A1 FF CMP # 0184 26 0D BNE $0193 0186 B6 30 LDA $30 0188 A1 FF CMP # 018A 26 07 BNE $0193 018C { 018C B6 00 LDA $00 portvalue=(unsigned char) porta;
018E 3F 30 CLR $30 0190 B7 31 STA $31 } 0192 81 RTS else{//executed 2nd, etc. time called } 0193 81 RTS } void main(void){ 0194 AD EA BSR $0180 ReadPortOnce();
0196 0196 20 E8 BRA $0180 ReadPortOnce();
0198 } 3FFE 01 98 0198 A6 C0 LDA # 019A C7 3F DF STA $3FDF 019D AE 30 LDX #$30 019F 7F CLR ,X 01A0 5C INCX 01A1 A3 CB CPX # 01A3 26 FA BNE $019F 01A5 A6 FF LDA # 01A7 B7 30 STA $30 01A9 A6 FF LDA # 01AB B7 31 STA $31 01AD CC 01 94 JMP $0194 For more information, see section 8.3.4.7 of the printed manual.
__FILE__ returns the name of the file currently open instead of that of the main .c source file. __DATE__ now returns the date with a four digit year instead of a two digit year.
For more information, see section 10.1.2.2 of the printed manual.
For more information on these directives, see section 10.2 of the printed manual.
#pragma CHECKSUM;
This directive informs the compiler that you wish to checksum the ROM. This directive reserves a single ROM location as a location for the checksum routine. The symbol table reference is __CHECKSUMPAD. This location contains the 2s complement checksum value for the rest of ROM memory. __CHECKSUM() is a library function that returns the checksum value for all of memory. A zero return means that the checksum has no error while a non-zero value means that there is a checksum error. __CHECKSUM() can access all memory locations generated in ROM by the compiler including interrupt vectors. Code need not be contiguous.
#pragma checksum;
char a,b,c;
void main(void){ a=b/c;
#ifdef __CHECKSUM if (__CHECKSUM() !=0) NOP();
#endif NOP();
} #pragma memory ROMPROG[4096] @0x1100;
void MoreCode(void){ NOP();
NOP();
} #pragma memory LOCAL
Described above.
#pragma option NOINIT;
This option turns off the default initialization. Using this directive has two effects:
-
The reset vector is not set to point to the start of the program. This becomes the responsibility of the programmer.
-
Global variables are not initialized before
main(). The compiler usually generates an error if you try to create a function called__RESETbecause this conflicts with the automatic setting of the reset vector. When NOINIT is used, the compiler allows you to create a__RESETfunction. However, you are responsible for jumping to the start of the program at the end of the__RESETfunction.
#pragma option CALLMAP;
This option displays a call tree for the functions in your program in the list file.
C6805 now supports the ## operator for macro concatenation.
For more information, see the C6805 errata.
C6805 compilers are available for the HP 700 series under HP-UX, the SUN SPARC under either Solaris or SUN-OS and the NEC-PC.
You can set the value stored in unused ROM locations with the #pragma option fillrom statement:
#pragma option fillrom value;where value is an 8-bit integer expression.
The default integer size of Code Development Systems is 8 bits. If the symbol __INT16 is defined, it indicates that the default integer size is 16 bits.
The __INT16 preprocessor symbol is defined by the compiler when either the +i is set on the command line, or the #pragma option +h directive appears in a source file.

eTPU_C:
C6808: