rt-thread/bsp/m16c62p/drivers/start_gcc.S

165 lines
6.2 KiB
ArmAsm

/****************************************************************
KPIT Cummins Infosystems Ltd, Pune, India.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************/
/* Start-up code for M16C targets only */
.text
.global _start
.type _start, @function
_start:
ldc #_istack, isp /* set interrupt stack pointer */
#ifndef EXT_RAM
mov.b #0x02,0x0a /* write enable in protect register */
mov.b #0x00,0x04 /* set processer mode :single chip mode */
/* 0x04 is the address of processor mode register 0 */
mov.b #0x00,0x0a /* write disable in protect register */
#endif
#if EXT_RAM
mov.w #0x000a,a0 /* Write enable in protect register */
mov.b #0xff,[a0]
mov.w #0x04,a0 /* Memory expansion mode, WRH/WRL/RD signals */
mov.b #0x05,[a0]
mov.w #0x05,a0 /* Insert wait, no limit in on-chip memory */
mov.b #0x88,[a0]
mov.w #0x08,a0 /* Enable all the CS signals with wait */
mov.b #0x0F,[a0]
mov.w #0x0a,a0 /* write disable in protect register */
mov.b #0x00,[a0]
#endif
; ldc #0x0080,flg /* select USER STACK POINTER (BIT7=1,USP) (BIT7=0,ISP) */
; ldc #_ustack,sp /* set user stack pointer */
/* INTERRUPT VECTOR ADDRESS definition */
ldc #0xF, intbh /* load upper 4 bits of variable vector address in intbh */
ldc #0xA000, intbl /* load lower 16 bits of variable vector address in intbl */
fset I /* ADD THIS TO ENABLE INTERRUPTS */
/* call the hardware initialiser */
; jsr.a _hw_initialise
/* load data section from ROM to RAM */
mov.b #%hi8(_mdata),r1h /* move upper 4 bits of the 20 bit address (_mdata) to, r1h */
mov.w #%lo16(_mdata),a0 /* move lower 16 bits of the 20 bit address (_mdata) to,a0 */
mov.w #_data,a1 /* store the start address of data section in, A1 */
mov.w #_edata,r3 /* store the end address of data section in R3 */
sub.w a1,r3 /* R3=R3-A1. Store size of data section in R3 */
mov.w r3,r2 /* Store size of data section in R2 */
smovf.b
/* bss initialisation : zero out bss */
mov.b #0x00,R0L /* load R0L reg with 0x0 (value at which bss section will be initialised) */
mov.w #_bss, a1 /* store the start address of bss in A1 */
mov.w #_ebss, a0 /* store the end address of bss in A0 */
sub.w a1,a0 /* (A0 = A0-A1) */
mov.w a0,r3 /* Store size of bss section in reg R3 */
sstr.b
#if EXT_RAM
/* load fdata section from ROM to External RAM only if EXT_RAM is defined */
pushc sp /*store stack pointer in stack */
popc fb /*copy the stack pointer in frame base register */
push.w #%hi16(_mdata) /* offset of -2 from fb: store higher 16 bits of _mdata */
push.w #%lo16(_mdata) /* offset of -4 from fb: store lower 16 bits of _mdata */
mov.w #_edata,r0 /* end address of data section */
mov.w #_data,r1 /* start address of data section */
sub.w r1,r0 /* size of data section in r0 */
add.w r0,-4[fb] /* store the lower 16 bits of source address on stack */
adc.w #0,-2[fb] /* store the higher 4 bits of source address on stack */
push.w #%hi16(_fdata) /* offset -6 from fp: store the higher 4 bits of destination address on stack */
push.w #%lo16(_fdata) /* offset -8 from fp: store the lower 16 bits of destination address on stack */
push.w #%hi16(_efdata) /* offset -10 from fp: higher 16 bits of _efdata */
push.w #%lo16(_efdata) /* offset -12 from fp: lower 16 bits of _efdata */
label1:
cmp.w -6[fb],-10[fb] /* Compare higher 16 bits of _fdata and _efdata */
jnz label2
cmp.w -8[fb],-12[fb] /* Compare lower 16 bits of _fdata and _efdata */
jeq init_fdata_end
label2:
mov.w -2[fb],a1 /* Copy higher 16 bits of source in A1 */
mov.w -4[fb],a0 /* Copy lower 16 bits of source in A1 */
lde.b [a1a0],r0l /* Copy contents of a1a0 in r0l */
mov.w -6[fb],a1 /* Copy higher 16 bits of destination in A1 */
mov.w -8[fb],a0 /* Copy lower 16 bits of destination in A0 */
ste.b r0l,[a1a0] /* store r0l contents at [a1a0] */
add.w #0x01,-4[fb] /* increment lower 16 bits of source */
adcf.w -2[fb] /* add carry to higher 16 bits of source */
add.w #0x01,-8[fb] /* increment lower 16 bits of destination */
adcf.w -6[fb] /* add carry to higher 16 bits of destination */
jmp.b label1
init_fdata_end:
pop.w r0 /* clean stack */
pop.w r0
pop.w r0
pop.w r0
pop.w r0
pop.w r0
/* Zero out fbss section */
push.w #%hi16(_fbss) /* offset of -2 from fb: higher 16 bits of _fbss */
push.w #%lo16(_fbss) /* offset of -4 from fb: lower 16 bits of _fbss */
push.w #%hi16(_efbss) /* offset of -6 from fb: higer 16 bits of _efbss */
push.w #%lo16(_efbss) /* offset of -8 from fb: lower 16 bits of _efbss */
mov.b #0x00,r0l
label3:
cmp.w -2[fb],-6[fb] /* Compare higher 16 bits of _fdata and _efdata */
jnz label4
cmp.w -4[fb],-8[fb] /* Compare lower 16 bits of _fdata and _efdata */
jeq init_fbss_end
label4:
mov.w -2[fb],a1 /* Copy higher 16 bits of source in A1 */
mov.w -4[fb],a0 /* Copy lower 16 bits of source in A1 */
ste.b r0l,[a1a0] /* store r0l contents at [a1a0] */
add.w #0x01,-4[fb] /* increment lower 16 bits of _fbss */
adcf.w -2[fb] /* add carry to higher 16 bits of _fbss */
jmp.b label3
init_fbss_end:
pop.w r0 /* clean stack */
pop.w r0
pop.w r0
pop.w r0
#endif
/* start user program */
jsr.a _main
.end