Xinu7/src/cmd/download/vax/src/sdl.boot.s

Compare this file to the similar file:
Show the results in this format:

/* dl.s -- phase0, phase1 */

#define	PH1LEN	r0
#define	PH1ADR	r1
#define	DELAY	r2
#define	ENTRY	r3
#define	IOBYTE	r4
#define	STATUS	r5
#define	SIDREG	r6

#include <procreg.h>
#include <vdownload.h>

/*----------------------------------------------------------------------------
 * Phase 0 of downloader.  Loaded at location P1BSTRT using console deposit
 * commands, loading stops with the 0xffffffff value.  Reads phase1 of
 * the downloader from the high speed line into a high location in memory
 * (address in r0) and then executes phase1.  Assumes processor in kernel
 * mode with interrupts disabled, memory mapping disabled, on interrupt
 * stack.
 *
 *   Arguments:
 *	r0 - length in bytes of phase1
 *	r1 - address of highest byte at which phase1 is to be loaded + 1
 *	r2 - time delay before performing autostart
 *	r3 - entry point for performing autostart (if r2 >= 0)
 *----------------------------------------------------------------------------
 */
	.text
phase0:					/* no entry mask -- not called	*/
	movab	tmpstk, sp		/* give stack some memory	*/
	mfpr	$SID, SIDREG		/* get system ID, if 8600, 	*/
	bicl2	$SYSTYPE, SIDREG	/* setup RXCS and TXCS		*/
	cmpl	SIDREG, $VAX8600SID
	jneq	loadphase1		/* if not 8600, go get input	*/
	mtpr	$RXCS8600, $RXCS	/* enable 8600 console I/O	*/
	mtpr	$TXCS8600, $TXCS
loadphase1:
	bsbb	getbyte			/* read phase1 in reverse order	*/
	cvtlb	IOBYTE, IOBYTE		/* (8600) chop off high bytes	*/
	cmpb	IOBYTE, $ESC		/* if escaped, get real byte	*/
	jneq	storebyte		/* otherwise go on		*/
	bsbb	getbyte
	bicl2	$0xffffff40, IOBYTE	/* remove stuffed bit		*/
storebyte:
	movb	IOBYTE, -(PH1ADR)	/* store the byte		*/
	sobgtr	PH1LEN, loadphase1	/* go back to input more	*/
	movl	PH1ADR, sp		/* give stack some memory	*/
	jmp	(PH1ADR)		/* run the loaded phase1	*/

getbyte:
	mfpr	$RXCS, STATUS		/* get input status		*/
	jbc	$SLURDYBIT,STATUS,getbyte/* go back if input not ready	*/
	mfpr	$RXDB, IOBYTE		/* get byte and store it	*/
	rsb

	.align	2			/* align loc ctr to longword	*/
	.long	P0MARKER		/* marks end of phase0		*/
tmpstk:					/* stack for phase 0		*/

/* definitions for phase1 */
#undef	PH1LEN
#define	SUM	r0			/* the checksum			*/
/*		r1	is PH1ADR
		r2	is DELAY
		r3	is ENTRY	
		r4	is IOBYTE
		r5	is STATUS
		r6	is SIDREG					*/
#define	LENGTH	r7			/* length of packet in words	*/
#define	BASEADR	r8			/* destination addr of packet	*/
#define	COUNT	r9			/* loop control variable	*/
#define	PACKADR	r10			/* current address in packet	*/
#define	INWORD	r11			/* the current input word	*/
#define	SAVCLKV	r12			/* saved copy of clock vector	*/

/*-----------------------------------------------------------------------
 * Phase1 -- load program into low memory over console line.  Phase1 is
 *		loaded into high memory by phase0
 *-----------------------------------------------------------------------
 */
phase1:					/* no entry mask -- not called	*/
	clrl	INWORD			/* initialize high word to 0	*/
getsoh:
	bsbw	rawgetc			/* scan for SOH			*/
	cmpb	IOBYTE, $SOH
	jneq	getsoh
	clrl	SUM			/* start check summing		*/
	bsbw	getwsum			/* get low word of base address	*/
	movw	INWORD, BASEADR
	bsbw	getwsum			/* get high word of base address*/
	insv	INWORD,$16,$16,BASEADR
	bsbw	getwsum			/* get packet length		*/
	movl	INWORD, LENGTH
	cmpw	LENGTH, $PACKSIZE	/* test packet length		*/
	jgtr	sendnak			/* invalid length--retry	*/

	movl	LENGTH,	COUNT		/* set up to get packet		*/
	jeql	getsum
	movaw	packbuf, PACKADR
getwbuf:
	bsbw	getwsum			/* get word for packet		*/
	movw	INWORD, (PACKADR)+	/* store in buffer		*/
	sobgtr	COUNT, getwbuf		/* get rest of packet		*/

getsum:
	bsbw	getwsum			/* test checksum		*/
	tstw	SUM			/* sum should now be zero	*/
	jeql	copypack		/* yes==> copy packet to memory	*/

sendnak:				/* invalid packet - send NAK &	*/
	movb	$NAK, IOBYTE		/* retry			*/
	bsbw	rawputc
	jbr	getsoh

copypack:				/* valid packet--place it in	*/
	movl	LENGTH, COUNT		/* memory and send ACK		*/
	jeql	sendack			/* zero length packet		*/
	movaw	packbuf, PACKADR
storeword:
	movw	(PACKADR)+, (BASEADR)+
	sobgtr	COUNT, storeword

sendack:
	movb	$ACK, IOBYTE
	bsbw	rawputc
	tstw	LENGTH			/* if zero length, that's all	*/
	jneq	getsoh			/* else get another packet	*/

	tstl	DELAY			/* see if autostart desired	*/
	jeql	startit			/* no delay, just start it	*/
					/* if delay<0, no autostart-->	*/
					/* wait for user to break to	*/
					/* console mode			*/
	jlss	haltit

/* implement autostart-- UVAXI and UVAXII don't have ICCS INT bit to	*/
/* busy-wait on, so drop interrupt priority to count down		*/

	movl	*$CVECTOR, SAVCLKV	/* save old clock vector	*/
	movab	tickhandler+1, *$CVECTOR/* point to autostart handler	*/
	movl	$100, COUNT		/* counts ticks (1/100th sec)	*/
	mtpr	$-CLKINTVL, $NICR	/* set up clock with timer val	*/
	mtpr	$STRTCLK, $ICCS		/* (UVAXEN are hardwired)	*/
	mtpr	$CLKIPL, $IPL		/* lower interrupt priority	*/

/* loop until DELAY == 0 if autostarting, or until user breaks into	*/
/* console mode, if no autostart and not UVAXII				*/

occupycpu:
	jbr	occupycpu
					/* tickhandler catches clock	*/
	.align	2			/* interrupts on interrupt stk	*/
tickhandler:
	mtpr	$CLEARINT, $ICCS	/* clear clock interrupt	*/
	decl	COUNT			/* count 1/100th sec ticks	*/
	jneq	1f			/* not a full second yet, go on	*/
	decl	DELAY			/* decrement count of seconds	*/
	jeql	arestore		/* count completed, start code	*/
	movl	$100, COUNT		/* count another second		*/
1:	rei

arestore:				/* restore from autostart	*/
	mtpr	$DISABLE, $IPL		/* disable interrupts		*/
	movl	SAVCLKV, *$CVECTOR	/* restore old clock vector	*/
	mtpr	$0, $NICR		/* restore clock		*/
	mtpr	$0, $ICCS

startit:				/* go to entry point of code	*/
	jmp	(ENTRY)			/* should never return		*/

haltit:
					/* if it's a UVAXII can halt,	*/
					/* otherwise must do tight loop	*/
					/* (halting may cause "reboot")	*/
	mfpr	$SID, SIDREG		/* get system id register value	*/
	bicl2	$SYSTYPE, SIDREG	/* mask off system id		*/
	cmpl	SIDREG, $UVAXIISID	/* if UVAXII, issue halt	*/
	jneq	occupycpu		/*   otherwise do tight loop	*/
	movw	$QMHALT,*$QMCPMBX	/* raise console prog mailbox	*/
	halt

getwsum:				/* getwsum--get word, chksuming	*/
	bsbw	getc			/* get low order byte		*/
	movb	IOBYTE, INWORD
	bsbw	getc			/* get high order byte		*/
	insv	IOBYTE,$8,$8,INWORD	/* high byte into word		*/
	addw2	INWORD, SUM		/* maintain checksum		*/
	rsb

getc:					/* get byte, honoring ESC	*/
	bsbw	rawgetc
	cmpb	$ESC, IOBYTE		/* is it the ESC?		*/
	jneq	1f			/* no ==> return the byte	*/
	bsbw	rawgetc			/* yes==> get the real byte	*/
	bicl2	$0xffffff40, IOBYTE	/* remove stuffed bit		*/
1:
	rsb

rawgetc:
	mfpr	$RXCS, STATUS		/* get status			*/
	jbc	$SLURDYBIT,STATUS,rawgetc/* go back if input not ready	*/
	mfpr	$RXDB, IOBYTE		/* get byte			*/
	cvtlb	IOBYTE, IOBYTE		/* (for 8600)			*/
	rsb

rawputc:				/* rawputc -- put character	*/
	mfpr	$TXCS, STATUS		/* get status			*/
	jbc	$SLURDYBIT,STATUS,rawputc/* if busy, go back		*/
	mtpr	IOBYTE, $TXDB		/* send byte			*/
	rsb

packbuf:				/* phase0 leaves PACKSIZE*2	*/
					/* bytes here for packet buffer	*/