/////////////////////////////////////////////////////////////////
/								/
/	XXDP DECtape II boot block.				/
/								/
/	Parameters:						/
/		r0 must contain the unit number.		/
/		r1 must contain the booting device CSR.		/
/								/
/	GNU Assembler syntax					/
/								/
/////////////////////////////////////////////////////////////////

	.text

	.even

	nop			/ always starts with a NOP
	br start		/ skip past the vector table

berr:	rtt	 		/ time out, bus error vector
	.word 0
inst:	.word 012		/ reserved instruction trap vector
	.word 0
debug:	.word 0			/ debugging trap vector
	.word 0
iotv:	.word 0			/ IOT trap vector
	.word 0
pfail:	.word 0			/ Power fail trap vector
	.word 0
emtv:	.word 0			/ EMT trap vector
	.word 0
trapv:	.word 0			/ TRAP trap vector
	.word 0
sys1:	.word 0			/ system software vector
	.word 0
sys2:	.word 0			/ system software vector
	.word 0
sys3:	.word 0			/ system software vector
	.word 0
sys4:	.word 0			/ system software vector
	.word 0

RCSR:	.word 0			/ pointer to the SLU RCSR
RBUF:	.word 0			/ pointer to the SLU RBUF
XCSR:	.word 0			/ pointer to the SLU XCSR
XBUF:	.word 0			/ pointer to the SLU XBUF

TU58:	.byte 0x02		/ TU58 CTRL flag
cmdlen:	.byte 10		/ message length
	.byte 2			/ Read op code
	.byte 0			/ modifier
unit:	.word 0			/ unit and switches
	.word 0			/ sequence number
	.word 512		/ byte count
block:	.word 8			/ block number

start:	mov $060000,sp		/ setup stack. this gets overwritten later
	reset 			/ reset the devices on the bus
	mov $RCSR,r3		/ location of CSR list
	mov $3,r2		/ get next 3 consecutive registers
1$:	mov r1,(r3)+		/ save a copy of CSR address
	tst (r1)+		/ test for bus error. skip to next register
	dec r2			/ done?
	bne 1$			/ no, continue
	mov @$berr,-(sp)	/ yes, push berr vector onto the stack
	mov $nberr,@$berr	/ store new vector in bus error vector
	tst (r1)		/ see if XBUF exists.
	mov r1,(r3)		/ yes, save its address
	br linkup		/ continue

nberr:	mov RBUF,(r3)		/ no, write to RBUF for transmit
	cmp (sp)+,(sp)+		/ clean up stack

linkup:	mov (sp)+,@$berr	/ restore bus error vector

	mov $8,block		/ first block is block - 1
	mov $01000,r4		/ get next block load address
	mov r0,unit		/ save unit number
	mov $8,-(sp)		/ try 8 times to link up with TU58
2$:	clr r3			/ set transmit value to 0
	inc @XCSR		/ send break
	jsr r7,send4		/ send 4 nulls
	dec @XCSR		/ clear break
	mov $0x0404,r3		/ two INIT flags (0x04)
	tst @RBUF		/ clear receiver flags & buffer
	jsr r7,sdata		/ send two INIT flags to drive
	clr r3			/ clear return value
	jsr r7,rbyte		/ read one byte to high byte
	swab r3			/ move char to low byte
	cmpb $0x10,r3		/ CONT flag from tape drive?
	beq 1$			/ yes, continue
	dec (sp)		/ no, done with retries?
	bne 2$			/ no, try again.
	tst (sp)+		/ yes, clean up stack
	br stop1		/ communications error - stop.

1$:	tst (sp)+		/ clean up stack
loadb:	inc block		/ increment block number
	cmp $40,block		/ done loading?
	bne 1$			/ no, continue.

	mov unit,r2		/ yes, get unit number
	mov RCSR,r1		/ get the CSR
	jmp @$0001046		/ start the OS

1$:	jsr r7,msglen		/ get message length in r1
	clr r2			/ clear checksum
	mov $TU58,r0		/ get address of command message
2$:	add (r0)+,r2		/ caclulate checksum for message
	adc r2			/ ....checksum
	decb r1			/ done calculating?
	bne 2$			/ no, continue
	mov r2,(r0)		/ yes, save checksum

	jsr r7,msglen		/ get message length again
	mov $TU58,r0		/ get start of message
3$:	mov (r0)+,r3		/ get first word
	jsr r7,sdata		/ send to tape drive
	decb r1			/ done transmitting?
	bpl 3$			/ no, keep going

6$:	jsr r7,recdat		/ yes, get response.
	cmpb $01,r3		/ data flag?
	bne 4$			/ no, see if it's command flag
	mov r3,r2		/ yes, start checksum
	swab r3			/ get message length
	movb r3,r1		/ move to r1
	bic $0177400,r1		/ make into sane value
	asr r1			/ convert to length in words
5$:	jsr r7,recdat		/ receive next word
	mov r3,(r4)+		/ save at next load address
	add r3,r2		/ calculate checksum
	adc r2			/ .... checksum
	decb r1			/ done receiving message?
	bne 5$			/ no, keep going
	jsr r7,recdat		/ yes, get checksum
	cmp r3,r2		/ is it a match?
	beq 6$			/ yes, get next message
	br stop2		/ no, stop.

4$:	cmpb $02,r3		/ command flag?
	bne stop1		/ no, stop
	mov r3,r2		/ yes, start checksum
	swab r3			/ get message length
	movb r3,r1		/ save it in r1
	bic $0177400,r1		/ convert to a sane value
	asrb r1			/ convert to words
	jsr r7,recdat		/ get next word
	cmpb $0x40,r3		/ end packet?
	bne stop1		/ no, comm. error - stop
	tst r3			/ yes, error code?
	bmi stop1		/ yes, comm. error - stop
	add r3,r2		/ no, add to checksum
	adc r2			/ ... checksum
	decb r1			/ decrement word count
7$:	jsr r7,recdat		/ get next word
	add r3,r2		/ calculate checksum
	adc r2			/ ... checksum
	decb r1			/ done?
	bne 7$			/ no, keep receiving
	tst r3			/ error in summary status?
	bmi stop1		/ yes, comm. error - stop
	jsr r7,recdat		/ no, get checksum
	cmp r3,r2		/ good checksum?
	bne stop2		/ no, bad checksum - stop
	jmp loadb		/ yes, load next block.

stop1:	halt 			/ communications error

stop2:	halt 			/ bad checksum

msglen:	movb cmdlen,r1		/ get command message length
	bic $0177400,r1		/ clear high byte
	asr r1			/ convert to words
	inc r1			/ add one word
	rts r7			/ done.

send4:	jsr r7,(r7)		/ send 2 duplicate words
	jsr r7,(r7)		/ 
sdata:	jsr r7,(r7)		/ send two bytes
	movb r3,@XBUF		/ write to XCSR
	swab r3			/ get next byte ready
1$:	tstb @XCSR		/ transmitter empty?
	bpl 1$			/ no, check again.
	rts r7			/ get next byte

recdat:	clr r3			/ clear return register
	jsr r7,(r7)		/ read two bytes
rbyte:	tstb @RCSR		/ received data?
	bpl rbyte		/ no, check again.
	mov @RBUF,r5		/ yes, get flags and data
	bmi stop1		/ if error during reception, stop
	bisb r5,r3		/ copy data byte to return register
	swab r3			/ swap data to high byte
	rts r7			/ get next byte, or leave if have 2 bytes

