; CC1B Ver 0.5A beta, Copyright (c) B Knudsen Data ; C compiler for the Ubicom SX family ; ************ 24. Jun 2002 11:39 ************* device SX28 INDF EQU $00 FSR EQU $04 Carry EQU 0 Zero_ EQU 2 RA EQU $05 RB EQU $06 RC EQU $07 a0 EQU $16 b0 EQU $17 a1 EQU $5C b1 EQU $5D a EQU $08 bx EQU $09 bt1 EQU 0 bt EQU 1 a_2 EQU $10 bx_2 EQU $11 c EQU $12 d EQU $13 a16 EQU $14 b16 EQU $54 a24 EQU $56 b24 EQU $59 i EQU $10 rs EQU $12 s EQU $50 aa16 EQU $30 bb EQU $32 i_2 EQU $53 acc24 EQU $34 C1cnt EQU $37 C2tmp EQU $38 TtmpA30 EQU $5E ; FILE sx\demo.c ;// DEMO.C : contains recommended program structure ; ;#pragma chip SX28 // select device ; ;// OTHER SAMPLE CODE: ;// demo-ins.c : generating single instructions using C code ;// demo-mat.c : integer math operations ;// demo-fpm.c : floating point math ;// demo-fxm.c : fixed point math ;// demo-rom.c : const data and DW ;// demo-ptr.c : indexed tables and pointers ;// demo-var.c : defining RAM variables ; ;/* ; It is RECOMMENDED to move definitions to header files (.h) and ; use #include on these. Also, because no linker is available, it ; is recommended to group related functions on separate files (.c) ; and use #include one these. ;*/ ; ; ;// ************************************************ ;// ************************************************ ;// MACRO DEFINITIONS AND CONSTANTS ; ;#define MY_CONSTANT1 10 ;#define MY_CONSTANT2 (MY_CONSTANT1 * 100L - 50) // nested definition ; ; ;// ************************************************ ;// ************************************************ ;// IO PORT DEFINITIONS ; ;bit pinA @ RA.1; // port A, bit 1 ;bit pinB @ RA.2; ; ; ;// ************************************************ ;// ************************************************ ;// GLOBAL VARIABLE DEFINITIONS ; ;#pragma rambank 0 ;char a0, b0; // located in ram bank 0 ; ;#pragma rambank 2 ;char a1, b1; // located in ram bank 2 ; ;#pragma rambank - ;char a, bx; // located in shared ram locations ; ;bank4 uns16 u16, table1[3]; // located in ram bank 3 ; ;bank2 bit bt1, bt; // located in ram bank 2 ; ; ;#define DefaultRamBank 1 ;#pragma rambank DefaultRamBank // change to default rambank ; ; ; ;// ************************************************ ;// ************************************************ ;// PROTOTYPES AND CODEPAGES ; ;/* Prototypes are needed when a function is called before it ;is defined. It can also be used for fine tuning the code ;layout (i.e. which codepage to use for a function). */ ; ;char function1( void); ;page2 char function2( void); ;#pragma location 3 ;void function3( void); ;void function4( char aa); ;void function5( int16); ;#pragma location - ; ; ;// ************************************************ ;// ************************************************ ;// INTERRUPT SUPPORT ; ; ;#pragma origin 0 // interrupt must be located first on codepage 0 ORG $0000 ; ;interrupt iServer(void) ;{ iServer ; /* NOTE: W, STATUS and FSR are automatically saved to ; and restored from shadow registers */ ; ; // handle the interrupt ; nop(); NOP ;} RETI ; ; ; ;// ************************************************ ;// ************************************************ ;// INCLUDED C FILES AND MATH ROUTINES ; ;/* C files that contains function located in codepage 0 need ;to be included after the interrupt routine. However, if the ;functions are not located in codepage 0, then they can be ;included before the interrupt routine. Using #pragma ;codepage ensures that functions not yet located (by page ;modifier or #pragma location) are put on certain ;codepages */ ; ;/* ;#pragma codepage 1 ; #include "math16.h" // 16 bit integer math routines ; #include "mm1.c" ; #include "mm2.c" ;#pragma codepage 2 ; #include "mm3.c" ;#pragma codepage 1 ; #include "mm4.c" ;#pragma codepage 3 ; #include "mm5.c" ;*/ ; ;#pragma codepage 0 ; ; ; ;// ************************************************ ;// ************************************************ ;// C FUNCTIONS ; ; ;void subr( void) ;{ subr ; bank0 char a, bx, c, d; ; bank0 uns16 a16; ; bank2 uns16 b16 = a16; MOV W,a16 BANK 64 MOV b16,W BANK 0 MOV W,a16+1 BANK 64 MOV b16+1,W ; bank2 uns24 a24, b24; ; ; b24.high16 = a24.low16; MOV W,a24 MOV b24+1,W MOV W,a24+1 MOV b24+2,W ; ; a = bx; BANK 0 MOV W,bx_2 MOV a_2,W ; c = 10; MOV W,#10 MOV c,W ; a = 10 | bx | d; OR W,bx_2 OR W,d MOV a_2,W ; ; do { ; nop(); m001 NOP ; a --; DEC a_2 ; } while ( --d > 0); DECSZ d JMP m001 ; ; #asm ; DW 0xFFF ; any data or instruction DW $FFF ; DW 0x000 DW $0 ; #endasm ;} RET ; ; ;uns24 accumulate( void) ;{ accumulate ; bank0 uns16 i; ; bank0 uns24 rs = 0; CLR rs CLR rs+1 CLR rs+2 ; ; // add all numbers from 1 to 1999 ; for (i = 1; i < 2000; i++) MOV W,#1 MOV i,W CLR i+1 m002 MOV W,#7 MOV W,i+1-W SB 3.Carry JMP m003 SB 3.Zero_ JMP m005 MOV W,#208 MOV W,i-W SNB 3.Carry JMP m005 ; rs += i; m003 MOV W,i+1 ADD rs+1,W SNB 3.Carry INC rs+2 MOV W,i ADD rs,W SB 3.Carry JMP m004 INC rs+1 SNB 3.Zero_ INC rs+2 m004 INC i SNB 3.Zero_ INC i+1 JMP m002 ; return rs; m005 MOV W,rs RET ;} ; ; ;void sub1( void) ;{ sub1 ; a0 = MODE; MOV W,M MOV a0,W ; MODE = 3; MOV M,#3 ; OPTION = a; MOV W,a MOV !option,W ; ; DDRA = 0x20; MOV M,#15 MOV W,#32 MOV !RA,W ; DDRB = 0x20; MOV !RB,W ; DDRC = 0x20; MOV !RC,W ; ; PLP_A = 0x20; MOV M,#14 MOV !RA,W ; PLP_B = 0x20; MOV !RB,W ; PLP_C = 0x20; MOV !RC,W ; ; LVL_A = 0x20; MOV M,#13 MOV !RA,W ; LVL_B = 0x20; MOV !RB,W ; LVL_C = 0x20; MOV !RC,W ; ; ST_B = 0x20; MOV M,#12 MOV !RB,W ; ST_C = 0x20; MOV !RC,W ; ; WKEN_B = 0x20; MOV M,#11 MOV !RB,W ; WKED_B = 0x20; MOV M,#10 MOV !RB,W ; WKPND_B = 0x20; MOV M,#9 MOV !RB,W ; ; CMP_B = a; MOV M,#8 MOV W,a MOV !RB,W ;} RET ; ; ;void main(void) ;{ main ; clearRAM(); // built in function MOV W,#8 MOV FSR,W m006 CLR INDF INC FSR SNB FSR.4 JMP m006 SNB FSR.3 JMP m006 MOV W,#16 ADD FSR,W XOR W,FSR SB 3.Zero_ JMP m006 ; ; subr(); CLR FSR CALL subr ; sub1(); CLR FSR CALL sub1 ; ; bank2 uns24 s = accumulate(); CALL accumulate BANK 64 MOV s,W BANK 0 MOV W,rs+1 BANK 64 MOV s+1,W BANK 0 MOV W,rs+2 BANK 64 MOV s+2,W ; ; bt1 = 0; // clear bit CLRB 94.bt1 ; a.7 = 1; // set bit SETB a.7 ; bt = !bt; // bit toggle MOV W,#2 XOR TtmpA30,W ; ; if (a > bx) MOV W,a MOV W,bx-W SNB 3.Carry JMP m007 ; a &= 0xF0; // mask bits MOV W,#240 AND a,W ; ; // uns16 is 16 bit (unsigned long) ; bank1 uns16 aa16 = 1000; // local variable m007 MOV W,#232 BANK 32 MOV aa16,W MOV W,#3 MOV aa16+1,W ; bank1 uns16 bb = aa16+10000; MOV W,#39 ADD W,aa16+1 MOV bb+1,W MOV W,#16 ADD W,aa16 MOV bb,W SNB 3.Carry INC bb+1 ; aa16 |= 0x10F; // set bits SETB aa16+1.0 MOV W,#15 OR aa16,W ; bb &= 0x7F; // clear bits CLR bb+1 CLRB bb.7 ; ; bank2 char i = 10; // 8 bit unsigned MOV W,#10 BANK 64 MOV i_2,W ; ; aa16 -= i; BANK 32 SUB aa16,W SB 3.Carry DEC aa16+1 ; ; bank1 uns24 acc24 = 0; // 24 bit unsigned CLR acc24 CLR acc24+1 CLR acc24+2 ; for (aa16 = 0; aa16 < 3000; aa16++) { CLR aa16 CLR aa16+1 m008 MOV W,#11 MOV W,aa16+1-W SB 3.Carry JMP m009 SB 3.Zero_ JMP m011 MOV W,#184 MOV W,aa16-W SNB 3.Carry JMP m011 ; acc24 += aa16; m009 MOV W,aa16+1 ADD acc24+1,W SNB 3.Carry INC acc24+2 MOV W,aa16 ADD acc24,W SB 3.Carry JMP m010 INC acc24+1 SNB 3.Zero_ INC acc24+2 ; nop(); m010 NOP ; } INC aa16 SNB 3.Zero_ INC aa16+1 JMP m008 ; ; if (acc24 == 0) m011 MOV W,acc24 OR W,acc24+1 OR W,acc24+2 SB 3.Zero_ JMP m012 ; acc24 = 0xFFFF; MOV W,#255 MOV acc24,W MOV acc24+1,W CLR acc24+2 ; ; aa16 = i * 200; m012 BANK 64 MOV W,i_2 BANK 32 MOV C2tmp,W CLR aa16 MOV W,#8 MOV C1cnt,W m013 CLRB 3.Carry RL aa16 RL aa16+1 RL C2tmp SB 3.Carry JMP m014 MOV W,#200 ADD aa16,W SNB 3.Carry INC aa16+1 m014 DECSZ C1cnt JMP m013 ; ; acc24 ++; // increment INCSZ acc24 JMP m015 INC acc24+1 SNB 3.Zero_ INC acc24+2 ; aa16 --; // decrement m015 DEC aa16 MOV W,++aa16 SNB 3.Zero_ DEC aa16+1 ; ; if (aa16 == 0 || !bt) MOV W,aa16 OR W,aa16+1 BANK 64 SNB 3.Zero_ JMP m016 BANK 64 SNB 94.bt JMP m017 ; a1 -= 33; m016 MOV W,#33 SUB a1,W ; if (!a.7) // test single bit m017 BANK 32 SNB a.7 JMP m018 ; b0 += a1 + b1; MOV W,b1 ADD W,a1 BANK 0 ADD b0,W ; ; nop(); // delay 1 instruction cycle m018 NOP ; ; W = 10; MOV W,#10 ;} SLEEP ORG $07FF GOTO main END