       1                                	.title Dual-Density bootstrap for RX02
       2                                
       3                                	; This bootstrap is derived from the RX211/RXV21
       4                                	; bootstrap that appears in the RX01/RX02 Pocket Service
       5                                	; Gude (DEC order number EK-RX012-PS-002).
       6                                	;
       7                                	; It has been modified so that:
       8                                	; * It can be used for unit 0 or unit 1
       9                                	; * It will first attempt to boot a double-density disk.
      10                                	;   If that fails, it will then attempt to boot a
      11                                	;   single-density disk.
      12                                	;
      13                                	; The code shown below is for unit 0. to boot from unit 1:
      14                                	; * change the word at 0010036 from 000407 to 000427
      15                                	; * change the word at 0010132 from 000000 to 000001
      16                                	;
      17                                	; Malcolm MacLeod - 11 June 2017
      18                                	;
      19                                	; Documentation and boot logic
      20                                	; Joerg Hoppe - Nov 2022
      21                                
      22                                
      23 177170                         rx2cs	= 177170		; RXV21 control/status register
      24 177172                         rx2db	= 177172		; RXV21 data buffer register
      25 000200                         wrdcnt	= ^D128 		; 128 for DBL-DEN, 64 for SGL-DEN
      26 100240                         mask	= 100240		; Bit 15=ERR, 7=XFER-RQST, 5=DONE
      27                                
      28                                	.asect
      29                                	; ---- Simple boot drive 0 from 0
      30 000000                         	. = 0
      31 000000 000137  010000          	jmp	@#start0
      32                                
      33                                	; ---- Reboot drive 0 on power event
      34 000024                         	. = 24				; Power ON/OFF
      35 000024 010000                  	.word	start0			; PC
      36 000026 000340                  	.word	340			; PSW priority level 7
      37                                
      38                                
      39                                	; ----- Main boot addresses
      40 010000                         	.=10000 			;  arbitrary position > 3000
      41                                
      42                                	; On boot from #0 implemented
      43                                start:
      44                                ;	; 2 unit numbers => 2 entry addresses
      45                                start0:
      46                                ;	mov	#0,r0
      47                                ;	br	boot
      48                                ;	nop
      49                                ;start1:
      50                                ;	mov	#1,r0
      51                                
      52 010000 012701  177170          boot:	mov	#rx2cs,r1	; put addr of rx2cs into r1
      53 010004 012700  100240          	mov	#mask,r0	; put bit mask into r0
      54 010010 005002                  	clr	R2		; clear bus addr (dma dest'n addr)
      55 010012 012705  000200          	mov	#wrdcnt,r5	; put word count (128) into r5
      56 010016 012704  000401          	mov	#401,r4 	; track 1, sector 1
      57 010022 012703  177172          $1:	mov	#rx2db,r3	; put addr of rx2db in r3
      58                                
      59                                	; Check that the rxv21 is ready
      60                                
      61 010026 030011                  $2:	bit	r0,(r1) 	; apply mask to rx2cs
      62 010030 001776                  	beq	$2		; loop until err, xfer-rqst or done
      63 010032 100441                  	bmi	quit		; halt if err is set
      64                                
      65                                	; Initiate a read-sector command
      66                                
      67 010034 012711  000407          	mov	#407,(r1)	; den=dden, unit=0, fn=rd-sector, go
      68 010040 030011                  $3:	bit	r0,(r1) 	; apply mask to rx2cs
      69 010042 001776                  	beq	$3		; loop until err, xfer-rqst or done
      70 010044 100434                  	bmi	quit		; halt if err is set
      71                                	; Code assumes that xfer-rqst is now set (ignores done)
      72 010046 110413                  	movb	r4,(r3) 	; write sector number to rx2db
      73 010050 000304                  	swab	r4		; swap track number to bits 0-7
      74 010052 030011                  $4:	bit	r0,(r1) 	; apply mask to rx2cs
      75 010054 001776                  	beq	$4		; loop until err, xfer-rqst or done
      76                                	; Code assumes that xfer-rqst (not err or done) is now set
      77 010056 110413                  	movb	r4,(r3) 	; write track number to rx2db
      78                                
      79                                	; rxv21 is now reading sector data into its own buffer
      80                                
      81 010060 000304                  	swab	r4		; swap track number to bits 15-8
      82 010062 030011                  $5:	bit	r0,(r1) 	; apply mask to rx2cs
      83 010064 001776                  	beq	$5		; loop until err, xfer-rqst or done
      84 010066 100423                  	bmi	quit		; halt if err is set
      85                                
      86                                	; Code assumes that xfer-rqst is now set (ignores done)
      87                                
      88                                	; The sector data is now in rxv21's data buffer.
      89                                	; Prepare to transfer sector data from rxv21 to ram by dma
      90                                
      91 010070 012711  000403          	mov	#403,(r1)	; den=dden, unit=any, fn=empty-buf, go
      92 010074 030011                  $6:	bit	r0,(r1) 	; apply mask to rx2cs
      93 010076 001776                  	beq	$6		; loop until err, xfer-rqst or done
      94 010100 100416                  	bmi	quit		; halt if err is set
      95                                	; Code assumes that xfer-rqst is now set (ignores done)
      96 010102 010513                  	mov	r5,(r3) 	; ld word count into rx2wc via rx2db
      97 010104 030011                  $7:	bit	r0,(r1) 	; apply mask to rx2cs
      98 010106 001776                  	beq	$7		; loop until err, xfer-rqst or done
      99 010110 100412                  	bmi	quit		; halt if err is set
     100                                	; Code assumes that xfer-rqst is now set (ignores done)
     101 010112 010213                  	mov	r2,(r3) 	; ld bus addrs into rx2ba via rx2db
     102                                
     103                                	; Data (256 bytes) is now being copied to ram via dma
     104                                
     105 010114 060502                  	add	r5,r2		; add 128 dec to bus address
     106 010116 060502                  	add	r5,r2		; add 128 dec to bus address
     107 010120 122424                  	cmpb	(r4)+,(r4)+	; increment sector number by 2
     108 010122 120427  000007          	cmpb	r4,#7		; sectors 1, 3, 5 & 7 will be read
     109 010126 003737                  	ble	$2		; loop back and do next sector
     110 010130 012700  000000          	mov	#0,r0		; boot device is unit 0
     111 010134 005007                  	clr	pc		; go to addr zero
     112                                
     113                                	; Errors always branch to here. on first error (during
     114                                	; dden attempt) we change to sden mode and try again.
     115                                	; Self modifying code here!
     116                                	; On second error, we halt.
     117                                
     118 010136 000005                  quit:	reset			; reset all i/o devices
     119 010140 012700  010000          	mov	#boot,r0	; load r0 with start address
     120 010144 012701  000400          	mov	#400,r1 	; setup mask byte
     121 010150 006260  000014          	asr	14(r0)		; change "mov #wrdcnt,r5" to 64 decimal
     122 010154 040160  000036          	bic	r1,36(r0)	; change "mov #407,(r1)" read-sector cmd to sden
     123 010160 040160  000072          	bic	r1,72(r0)	; change "mov #403,(r1)" empty-buffer cmd to sden
     124 010164 012760  000017  000124  	mov	#17,124(r0)	; change "cmpb r4,#7" last sector to d'15
     125 010172 005060  000136          	clr	136(r0) 	; change "reset" to halt at quit location
     126 010176 000700                  	br	boot		; go back and try sden mode
     127                                
     128                                	.end
     128                                
