	.title	M9312 'DU' BOOT prom for MSCP compatible controller

	; This source code is a mdified copy of the DEC M9312 23-767A9 boot PROM.
	;
	; This boot PROM is for any MSCP compatible controller (DEC UDA50, EMULEX UC17/UC18).
	;
	; Multiple units and/or CSR addresses are supported via different entry points.

		;
	; Revision history:
	; May 2017: Joerg Hoppe
	;
	; 198?:  DEC
	;      Original ROM 23-767A9 for M9312.
	;



mscsr	=172150 			; std MSCP csrbase

msip	=+0				; IP register
mssa	=+2				; SA register

	.asect
	; ---- Simple boot drive 0 from 0
	. = 0
	jmp	@#start0

	; ---- Reboot drive 0 on power event
	. = 24				; Power ON/OFF
	.word	     start0		; PC
	.word	     340		; PSW priority level 7


	; ----- Main boot addresses
	.=10000 			;  arbitrary position > 3000


rpkt	=1004	; rpkt structure
cpkt	=1070	; cpkt structure
comm	=1200	; comm structure
;comm	 =2404	 ; comm structure (at 'blt .+12')

	; register usage:
	; r0: unit number 0..3
	; r1: MSCP csrbase
	; r2: moving buffer pointer
	; r3: moving buffer pointer
	; r5: init mask

	; 4 unit numbers => 4 entry addresses
start0:
	mov	#0,r0
	br	duNr
	nop
start1:
	mov	#1,r0
	br	duNr
	nop
start2:
	mov	#2,r0
	br	duNr
	nop
start3:
	mov	#3,r0

	; retry entry
duNr:	mov	#mscsr,r1		; boot std csr, unit <R0>

go:	mov	r0,(r1)+		; init controller (write IP), bump ptr
	mov	#4000,r5		; S1 state bitmask
	mov	#mscpdt,r3		; point to data

	; write 4 init words, with r5 mask from 4000 to 40000
3$:	tst	(r1)			; error bit set ?
	bmi	duNr			; yes, fail back to begin to retry
	bit	(r1),r5 		; step bit set ?
	beq	3$			; not yet, wait loop
	mov	(r3)+,(r1)		; yes, send next init data
	asl	r5			; next mask
	bpl	3$			; s4 done? br if not yet

4$:	clr	r2			; set bufptr to 0
5$:	clr	(r2)+			; clear buffer [0..2403]
	cmp	r2,#comm		; check for end of buffer
	bne	5$			; loop if not done

	mov	r2,@#cpkt-4		; set lnt -- R2=2404
	movb	(r3)+,@#cpkt+10 	; set command
	movb	(r3),@#cpkt+15		; set bytecnt(hi)
	mov	r0,@#cpkt+4		; set unit
	mov	#rpkt,(r2)+		; rq desc addr
	mov	r5,(r2)+		; rq own bit15
	mov	#cpkt,(r2)+		; cp desc addr
	mov	r5,(r2)+		; cq own bit15
	mov	-2(r1),r2		; wake controller (read IP)

6$:	tst	@#comm+2		; rq own controller ?
	bmi	6$			; loop if not done

	tstb	@#rpkt+12		; check for error ?
	bne	duNr			; yup, fail back to begin to retry

	tstb	(r3)+			; check end of table ?
	beq	4$			; br if not yet

	clr	-(r1)			; init controller (write IP)
	clr	pc			; jmp to bootstrap at zero

	; MSCP init and command data
	; pointed to by r3
mscpdt:
	.word	100000			; S1: 100000 = no int, ring size 1, no vector
	.word	comm			; S2: 002404 = ringbase lo addr
	.word	000000			; S3: 000000 = no purge/poll, ringbase hi addr
	.word	000001			; S4: 000001 = go bit
	;
	; MSCP command data
	;
	.byte	011,000 		; cmd=011(online), bytecnt_hi=000(0)
	.byte	041,002 		; cmd=041(read), bytecnt_hi=002(512)

	.end
