Rev 409 | Blame | Compare with Previous | Last modification | View Log | Download
/******************************************************************************FILE : start08.cPURPOSE : 68HC08 standard startup codeLANGUAGE : ANSI-C / INLINE ASSEMBLER----------------------------------------------------------------------------HISTORY22 oct 93 Created.04/17/97 Also C++ constructors called in Init().******************************************************************************//**********************************************************************//* NOTE: *//* This version of the startup code does assumes that main *//* does never return (saving the 2 byte return address of _Startup on *//* the stack). *//**********************************************************************/#define __NO_FLAGS_OFFSET /* we do not need the flags field in the startup data descriptor */#define __NO_MAIN_OFFSET /* we do not need the main field in the startup data descriptor */#include <start08.h>#ifdef __cplusplus#define __EXTERN_C extern "C"#else#define __EXTERN_C#endif/**********************************************************************//* __ONLY_INIT_SP define: *//* This define selects an shorter version of the startup code *//* which only loads the stack pointer and directly afterwards calls *//* main. This version does however NOT initialized global variables *//* (So this version is not ANSI compliant!) *//**********************************************************************/#ifndef __ONLY_INIT_SP#pragma DATA_SEG FAR _STARTUPstruct _tagStartup _startupData; /* read-only:_startupData is allocated in ROM andinitialized by the linker */#pragma MESSAGE DISABLE C20001 /* Warning C20001: Different value of stackpointer depending on control-flow *//* the function _COPY_L releases some bytes from the stack internally */#ifdef __OPTIMIZE_FOR_SIZE__#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAME/*lint -esym(528, loadByte) inhibit warning about not referenced loadByte function */static void near loadByte(void) {asm {PSHHPSHX#ifdef __HCS08__LDHX 5,SPLDA 0,XAIX #1STHX 5,SP#elseLDA 5,SPPSHALDX 7,SPPULHLDA 0,XAIX #1STX 6,SPPSHHPULXSTX 5,SP#endifPULXPULHRTS}}#endif /* __OPTIMIZE_FOR_SIZE__ *//*lint -esym(752,_COPY_L) inhibit message on dunction declared, but not used (it is used in HLI) */__EXTERN_C extern void _COPY_L(void);/* DESC: copy very large structures (>= 256 bytes) in 16 bit address space (stack incl.)IN: TOS count, TOS(2) @dest, H:X @srcOUT:WRITTEN: X,H */#ifdef __ELF_OBJECT_FILE_FORMAT__#define toCopyDownBegOffs 0#else#define toCopyDownBegOffs 2 /* for the hiware format, the toCopyDownBeg field is a long. Because the HC08 is big endian, we have to use an offset of 2 */#endifstatic void Init(void) {/* purpose: 1) zero out RAM-areas where data is allocated2) init run-time data3) copy initialization data from ROM to RAM*//*lint -esym(529,p,i) inhibit warning about symbols not used: it is used in HLI below */int i;int *far p;asm {ZeroOut: ;LDA _startupData.nofZeroOuts:1 ; nofZeroOutsINCASTA i:1 ; i is counter for number of zero outsLDA _startupData.nofZeroOuts:0 ; nofZeroOutsINCASTA i:0LDHX _startupData.pZeroOut ; *pZeroOutBRA Zero_5Zero_3: ;; CLR i:1 is already 0Zero_4: ;; { HX == _pZeroOut }PSHXPSHH; { nof bytes in (int)2,X }; { address in (int)0,X }LDA 0,XPSHALDA 2,XINCASTA p ; p:0 is used for high byte of byte counterLDA 3,XLDX 1,XPULHINCABRA Zero_0Zero_1: ;; CLRA A is already 0, so we do not have to clear itZero_2: ;CLR 0,XAIX #1Zero_0: ;DBNZA Zero_2Zero_6:DBNZ p, Zero_1PULHPULX ; restore *pZeroOutAIX #4 ; advance *pZeroOutZero_5: ;DBNZ i:1, Zero_4DBNZ i:0, Zero_3;CopyDown: ;}/* copy down *//* _startupData.toCopyDownBeg ---> {nof(16) dstAddr(16) {bytes(8)}^nof} Zero(16) */#if defined(__OPTIMIZE_FOR_SIZE__)asm {#ifdef __HCS08__LDHX _startupData.toCopyDownBeg:toCopyDownBegOffsPSHXPSHH#elseLDA _startupData.toCopyDownBeg:(1+toCopyDownBegOffs)PSHALDA _startupData.toCopyDownBeg:(0+toCopyDownBegOffs)PSHA#endifLoop0:JSR loadByte ; load high byte counterTAX ; save for compareINCASTA iJSR loadByte ; load low byte counterINCASTA i:1DECABNE notfinishedCBEQX #0, finishednotfinished:JSR loadByte ; load high byte ptrPSHAPULHJSR loadByte ; load low byte ptrTAX ; HX is now destination pointerBRA Loop1Loop3:Loop2:JSR loadByte ; load data byteSTA 0,XAIX #1Loop1:DBNZ i:1, Loop2DBNZ i:0, Loop3BRA Loop0finished:AIS #2};#else /* defined(__OPTIMIZE_FOR_SIZE__) time optimized asm version. */asm {#ifdef __HCS08__LDHX _startupData.toCopyDownBeg:toCopyDownBegOffs#elseLDX _startupData.toCopyDownBeg:(0+toCopyDownBegOffs)PSHXPULHLDX _startupData.toCopyDownBeg:(1+toCopyDownBegOffs)#endifnext:LDA 0,X ; list is terminated by 2 zero bytesORA 1,XBEQ copydonePSHX ; store current positionPSHHLDA 3,X ; psh dest lowPSHALDA 2,X ; psh dest highPSHALDA 1,X ; psh cnt lowPSHALDA 0,X ; psh cnt highPSHAAIX #4JSR _COPY_L ; copy one blockPULHPULXTXAADD 1,X ; add lowPSHAPSHHPULAADC 0,X ; add highPSHAPULHPULXAIX #4BRA nextcopydone:};#endif /* defined(__OPTIMIZE_FOR_SIZE__) *//* FuncInits: for C++, this are the global constructors */#ifdef __cplusplus#ifdef __ELF_OBJECT_FILE_FORMAT__i = (int)(_startupData.nofInitBodies - 1);while (i >= 0) {(&_startupData.initBodies->initFunc)[i](); /* call C++ constructors */i--;}#else /* __ELF_OBJECT_FILE_FORMAT__ *//* HIWARE object file format */if (_startupData.mInits != NULL) {_PFunc *fktPtr;fktPtr = _startupData.mInits;while(*fktPtr != NULL) {(**fktPtr)(); /* call constructor */fktPtr++;}}#endif /* __ELF_OBJECT_FILE_FORMAT__ */#endif /* __cplusplus *//* implement ROM libraries initialization here (see startup.c) */}#endif /* __ONLY_INIT_SP */__EXTERN_C extern void main(void); /* prototype of main function */#pragma NO_EXIT__EXTERN_C void _Startup(void) {/* set the reset vector to _Startup in the linker parameter file (*.prm):'VECTOR 0 _Startup'purpose: 1) initialize the stack2) initialize run-time, ...initialize the RAM, copy down init dat etc (Init)3) call main;called from: _PRESTART-code generated by the Linker*/INIT_SP_FROM_STARTUP_DESC();#ifndef __ONLY_INIT_SPInit();#endif__asm JMP main; /* with a C style main(); we would push the return address on the stack wasting 2 RAM bytes */}