;----------------------------------------------------------------------- ; ; cstartup_21xx.s37 ; ; ; This version of cstartup is tailored to work with H8S/21xx chip. ; It might be necessary to tailor this file to suit your hardware layout. ; For all other H8 chip families we recomend usage of cstartup.s37. ; ; Define the symbol IGNORE_SEG_INIT to remove segment initialization ; code. This can be done if you do not rely on having global/static ; variables set to 0 or some explicit value at startup. ; ; ; Revision of this file: $Revision: 1.2 $ ; ; Copyright: 1996-1999 IAR Systems. All rights reserved. ; ; Revised: 27/Apr/99 ITHA Added support for huge (-mh) and for H8S/23xx ; Revised: 29/Mar/99 ITHA Released with C compiler ; Revised: 19/Feb/99 HMSE Correct SP for H8S/21xx ; ;----------------------------------------------------------------------- caseon ; H8 assembler? #if (((__TID__ >> 8) BINAND 0x7F) != 0x25) ; Trying to use wrong assembler. #error Must be assembled with ah8 #else ;---------------------------------------------------------------; ; The following defines are used: ; ; Mappings to (compiler) memory models: ; H8_SMALL - The chip will be used in 64k mode (-ms) ; H8_LARGE - The chip will be used in 'advance' mode. 32 Mb or ; 4 Gb depending on chip type (-ml or -mh) ; ; Mappings to (compiler) chip option: ; H8S_MAX, H8S_64k, H8H_MAX, H8H_64k ; These are used to setup the stack pointer if no (user made) ; low_level_init has been defined. ; ;---------------------------------------------------------------; ; H8S chip - large memory model #if (((__TID__ BINAND 0xFF) = 0x11) OR ((__TID__ BINAND 0xFF) = 0x21) OR ((__TID__ BINAND 0xFF) = 0x31)) #define H8_LARGE #define H8S_MAX ; H8S chip - huge memory model #elif (((__TID__ BINAND 0xFF) = 0x12) OR ((__TID__ BINAND 0xFF) = 0x22) OR ((__TID__ BINAND 0xFF) = 0x32)) #define H8_LARGE #define H8S_MAX ; H8S chip small memory model #elif (((__TID__ BINAND 0xFF) = 0x10) OR ((__TID__ BINAND 0xFF) = 0x20) OR ((__TID__ BINAND 0xFF) = 0x30)) #define H8_SMALL #define H8S_64k ; H8/300H large or huge memory model #elif (((__TID__ BINAND 0xFF) = 0x01) OR ((__TID__ BINAND 0xFF) = 0x02)) #define H8_LARGE #define H8H_MAX ; H8/300H small memory model #elif ((__TID__ BINAND 0xFF) = 0x00) #define H8_SMALL #define H8H_64k #else #error "Unknown memory model or chip option (-v)" #endif #endif ; H8 assembler ;#define IGNORE_LOW_INIT ;Remove this if not adding ; low_level_init function program CSTARTUP ;---------------------------------------------------------------; ; Define XR1 and XR2 to be the largest register name. ; ; They are used for copy and move support functions to prevent ; ; compilation errors. ;---------------------------------------------------------------; #define XR0 er0 #define XR1 er1 #define XR2 er2 ;---------------------------------------------------------------; ; C interrupt routines with defined [vectors] will reserve ; ; space in this area. So will handlers written in assembler ; ; if they follow the recommended format. ; ;---------------------------------------------------------------; COMMON INTVEC #ifdef H8_LARGE DC.L startup DC.L 0,0,0 #endif #ifdef H8_SMALL DC.W startup DC.W 0,0,0 #endif rseg CSTACK ds.b 0 ; can be changed if needed ;--------------------------------------------------------------; ; RCODE - Perform C initialization. ; ;--------------------------------------------------------------; rseg RCODE extern main,exit startup: ;--------------------------------------------------------------; ; Make sure that the data bus width and characteristics are ; ; known when the 'low_level_init' functions is called. ; ; ; ; NOTE ; ; You might have to change the stack pointer (R7/ER7) to an ; ; address where your hardware has RAM. ; ;--------------------------------------------------------------; #ifndef IGNORE_LOW_INIT #ifdef H8S_MAX ; For H8S/21xx devices only. ; The value 00FFFF40 gives an initial stack of H'40 bytes mov.l # 0x00FFFF40,er7 ; If using H8S/22xx, H8S/23xx or H8S/26xx use this line ; mov.l # 0x00FFFC00,er7 #endif #ifdef H8S_64k ; For H8S/21xx devices only. ; The value 00FFFF40 gives an initial stack of H'40 bytes mov.w # 0xFF40,r7 ; If using H8S/22xx, H8S/23xx or H8S/26xx use this line ; mov.w # 0xFC00,r7 #endif #ifdef H8H_MAX mov.l # 0x00FFFF00,er7 #endif #ifdef H8H_64k mov.w # 0xFF00,r7 #endif ;--------------------------------------------------------------; ; If hardware must be initialized from C or if watch dog timer ; ; must be handled or if the segment init should not be ; ; performed it can now be done in low_level_init. ; ;--------------------------------------------------------------; extern low_level_init jsr @low_level_init #endif /* IGNORE_LOW_INIT */ ;--------------------------------------------------------------; ; Set up the official C-stack now when the width etc. is ; ; decided. ; ;--------------------------------------------------------------; #ifdef H8_LARGE mov.l #SFE CSTACK,er7 #else ; H8_SMALL mov.w #SFE CSTACK,r7 #endif #ifndef IGNORE_LOW_INIT mov.b r6l,r6l beq no_seg_init #endif /* IGNORE_LOW_INIT */ ;--------------------------------------------------------------; ; If it is not a requirement that static/global data is set ; ; to zero or to some explicit value at startup, the symbol ; ; IGNORE_SEG_INIT should be defined. ; ;--------------------------------------------------------------; #ifndef IGNORE_SEG_INIT jsr @seg_init #endif /* IGNORE_SEG_INIT */ no_seg_init: ;--------------------------------------------------------------; ; Call C main() with no parameters. ; ;--------------------------------------------------------------; jsr @main ;---------------------------------------------------------------; ; Now when we are ready with our C program (usually H8/300H ; ; programs are continouous) we must perform a system-dependent ; ; action. In this case we just stop. ; ;---------------------------------------------------------------; ; DO NOT CHANGE THE NEXT LINE OF CSTARTUP IF YOU WANT TO RUN ; ; YOUR SOFTWARE WITH THE C-SPY HLL DEBUGGER. ; ;---------------------------------------------------------------; jmp @exit ; Exit ;---------------------------------------------------------------; ; Forward declarations of segments used in initialization ; ;---------------------------------------------------------------; rseg UDATA0 rseg UDATA1 rseg UDATA2 rseg UDATA3 rseg IDATA0 rseg IDATA1 rseg IDATA2 rseg IDATA3 rseg CDATA0 rseg CDATA1 rseg CDATA2 rseg CDATA3 rseg CSTR rseg CONST rseg ECSTR rseg TEMP rseg CCSTR rseg CODE ;-----------------------------------------------------------------------; ; Segment initialization code. Copy initialized PROMmed code to shadow ; ; RAM and clear uninitialized variables. ; ;-----------------------------------------------------------------------; #ifndef IGNORE_SEG_INIT rseg RCODE seg_init: ;---------------------------------------------------------------; ; Zero out UDATA0 ; ;---------------------------------------------------------------; mov.w # SFB UDATA0,r0 #ifdef H8_LARGE mov.l #SFE UDATA0,er1 #else mov.w #SFE UDATA0,r1 #endif jsr @clear64 ;---------------------------------------------------------------; ; Zero out UDATA1 ; ;---------------------------------------------------------------; mov.w # SFB UDATA1,r0 #ifdef H8_LARGE mov.l #SFE UDATA1,er1 #else mov.w #SFE UDATA1,r1 #endif jsr @clear64 #ifdef H8_LARGE ;---------------------------------------------------------------; ; Zero out UDATA2 ; ;---------------------------------------------------------------; mov.l # SFB UDATA2,er0 mov.l #SFE UDATA2,er1 jsr @clear ;---------------------------------------------------------------; ; Zero out UDATA3 ; ;---------------------------------------------------------------; mov.l # SFB UDATA3,er0 mov.l #SFE UDATA3,er1 jsr @clear #endif /* H8_LARGE */ ;---------------------------------------------------------------; ; Copy CDATA0 into IDATA0 ; ;---------------------------------------------------------------; mov.w #SFE CDATA0,r1 #ifdef H8_LARGE mov.l # SFB CDATA0,er0 mov.l # SFB IDATA0,er2 #else mov.w # SFB CDATA0,r0 mov.w # SFB IDATA0,r2 #endif jsr @copy64 ;---------------------------------------------------------------; ; Copy CDATA1 into IDATA1 ; ;---------------------------------------------------------------; mov.w #SFE CDATA1,r1 #ifdef H8_LARGE mov.l # SFB CDATA1,er0 mov.l # SFB IDATA1,er2 #else mov.w # SFB CDATA1,r0 mov.w # SFB IDATA1,r2 #endif jsr @copy64 #ifdef H8_LARGE ;---------------------------------------------------------------; ; Copy CDATA2 into IDATA2 ; ;---------------------------------------------------------------; mov.l # SFB CDATA2,er0 mov.l #SFE CDATA2,er1 mov.l # SFB IDATA2,er2 jsr @copy ;---------------------------------------------------------------; ; Copy CDATA3 into IDATA3 ; ;---------------------------------------------------------------; mov.l # SFB CDATA3,er0 mov.l #SFE CDATA3,er1 mov.l # SFB IDATA3,er2 jsr @copy #endif /* H8_LARGE */ ;---------------------------------------------------------------; ; Copy CCSTR into ECSTR ; ;---------------------------------------------------------------; #ifdef H8_LARGE mov.l # SFB CCSTR,er0 mov.l #SFE CCSTR,er1 mov.l # SFB ECSTR,er2 jsr @copy #else mov.w # SFB CCSTR,r0 mov.w #SFE CCSTR,r1 mov.w # SFB ECSTR,r2 jsr @copy64 #endif rts ; done with segment initialization ;---------------------------------------------------------------; ; Copy a chunk of memory inside 64k ; ;---------------------------------------------------------------; copy64: cmp.w r0,r1 beq cl64_done mov.b @XR0+,r3l mov.b r3l,@XR2 #ifdef H8_SMALL inc.l #1,er2 #else ; adds #1,r2 add.w #1,r2 #endif /* H8_SMALL */ bra copy64 #ifdef H8_LARGE ;---------------------------------------------------------------; ; Copy a chunk of memory using full 32 bits pointers. ; ;---------------------------------------------------------------; copy: cmp.l er0,er1 beq cl64_done mov.b @er0+,r3l mov.b r3l,@er2 inc.l #1,er2 bra copy #endif /* H8_LARGE */ ;---------------------------------------------------------------; ; Clear a chunk of memory inside 64k ; ;---------------------------------------------------------------; clear64: mov.b #0,r2l cl64_loop: cmp.w r0,r1 beq cl64_done mov.b r2l,@-XR1 bra cl64_loop cl64_done: rts #ifdef H8_LARGE ;---------------------------------------------------------------; ; Clear a chunk of memory using 32 bits pointers. ; ;---------------------------------------------------------------; clear: mov.b #0,r2l cl_loop: cmp.l er0,er1 beq cl64_done mov.b r2l,@-er1 bra cl_loop #endif /* H8_LARGE */ #endif /* IGNORE_SEG_INIT */ ENDMOD startup ;---------------------------------------------------------------; ; C exit code ; ;---------------------------------------------------------------; module exit public ?C_EXIT,exit rseg CODE ?C_EXIT: exit: ;---------------------------------------------------------------; ; The next line can be replaced with user defined code. ; ; Remember to set the m-flag to the value you want and ; ; tell the assembler about it as usual. ; ;---------------------------------------------------------------; bra $ END