;+ ; ; MSCP device driver. ; ; I hope to squeeze a Pro/350 RX50 bootstrap in here too but space is tight, ; anyway I have yet to figure out how to make an RX50 look bootable to the ; Pro ROM code, and I don't know what the entry conditions are (are r0/r1 set ; as usual or do I have to search the slots for the RX50 controller?). ; ; By John Wilson. This file is hereby released into the public domain. ; ; 11/20/95 JMBW Created. ; ;- udip= 0 ;(772150) initialization, polling udsa= 2 ;(772152) status/addr, purge ; op.scc= 004 ;set controller characteristics op.onl= 011 ;online op.rd= 041 ;read data ; ; PRO350/RX50 stuff ompr= 173702 ;bitmap of which options exist (bits 0-5 = slots 0-5) slot0= 174000 ;slot 0 location sltinc= 200 ;increment between slots ; rx5id= 00 ;ID register, low byte reads as 004 ;rsvd 02 ;not for us rx5cs0= 04 ;CSR 0 (status/cmd) rx5cs1= 06 ;CSR 1 (track etc.) rx5cs2= 10 ;CSR 2 (sector etc.) rx5cs3= 12 ;CSR 3 (disk change/ready bits etc.) rx5cs4= 14 ;CSR 4 (disk avail bits) rx5cs5= 16 ;CSR 5 (extended function code) rx5eb= 20 ;empty buf (reads next silo byte) rx5ca= 22 ;clear addr reg (any access clears silo ptr) rx5go= 24 ;start cmd (any access starts cmd in other regs) rx5fb= 26 ;fill buf (writes next silo byte) ; rxrtry= 10. ;# retries to attempt ; rxrcl= 2*20 ;recalibrate rxrds= 4*20 ;read sector ; rxdone= 10 ;"done" bit in RX5CS0 ; idprom= 173600 ;base of 32-byte ID PROM in Pro ; .btini ;UDA50 init code mov r0,bunit ;save unit ; ; see if it's a Pro ; mov sp,r5 ;save stack ; mov #10$,@#4 ;trap if not Pro ; cmp @#idprom+64,#125 ;look for checkerboard part of PROM ; bne 10$ ; cmp @#idprom+66,#252 ; beq 60$ ;10$: mov r5,sp ;restore stack mov #6,@#4 ; go through 4-step init process clr (r1)+ ;write IP, start init process mov #4000,r0 ;step 1 flag mov #steps,r5 ;point at table 20$: mov (r1),r2 ;get flag from UDSA bpl 30$ bpt ;error, die 30$: bit r0,r2 ;is our step on yet? bne 50$ ;got it ; Dilog controllers get stuck if you poll too often mov #1000.,r3 ;delay count, somewhat CPU-specific 40$: tst @#ttcsr ;touch a known port, less CPU-specific dec r3 bne 40$ br 20$ ;go poll again 50$: mov (r5)+,(r1) ;store next word asl r0 ;shift to next step bpl 20$ ;loop unless ran into bit 15 ; resync per page 4-17 of MSCP Basic Disk Functions Manual jsr r5,inipkt ;init packet .word op.scc ;set controller characteristics call cmd ;accept all defaults jsr r5,inipkt ;init packet .word op.onl ;unit online call cmd br 70$ 60$: ; Pro ;;; detect which slot it's in mov #rxread,@#20 ;reset IOT vector mov #"DZ,@#24 ;device name 70$: .btfin ;finish up boot process ;+ ; ; UDA50 bootstrap read driver. ; ; r5 memory addr ; r4 block count ; r3 starting block ; ;- read: jsr r5,inipkt ;init packet .word op.rd ;func=read mov r3,dublk ;set block # swab r4 ;word count asl r4 ;byte count mov r4,dubc mov r5,duba ;bus addr ;br cmd ;do it, return ; cmd: ; do command mov #rsprng,r1 ;point at descriptors mov #packet,(r1)+ ;reinit descriptors mov #100000,(r1)+ ;OWN=1, FLAG=0 mov #packet,(r1)+ ;(RQDX3 appears to clear out whole entry) mov #100000,(r1) tst @bcsr ;tell UDA50 to poll 10$: tst rsprng+2 ;wait until UDA gives back msg buf bmi 10$ 20$: tst cmdrng+2 ;and cmd buf bmi 20$ bitb #37,dustat ;error completion? bne 30$ ;yes rts pc 30$: bpt ;+ ; ; Init command packet. ; ; Called through r5 with in-line opcode word. ; ; r3-5 preserved ; ;- inipkt: mov #packet,r1 ;point at it mov #/2,r2 ;length in words 10$: clr (r1)+ ;clear a word dec r2 ;loop bne 10$ mov (r5)+,duopcd ;set opcode mov bunit,duunit ;and unit # rts r5 ;+ ; ; Pro/350,380 RX-50 bootstrap read driver. ; ; Since Pro's always have F-11 or J-11 processors we know it's OK to use EIS ; instructions. ; ; r5 memory addr ; r4 block count ; r3 starting block ; ; IHEAD=ITRK/80 ! apparently not supported by hardware yet ; ITRK=MOD(ITRK,80) ! ; ISEC=ISEC*2 ; IF(ISEC.GE.10) ISEC=ISEC+1 ; ISEC=MOD(ISEC+ITRK*2,10)+1 ; ITRK=MOD(ITRK+1,80) ; ;- rxread: mov #rxrtry,(pc)+ ;init counter retry: .blkw ;# retries left to go 10$: ; attempt to read next sector mov r3,r1 ;copy block clr r0 ;zero-extend div #10.,r0 ;r0=track, r1=sector cmp #4.,r1 ;C=1 if second half of sector rol r1 ;sector *2, use odd locs if in second half mov r0,r2 ;save track asl r0 ;track *2 (track-to-track skew=2) add r0,r1 ;add to sec clr r0 ;zero-extend div #10.,r0 ;make all the interleave stuff mod 10. inc r1 ;secs are in [1,10.] inc r2 ;track +1 cmp r2,#80. ;off end? blo 20$ clr r2 ;yes, wrap around to track 0 (weird!) 20$: mov bcsr,r0 ;point at CSR movb r1,rx5cs2(r0) ;set sector movb r2,rx5cs1(r0) ;set track mov bunit,r1 ;get drive, unit asl r1 ;*2 bis #rxrds,r1 ;OR in command movb r1,rx5cs0(r0) ;set cmd clrb rx5go(r0) ;start it 30$: bitb #rxdone,rx5cs0(r0) ;done? beq 30$ tstb rx5cs0(0) ;error? bmi 50$ clrb rx5ca(r0) ;clear silo pointer mov #1000,r1 ;block length add #rx5eb,r0 ;point at silo 40$: movb (r0),(r5)+ ;get a byte sob r1,40$ ;loop through all inc r3 ;bump block # dec r4 ;done all blocks? bne rxread ;do next if not rti 50$: ; read error dec retry ;time to give up? beq 70$ ;yes mov bunit,r1 ;get drive, unit asl r1 ;*2 bis #rxrcl,r1 ;OR in command mov r1,rx5cs0(r0) ;set cmd clrb rx5go(r0) ;start it 60$: bitb #rxdone,rx5cs0(r0) ;done? beq 60$ tstb rx5cs0(0) ;error? bmi 50$ ;recal again br 10$ 70$: bpt ; ; prev 2/4 words get overwritten with int info by port rsprng: .blkw 2 ;response ring base cmdrng: .blkw 2 ;command ring base ; ;.=.-8. ; hoped I could overlay it, but doesn't work with RQDX3 steps: .word 100000 ;STEP bit, no interrupts, rings=1 entry each .word rsprng ;LSW of ring pointer base .word 0 ;MSW=0 .word 1 ;burst=default, last fail=no, go ; .word endpkt-packet ;length of packet .word 0 ;virtual circuit ID packet: ; actual start of packet (prev 4 bytes not official but oh please) .word 1,0 ;ref number duunit: .word ;unit # .word 0 ;(rsvd) duopcd: .blkw ;opcode dustat: .blkw ;status dubc: .blkw 2 ;byte count duba: .blkw 6 ;buffer addr dublk: .blkw 2 ;block # .rept 60-<.-packet> ;pad out to 60 bytes (or is that 60. bytes?) .byte 0 .endr endpkt: ; end of packet ; .end boot