3.12.1 MCS51/DS390 Startup Code

Next: 3.12.2 HC08 Startup Code Up: 3.12 Startup Code Previous: 3.12 Startup Code Contents Index

## 3.12.1 MCS51/DS390 Startup Code

The compiler triggers the linker to link certain initialization modules from the runtime library called crt<something>. Only the necessary ones are linked, for instance crtxstack.asm (GSINIT1, GSINIT5) is not linked unless the --xstack option is used. These modules are highly entangled by the use of special segments/areas, but a common layout is shown below:

> `(main.asm)`

> `.area HOME (CODE)`
> `__interrupt_vect:`
> `ljmp __sdcc_gsinit_startup`

> `(crtstart.asm)`

> `.area GSINIT0 (CODE)`
> `__sdcc_gsinit_startup::`
> `mov sp,#__start__stack - 1`

> `(crtxstack.asm)`

> `.area GSINIT1 (CODE)`
> `__sdcc_init_xstack::`
> `; Need to initialize in GSINIT1 in case the user's __sdcc_external_startup uses the xstack.`
> `mov __XPAGE,#(__start__xstack >> 8)`
> `mov _spx,#__start__xstack`

> `(crtstart.asm)`

> `.area GSINIT2 (CODE)`
> `lcall __sdcc_external_startup`
> `mov a,dpl`
> `jz __sdcc_init_data`
> `ljmp __sdcc_program_startup`
> `__sdcc_init_data:`

> `(crtxinit.asm)`

> `.area GSINIT3 (CODE)`
> `__mcs51_genXINIT::`
> `mov r1,#l_XINIT`
> `mov a,r1`
> `orl a,#(l_XINIT >> 8)`
> `jz 00003$`
> `mov r2,#((l_XINIT+255) >> 8)`
> `mov dptr,#s_XINIT`
> `mov r0,#s_XISEG`
> `mov __XPAGE,#(s_XISEG >> 8)`
> `00001$: clr a`
> `movc a,@a+dptr`
> `movx @r0,a`
> `inc dptr`
> `inc r0`
> `cjne r0,#0,00002$`
> `inc __XPAGE`
> `00002$: djnz r1,00001$`
> `djnz r2,00001$`
> `mov __XPAGE,#0xFF`
> `00003$:`

> `(crtclear.asm)`

> `.area GSINIT4 (CODE)`
> `__mcs51_genRAMCLEAR::`
> `clr a`
> `mov r0,#(l_IRAM-1)`
> `00004$: mov @r0,a`
> `djnz r0,00004$`
> `; _mcs51_genRAMCLEAR() end`

> `(crtxclear.asm)`

> `.area GSINIT4 (CODE)`
> `__mcs51_genXRAMCLEAR::`
> `mov r0,#l_PSEG`
> `mov a,r0`
> `orl a,#(l_PSEG >> 8)`
> `jz 00006$`
> `mov r1,#s_PSEG`
> `mov __XPAGE,#(s_PSEG >> 8)`
> `clr a`
> `00005$: movx @r1,a`
> `inc r1`
> `djnz r0,00005$`
> `00006$:`
> `mov r0,#l_XSEG`
> `mov a,r0`
> `orl a,#(l_XSEG >> 8)`
> `jz 00008$`
> `mov r1,#((l_XSEG + 255) >> 8)`
> `mov dptr,#s_XSEG`
> `clr a`
> `00007$: movx @dptr,a`
> `inc dptr`
> `djnz r0,00007$`
> `djnz r1,00007$`
> `00008$:`

> `(crtxstack.asm)`

> `.area GSINIT5 (CODE)`
> `; Need to initialize in GSINIT5 because __mcs51_genXINIT modifies __XPAGE`
> `; and __mcs51_genRAMCLEAR modifies _spx.`
> `mov __XPAGE,#(__start__xstack >> 8)`
> `mov _spx,#__start__xstack`

> `(application modules)`

> `.area GSINIT (CODE)`

> `(main.asm)`

> `.area GSFINAL (CODE)`
> `ljmp __sdcc_program_startup`
> `;----------------------------`
> `; Home`
> `;----------------------------`
> `.area HOME (CODE)`
> `.area CSEG (CODE)`
> `__sdcc_program_startup:`
> `lcall _main`
> `; return from main will lock up`
> `sjmp .`

One of these modules (crtstart.asm) contains a call to the C routine _sdcc_external_startup() at the start of the CODE area. This routine is also in the runtime library and returns 0 by default. If this routine returns a non-zero value, the static & global variable initialization will be skipped and the function main will be invoked. Otherwise static & global variables will be initialized before the function main is invoked. You could add an _sdcc_external_startup() routine to your program to override the default if you need to setup hardware or perform some other critical operation prior to static & global variable initialization. On some mcs51 variants xdata memory has to be explicitly enabled before it can be accessed or if the watchdog needs to be disabled, this is the place to do it. The startup code clears all internal data memory, 256 bytes by default, but from 0 to n-1 if --iram-sizen is used. (recommended for Chipcon CC1010).

See also the compiler options --no-xinit-opt, --main-return and section 4.1 about MCS51-variants.

While these initialization modules are meant as generic startup code there might be the need for customization. Let's assume the return value of _sdcc_external_startup() in crtstart.asm should not be checked (or _sdcc_external_startup() should not be called at all). The recommended way would be to copy crtstart.asm (f.e. from http://sdcc.svn.sourceforge.net/viewvc/*checkout*/sdcc/trunk/sdcc/device/lib/mcs51/crtstart.asm) into the source directory, adapt it there, then assemble it with asx8051 -plosgff 3.4 crtstart.asm and when linking your project explicitly specify crtstart.rel. As a bonus a listing of the relocated object file crtstart.rst is generated.

Next: 3.12.2 HC08 Startup Code Up: 3.12 Startup Code Previous: 3.12 Startup Code Contents Index