Xinu7/src/cmd/download/OLD/dl.s

halt=0
reset=5
/
/ Downloader - two part download program for LSI-11/02
/
/     Port constants
/
RCSR=0		/ Register displacements
RDATA=2		/ .
TCSR=4		/ .
TDATA=6		/ .
P0=177560
/
PACKSIZE=200    / maximum packet size
SOH='/		/ start-of-header
ACK='y
NAK='n
ESC=33
/
/
/ Phase 0
/
/ this gets loaded at location zero - loading stops with the 177777.
/ It reads the downloader from the high speed line into the topmost
/ part of memory and then halts.
/
/   Arguments:
/	r1 - length of bss section (this is zeroed)
/	r2 - time delay in seconds before starting program (<0 then halt)
/	r3 - starting address of the program if r2 >= 0
/	r4 - base address of RCSR
/
/   Stack frame displacements
/
bsslen=-2
delay=-4
pstart=-6		/ program start address
sum=-10			/ global checksum
packbuf=-12		/ address of packet buffer
baseaddr=-14		/ address field of current packet
length=-16		/ length field from current packet
FRAMELEN=200            /   frame length


start:
        reset
        jbr begin               / skip exception vector
	excpt; 340
begin:
0:	bitb	$200,*$P0+RCSR	/ wait for character
	beq	0b
excpt:
	mov	$stack,sp	/ reload stack pointer
	movb	*$P0+RDATA,-(r0) / try storing, if fail, dec and retry
	sob	r1,0b		/ success - load remaining bytes
	mov	r0,sp		/ set sp to beginning of program
	halt			/ return control to ODT, VAX issues "P"
	jmp	(sp)		/ start program
	177777
stack=.+4
/
/  Phase 1
/
/  This program is copied into the topmost portion of memory by phase 0.
/  It must be relocatable (no PC-relative modes).
/
phase1:
	mov	sp,r5		/ allocate a stack frame
        sub     $PACKSIZE*2+FRAMELEN,sp
	mov	r1,bsslen(r5)	/ save arguments
	mov	r2,delay(r5)
	mov	r3,pstart(r5)
	mov	sp,packbuf(r5)
retry:
0:	jsr	pc,rawgetc	/ scan for SOH
	cmpb	$SOH,r0
	bne	0b
	clr	sum(r5)		/ start check summing
	jsr	pc,getwsum	/ get base address
	mov	r0,baseaddr(r5)
	jsr	pc,getwsum	/ get packet length
	mov	r0,length(r5)
	cmp	$PACKSIZE,r0	/ valid?
	blt	sendnak		/ no - send nak
/
/  read data words into the packet buffer on the stack
/
	mov	r0,r3		/ set up registers for loop
        beq     getsum
	mov	packbuf(r5),r2
1:	jsr	pc,getwsum	/ get a data word
	mov	r0,(r2)+	/ save in buffer on stack
	sob	r3,1b
/
/  read and check checksum
/
getsum:
	jsr	pc,getwsum
	tst	sum(r5)		/ sum should now be exactly zero
	beq	copypack	/  yes=>copy packet into place
/
/ invalid packet - send NAK and retry
/
sendnak:
	mov	$NAK,r0
        jsr     pc,rawputc
	jbr	retry
/
/ valid packet - copy into place and send the ACK
/
copypack:
	mov	baseaddr(r5),r2
	mov	packbuf(r5),r1
	mov	length(r5),r3
	beq	sendack
0:	mov	(r1)+,(r2)+
	sob	r3,0b
sendack:
	mov	$ACK,r0
        jsr     pc,rawputc
/
/ if the length was zero then that's all there is
/
	tst	length(r5)
	bne	retry
/
/ zero out bss - if there is any
/
	mov	bsslen(r5),r1
	beq	1f
	mov	baseaddr(r5),r0
0:	clrb	(r0)+
	sob	r1,0b
1:
/
/ implement auto start options - derived from Chris Kent's code
/
	mov	delay(r5),r0	/ get delay
	tst	r0		/ if <0, don't start loaded program
	bgt	1f
	beq	3f		/ if = 0, just start it
	halt
1:
	asl	r0		/ multiply by 2
1:
	mov	$175000,r1	/ .5 sec time constant
2:
	dec	r1
	bhi	2b		/ .5 sec loop end
	dec	r0
	bhi	1b		/ timer loop end
3:
	jmp	*pstart(r5)	/ start the program
/
/ getwsum - get a word and add into the checksum
/ getw - get a word from the line
/
getwsum:
	jsr	pc,getw		/ get a word
	add	r0,sum(r5)
	rts	pc
getw:
	jsr	pc,getc		/ get low order byte
	mov	r0,r1		/ save.
	jsr	pc,getc		/ get high order byte
        swab    r0
        bis     r1,r0           / merge together
	rts	pc
/
/ getc - get a character, honoring ESCing
/
getc:
	jsr	pc,rawgetc	/ get a character
	cmpb	$ESC,r0		/ is it an escape
	bne	1f
	jsr	pc,rawgetc	/ get the real one
1:	rts	pc
/
/ rawgetc - get a character from the line
/
rawgetc:
0:	bitb	$200,RCSR(r4)
	beq	0b
	movb	RDATA(r4),r0
        bic     $177400,r0
	rts	pc

/
/ rawputc - put a character on the line
/
rawputc:
0:	bitb	$200,TCSR(r4)
	beq	0b
	movb	r0,TDATA(r4)
	rts	pc