/* 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	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

start:
__start:
	.word	0
	nop			/* nop's are saving space */
	nop
	movl	ERPB_R5(r11),r11	/* Get boot flags */
/*
	pushl	r11
	calls	$1,_phex
	pushl	$10
	calls	$1,_putchar
*/
	/* If is a uVAX-II, set up a straight Q-bus map. */
	mfpr	$SID,r0
	bicl2	$SIDmask,r0
	cmpl	r0,$uVAX2
	bneq	3f
	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
/*
	pushab	9f
9:	calls	$1,_phex
	pushl	$10
	calls	$1,_putchar

	/* Get off the interrupt stack */
	pushl	$0x41f0000	/* A PSL at IPL 1f */
	pushab	_JOBSA		/* The PC to return to */
	rei

_JOBSA:
/*
	pushab	9f
9:	calls	$1,_phex
	pushl	$10
	calls	$1,_putchar
*/
	/* 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 */

	/* get off interrupt stack again */
	pushl	$0x41f0000
	pushab	2f
	rei
2:	/* Copy self into high memory */
/*
	pushab	9f
9:	calls	$1,_phex
	pushl	$10
	calls	$1,_putchar
*/
	movl	_himem,r7
	/* BEGIN CROCK */
	cmpl	$0x200000,r7		/* are we above the 22-bit mark? */
	jgeq	1f			/* (a flat Q-bus map won't do any */
	movl	$0x200000,r7		/* good above here) */
1:
	/* END CROCK */
	subl2	$bootmem,r7		/* compute destination */
	/* TEMPORARY KLUDGE */
	movl	$0x200000,r7
	/* END TEMPORARY KLUDGE */
	movab	start,r0
	movab	_end,r6
	subl2	r0,r6			/* compute length (this is a crock!) */
	movc3	r6,start,(r7)
	jmp	*$3f	/* jump into the copy (if linked for high mem) */
/*
	movab	3f(r7),r7
	movab	start,r1
	subl2	r1,r7
	jmp	(r7)		/* jump into the copy (if linked at 0) */

3:
/*
	pushab	9f
9:	calls	$1,_phex
	pushl	$10
	calls	$1,_putchar
*/
	movab	ddtrestart,start  /* save restart address so DDT can find it */
	movab	tmpstack,r0
	mtpr	r0,$ISP
	movab	start,sp
	mtpr	sp,$KSP
	clrl	ap
	clrl	fp
/*
	pushl	r11
	calls	$1,_phex
	pushl	$10
	calls	$1,_putchar
*/
	pushl	$0
	pushl	$0
	pushl	$0
	calls	$3,_main
	halt

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

	.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 */
