/* A crt0 for use with the netbooter.  This code expects to have been
* just loaded by the VMB. */

/* Processor Registers */
.set	KSP,0		/* Kernel Stack Pointer */
.set	ISP,4		/* Interrupt Stack Pointer */
.set	SCBB,0x11	/* System Control Block Base register */
.set	MCESR,0x26	/* Machine Check Error Summary Register */
.set	SID,62		/* System ID register */
.set	MCHECK,0x4	/* Machine Check Vector */

.set	SIDmask,0x00ffffff /* Only the high byte has the processor type */
.set	SID_EXT,0x20040004 /* SID extention register physical address */
.set	uVAX2,0x08000000 /* SID for the uVAX-II */
.set	QBMAP,0x20088000 /* Start of Q-Bus mapping resigters on uVAX-II */
.set	QBMvalid,0x80000000 /* Valid bit in Q-Bus mapping register */
.set	QBMnum,0x2000	/* Number of Q-Bus mapping registers */
.set	Conmem,0x400	/* High memory to save for use by console program */
.set	bootmem,65536	/* Save memory for boot loader */
.set	ERPB_R5,0x30	/* Offset from r11 for VMB input register R5 */

	.globl	start
	.globl	__start
	.globl	_main
	.globl	_himem
	.globl	_load_start

start:
__start:
	.word	0
	nop			/* nop's are saving space */
	nop
	/*
	 * Were we booted by VMB?  If so, r11 is not boothowto,
	 * but rather the address of the `Extended RPB' (see KA630
	 * User's Manual, pp 3-21).  These tests were devised by
	 * richl@tektronix, 11/10/87.
	 */
	cmpl	(r11),r11		# if boothowto, r11 will be small
	bneq	1f			# and these will not fault
	cmpl	4(r11),$0
	bneq	1f
	cmpl	8(r11),$-1
	bneq	1f
	tstl	0xc(r11)
	bneq	1f
	movl	ERPB_R5(r11),r11	/* Get boot flags */
1:
	/* If is a uVAX-II, set up a straight Q-bus map. */
	mfpr	$SID,r0
	bicl2	$SIDmask,r0
	movl	r0,_sid
	cmpl	r0,$uVAX2
	bneq	3f
	movl	*$SID_EXT,r0
	movab	_sid_ext,r1
	extzv	$24,$8,r0,(r1)
	clrl	r0
	movl	$QBMAP,r1	/* Using r1 is important here so that the */
4:	movl	r0,(r1)[r0]	/* code produced is position independant. */
	bisl2	$QBMvalid,(r1)[r0]
	aoblss	$QBMnum,r0,4b

3:	movab	tmpstack,r0
	mtpr	r0,$ISP
	mtpr	r0,$KSP
	/* Get off the interrupt stack */
	pushl	$0x41f0000	/* A PSL at IPL 1f */
	pushab	_JOBSA		/* The PC to return to */
	rei

_JOBSA:
	/* Size memory */
	mfpr	$SCBB,r0
	movab	mcheck,MCHECK(r0)	/* Install own mcheck vector */
	clrl	r0
1:	tstl	(r0)			/* touch memory location */
	addl2	$512,r0			/* go through memory by pages */
	brb	1b

.align	2
mcheck:	mtpr	$0,$MCESR		/* Clear machine check error */
	subl2	$Conmem,r0		/* Save memory for console program */
					/*   Only really needed on uVAX-II */
	movl	r0,_himem		/* store address of first non-existant 
					 * page */

	/* round load_start up to next 1K boundary */
	movab	_end,r0
	addl2	$1023,r0
	bicl2	$1023,r0
	movl	r0,_load_start

	/* get off interrupt stack again */
	pushl	$0x41f0000
	pushab	2f
	rei
2:
	movl	r11,_flags
	movab	tmpstack,sp
	mtpr	sp,$ISP
	mtpr	sp,$KSP
	clrl	ap
	clrl	fp
	pushl	$0
	pushl	$0
	pushl	$0
	calls	$3,_main
	halt

ddtrestart:
	.word	0
	movl	4(ap),r11		/* Pick up boot argument */
	movab	tmpstack,sp
	mtpr	sp,$ISP
	mtpr	sp,$KSP
	clrl	ap
	clrl	fp
	pushl	$0
	pushl	$0
	pushl	$0
	calls	$3,_main
	halt

/* Shift program from _load_start down to 0. */
	.globl	_launch
_launch:
	.word	0
/* relocate ourselves up into high memory */
	movl	4(ap),r9	/* entry point */
	movl	8(ap),r8	/* count */
	movl	_load_start,r7
	clrl	r6
	ashl	$-2,r8,r8
	movl	_himem,r10
	subl2	$0x100,r10
	movab	1f,r0
	movab	2f,r12
	subl2	r0,r12
	movc3	r12,1f,(r10)
	movl	_flags,r11
	jmp	(r10)
1:
	movl	(r7)+,(r6)+
	sobgtr	r8,1b
	clrl	ap
	clrl	r10
	jmp	2(r9)		/* to application */
2:
	.data
/* A stack for the boot program */
	.align	2
	.space	0x1000
kstack:
	.space	0x100
tmpstack:
	.space	4

_himem:	.long	0	/* Address of first nonexistant memory page */
_load_start:
	.long	0	/* Address to (temporarily) load first byte at */
_flags:	.globl _flags
	.long	0
_sid:	.globl _sid
	.long	0
_sid_ext: .globl _sid_ext
	.long 	0
