

| 	srt0.c	6.1	83/07/29

#define	LOCORE
#include "../s32/cpu.h"
#include "../s32/trap.h"

| 
|  Startup code for standalone system
|  Non-relocating version -- for programs which are loaded by boot
| 

	.globl	_end
	.globl	_edata
#ifdef USE_ERM
	.globl	erm_startup
#endif USE_ERM
	.globl	main
	.globl	_rtt
	.globl	configure
	.globl	startup
	.globl	spl0
	.globl	spl5
	.globl	splx
	.globl	chipType, openfirst, autoboot_area, bootline_area, statusReg, PC
	.globl	berrfound, ignerr
	.globl	exit_jmp, setjmp

.data
	.globl symbytes, symcmp, oldsyms
symbytes:	.ascii "SYMS"
symcmp:		.ascii "SYMS"
oldsyms:	.long 0
origregs:	.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.text

	.globl	entry

entry:	movw	#0x2700, sr
	moveml	#0xFFFF, origregs
	movl	#REL_BSS, sp
	movl	sp, a6
	movl	d0, crmboottype		| Save autoboot parameter
	movl	a5, d0
	movl	d0, crmdevtype		| Save device parameter
	movl	#0x0, ignerr		| Set default Berrvec to NOT ignore
start:
#ifdef REL_BSS
	movl	#REL_BSS, a0		| If BSS is not right after data
#else
	movl	#_edata, a0		| If BSS is right after data
#endif
	movl	#_end, a1		| End of BSS
clr:
	movl	#0, a0@+		| Clear BSS
	cmpl	a0, a1
	jge	clr

	movl	#exit_jmp, a7@-		| Set up exit path
	jsr	setjmp
	cmpl	#0, d0
	jne	jmp_exit
	
	jsr	configure		| Configure devices
	jsr	startup			| Initialize environment
#ifdef USE_ERM
#ifdef JMP_ERM
	clrl	a7@-			| set up ERM and jump to it.
	jsr	erm_startup		| E{d's,nhanced} Resident Monitor
	addql	#4, a7
#else  JMP_ERM
	movl	#1, a7@-		| set up but do not jump to ERM.
	jsr	erm_startup		| E{d's,nhanced} Resident Monitor
	addql	#4, a7
#endif JMP_ERM
#endif USE_ERM
	movl	#1, openfirst		| Set in initialize iob's
	movl	crmdevtype, a7@-	| Push device parameter
	movl	crmboottype, a7@-	| Push auotboot parameter
	jsr	main			| Call the main routine
jmp_exit:
	moveml	origregs, #0xFFFF
	rts				| Return to caller?

	.globl	crmboottype, crmdevtype
crmboottype:	.long 0
crmdevtype:	.long 0
ignerr:		.long 0
berrfound:	.long 0

bootline_area:				| See note at autoboot_area below
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
	.long	0
autoboot_area:				| Used to store autoboot parameter
	.word	0			| passed to UNIX must be > 0x2000
	.text				| && < 0x5000

_rtt:
	jmp	start			| Start over

|*
|*  Trap and fault entry, called like:
|* 
|* 	jsr	fault		| leaves ptr to following word on stack
|* 	.word	n		| n will be fault number

	.globl	rte, fault, trap

rte:	rte			| ignore exception

fault:				| Fault handler for bus and address error
	clrw	sp@-		| this makes ps long aligned
	moveml	#0xFFFF,sp@-	| save all registers
|	movl	usp,a0
|	movl	a0,sp@(60)	| save usr stack ptr
	movl	sp@(66),a0	| return ptr from the jsr
	movw	a0@,d0		| get the fault number
	extl	d0
1$:
	movl	d0,sp@-		| argument to trap
	jsr	trap		| C handler for traps and faults


	.globl	buserr

buserr:				| Bus error interrupt routine
	movw	sp@, statusReg	| Save ps
	movl	sp@(2), PC	| Save pc
	addql	#8,sp		| pop fcode, aaddr and ireg
	orw	#0x2000, 0x1f000	| Clear timeout pending bit
	andw	#0xdfff, 0x1f000        | 68020 only
	movw	#0, 0x1e800		| reset the error register
	jsr	fault
	.word	2

	.globl	defaulterr

defaulterr:			| Defualt trap vector
	movw	sp@, statusReg	| Save ps
	movl	sp@(2), PC	| Save pc
	movw	sp@(6), d0	| Get frame type and vector
	andw	#0xFFF, d0	| Mask off just the vector
	lsrw	#2, d0		| Change vector address into vector number
	movl	d0, faultno	| Use vector number as arguement to trap
	jsr	fault		| Trap never returns
faultno:	.word	0

	.globl	addrerr

addrerr:			| Address error interrupt routine
	movw	sp@, statusReg	| Save ps
	movl	sp@(2), PC	| Save pc
	addql	#8,sp		| pop fcode, aaddr and ireg
	jsr	fault
	.word	3

	.globl setjmp,longjmp
setjmp:				| Set up non-local jump
	movl sp@(4),a0		| address of save area
	movl sp@+,a1		| pop return address
	moveml #0xfcfc,a0@	| save d2-d7, a2-a7
	movl a1,a0@(48)		| save pc
	moveq #0,d0		| return value
	jmp a1@			| return

longjmp:			| Execute non local jump
	movl sp@(4),a0		| address of save area
	moveml a0@,#0xfcfc	| restore the registers
	movl a0@(48),a1		| where to resume to
	moveq #1,d0		| return non-zero
	jmp a1@
	
|
| getChipType():
|
| Causes an address error to occur so that we can discover on
| which processor we are running -- 68000/8, 68010 or 68020.
|
| The depth of the stack after an address error distinguishes the type
| of the microprocessor.  After cleaning up the intentional mess,
| we return the processor type to the caller in D0:
|
|		 0 ==>	68000/08;
|	      0x10 ==>	68010;
|	      0x20 ==>	68020;
|		-1 ==>	Don't know! Error.
|
| Addr-err vector:
		GVECT_ADDR=T_ADDRERR<<2

| Chip types:
		G68000=CHIPTYPE_68000 & 0xFF
		G68010=CHIPTYPE_68010 & 0xFF		| Be careful...
		G68020=CHIPTYPE_68020 & 0xFF
		GERROR=-1

		.globl	chipType, aeStackDepth
		.data
		.even
chipType:	.long	CHIPTYPE_68000	| Default microprocessor type
aeStackDepth:	.long	-1		| Address Error stack depth
		.text

	.globl	getChipType

getChipType:
	movl	GVECT_ADDR,a1	| Save the old 'address error' exception vector
	movl	#1$,GVECT_ADDR	| Use our (local) exception vector...
	movl	sp,a0		| Preserve the current stack ptr
|
| The 68000, 68008, and 68010 enforce even boundary data alignment.
| (The 68020 does not enforce any data alignment restrictions.)
|
	tstl	1		| Cause address error: access odd data address
1$:
	movl	a1,GVECT_ADDR	| Restore the old exception vector
	movl	sp,a1		| Get the new stack pointer for comparing
	movl	a0,sp		| Restore the stack pointer

	clrl	d0		| Assume	68000
	subl	a1,a0		| Find out by how much the stack grew...
	movl	a0,aeStackDepth	| DEBUG: Preserve the address-error stack depth
	movl	a0,d1
	cmpb	#14,d1		| Is it a	68000?
	jeq	2$		| Yes, return	68000

	movb	#G68010,d0	| No, pressume	68010
	cmpb	#58,d1		| Is it a	68010?
	jeq	2$		| Yes, return	68010

	movb	#G68020,d0	| No, try 	68020
	cmpb	#0,d1		| Is it a	68020?
	jeq	2$		| Yes, return	68020

	movl	#GERROR,d0	| No, fails all our tests: signify error!
2$:
	orl	d0,chipType	| Save the microprocessor type
	movl	chipType,d0	| Pass chipType back to caller
	rts
|* spl's

	.globl	spl7, spl6, spl5, spl4, spl1, spl0, splx

spl7:	movw	#0x2700,d1	| disable all interrupts including clock
	jra	spl

spl6:	movw	#0x2600,d1	| disable all interrupts but clock
	jra	spl

spl5:	movw	#0x2500,d1
	jra	spl

spl4:	movw	#0x2400,d1
	jra	spl

spl1:	movw	#0x2100,d1
	jra	spl

spl0:	movw	#0x2000,d1
	jra	spl

splx:	movl	sp@(4),d1	| the priority he passed as arg
spl:	movw	sr,d0		| return old priority in d0
	movw	d1,sr
	rts
