⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 start.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
; @(#)crt0.s	1.3 96/05/31 14:40:27, AMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Copyright 1988, 1989, 1990 Advanced Micro Devices, Inc.;; This software is the property of Advanced Micro Devices, Inc	(AMD)  which; specifically	grants the user the right to modify, use and distribute this; software provided this notice is not removed or altered.  All other rights; are reserved by AMD.;; AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS; SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL; DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR; USE OF THIS SOFTWARE.;; So that all may benefit from your experience, please report  any  problems; or  suggestions about this software to the 29K Technical Support Center at; 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in	the  UK,  or; 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.;; Advanced Micro Devices, Inc.; 29K Support Products; Mail Stop 573; 5900 E. Ben White Blvd.; Austin, TX 78741; 800-292-9263;;  /* $Id: start.S,v 1.1 2000/09/22 20:33:08 joel Exp $ */;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	.file	"crt0.s"; crt0.s version 3.3-0;; This module gets control from the OS.; It saves away the Am29027 Mode register settings and; then sets up the pointers to the resident spill and fill; trap handlers. It then establishes argv and argc for passing; to main. It then calls _main. If main returns, it calls _exit.;;	void = start( );;	NOTE - not C callable (no lead underscore);#if 0#include <sysmac.h>#endif;;	.extern V_SPILL, V_FILL;	.comm	__29027Mode, 8	; A shadow of the mode register	.comm	__LibInit, 4	.text	.extern _main, _exit, _atexit	.word	0			; Terminating tag word	.global startstart:#if 0	sub	gr1, gr1, 6 * 4	asgeu	V_SPILL, gr1, rab	; better not ever happen	add	lr1, gr1, 6 * 4;; Save the initial value of the Am29027 Mode register;; If your system does not enter crt0 with value for Am29027 Mode ; register in gr96 and gr97, and also the coprocessor is active ; uncomment the next 4 instructions.;;	const	gr96, 0xfc00820;	consth	gr96, 0xfc00820;	const	gr97, 0x1375;	store	1, 3, gr96, gr97;;	const	gr98, __29027Mode;	consth	gr98, __29027Mode;	store	0, 0, gr96, gr98;	add	gr98, gr98, 4;	store	0, 0, gr97, gr98;; Now call the system to setup the spill and fill trap handlers;	const	lr3, spill	consth	lr3, spill	const	lr2, V_SPILL	syscall setvec	const	lr3, fill	consth	lr3, fill	const	lr2, V_FILL	syscall setvec;; atexit(_fini);;        const   lr0, _atexit;        consth  lr0, _atexit;        const   lr2,__fini;        calli   lr0,lr0;        consth  lr2,__fini;; Now call _init;;        const   lr0, __init;        consth  lr0, __init;        calli   lr0,lr0;        nop;; Get the argv base address and calculate argc.;	syscall getargs	add	lr3, v0, 0		; argv	add	lr4, v0, 0	constn	lr2, -1argcloop:				; scan for NULL terminator	load	0, 0, gr97, lr4	add	lr4, lr4, 4	cpeq	gr97, gr97, 0	jmpf	gr97, argcloop	add	lr2, lr2, 1;; Now call LibInit, if there is one. To aid runtime libraries; that need to do some startup initialization, we have created; a bss variable called LibInit. If the library does not need; any run-time initialization, the variable is still 0. If the; library does need run-time initialization, the library will; contain a definition like; void (*_LibInit)(void) = LibInitFunction;; The linker will match up our bss LibInit with this data LibInit; and the variable will not be 0.  This results in the LibInit routine; being called via the calli instruction below.;	const	lr0, __LibInit	consth	lr0, __LibInit	load	0, 0, lr0, lr0	cpeq	gr96, lr0, 0	jmpt	gr96, NoLibInit	nop	calli	lr0, lr0	nopNoLibInit:;; Call RAMInit to initialize the data memory.; ; The following code segment was used to create the two flavors of the ; run-time initialization routines (crt0_1.o, and crt0_2.o) as described; in the Users Manual.  If osboot is used to create a stand-alone; application, or the call to RAMInit is made in the start-up routine, ; then the following is not needed.;;       .ifdef ROM_LOAD;       .extern RAMInit;;       const   lr0, RAMInit;       consth  lr0, RAMInit;       calli   gr96, lr0;       nop;       .else;       nop;       nop;       nop;       nop;       .endif;; Uncomment the following .comm, if you ARE NOT using osboot as released; with the High C 29K product, AND plan to use the romcoff utility to; move code and/or data sections to ROM.;;       .comm   RAMInit, 4; ; Furthermore, if the above is uncommented, then use the following logic; to call the RAMInit function, if needed.  ;;       const   lr0, RAMInit;       consth  lr0, RAMInit;       load    0, 0, gr96, lr0;       cpeq    gr96, gr96, 0           ; nothing there?;       jmpt    gr96, endRAMInit        ; yes, nothing to init;       nop;       calli   gr96, lr0               ; no, then instruction found;       nop                             ; execute function.;;; call main, passing it 2 arguments. main( argc, argv );	const	lr0, _main	consth	lr0, _main	calli	lr0, lr0	nop;; call exit;	const	lr0, _exit	consth	lr0, _exit	calli	lr0, lr0	add	lr2, gr96, 0;; Should never get here, but just in case;loop:	syscall exit	jmp	loop	nop	.sbttl	"Spill and Fill trap handlers"	.eject;;	SPILL, FILL trap handlers;; Note that these Spill and Fill trap handlers allow the OS to; assume that the only registers of use are between gr1 and rfb.; Therefore, if the OS desires to, it may simply preserve from; lr0 for (rfb-gr1)/4 registers when doing a context save.;;; Here is the spill handler;; spill registers from [*gr1..*rab); and move rab downto where gr1 points;; rab must change before rfb for signals to work;; On entry:	rfb - rab = windowsize, gr1 < rab; Near the end: rfb - rab > windowsize, gr1 == rab; On exit:	rfb - rab = windowsize, gr1 == rab;	.global spillspill:	sub	tav, rab, gr1	; tav = number of bytes to spill	srl	tav, tav, 2	; change byte count to word count	sub	tav, tav, 1	; make count zero based	mtsr	CR, tav		; set Count Remaining register	sub	tav, rab, gr1	sub	tav, rfb, tav	; pull down free bound and save it in rab	add	rab, gr1, 0	; first pull down allocate bound	storem	0, 0, lr0, tav	; store lr0..lr(tav) into rfb	jmpi	tpc		; return...	add	rfb, tav, 0;; Here is the fill handler;; fill registers from [*rfb..*lr1); and move rfb upto where lr1 points.;; rab must change before rfb for signals to work;; On entry:	rfb - rab = windowsize, lr1 > rfb; Near the end: rfb - rab < windowsize, lr1 == rab + windowsize; On exit:	rfb - rab = windowsize, lr1 == rfb;	.global fillfill:	const	tav, 0x80 << 2	or	tav, tav, rfb	; tav = ((rfb>>2) | 0x80)<<2 == [rfb]<<2	mtsr	IPA, tav	; ipa = [rfb]<<2 == 1st reg to fill				; gr0 is now the first reg to fill	sub	tav, lr1, rfb	; tav = number of bytes to fill	add	rab, rab, tav	; push up allocate bound	srl	tav, tav, 2	; change byte count to word count	sub	tav, tav, 1	; make count zero based	mtsr	CR, tav		; set Count Remaining register	loadm	0, 0, gr0, rfb	; load registers	jmpi	tpc		; return...	add	rfb, lr1, 0	; ... first pushing up free bound;; The __init function;;        .sect   .init,text;        .use .init;        .global __init;__init:;        sub     gr1,gr1,16;        asgeu   V_SPILL,gr1,gr126;        add     lr1,gr1,24;;; The __fini function;;        .sect   .fini,text;        .use .fini;        .global __fini;__fini:;        sub     gr1,gr1,16;        asgeu   V_SPILL,gr1,gr126;        add     lr1,gr1,24;#endif	.end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -