;+ ; ; RK611/RK06,RK07 boot device driver. ; ; By John Wilson. This file is hereby released into the public domain. ; ; 11/24/95 JMBW Created. ; ;- rkcs1= 00 ;(777440) control/status 1 rkwc= 02 ;(777442) word count rkba= 04 ;(777444) bus addr rkda= 06 ;(777446) disk addr rkcs2= 10 ;(777450) control/status 2 rkds= 12 ;(777452) drive status rker= 14 ;(777454) error rkas= 16 ;(777456) attn summary/offset rkdc= 20 ;(777460) desired cyl ; 22 ;(777462) unused R/W register rkdb= 24 ;(777464) data buf rkmr1= 26 ;(777466) maint reg 1 rkecps= 30 ;(777470) ECC posn rkecpt= 32 ;(777472) ECC pattern rkmr2= 34 ;(777474) maint reg 2 rkmr3= 36 ;(777476) maint reg 3 ; rkrtry= 5 ;max retry count ; ; RKCS1 bits: rkerr= 100000 ;composite error ; rkrdy= 200 ;ready ; rksel= 00*2 ;select drive rkack= 01*2 ;pack acknowledge rkdcl= 02*2 ;drive clear rkrcl= 05*2 ;recalibrate rkrdd= 10*2 ;read data ; rkgo= 1 ; ; RKER bits: rkdck= 100000 ;data check error rkech= 100 ;DCK error is not ECC correctable ; .btini ;RK611 init code mov rkcs2(r1),r0 ;get unit bic #^C7,r0 ;isolate mov r0,bunit ;save movb rkds(r1),r0 ;get drive type asl r0 ;from bit 8 to bit 10 asl r0 bic #^C2000,r0 ;isolate mov r0,(pc)+ ;save drive type bit rkdrvt: .word ;drive type in bit 10: 0=RK06, 1=RK07 .btfin ;finish up boot process ;+ ; ; RK611/RK06,RK07 bootstrap read driver. ; ; r5 memory addr ; r4 block count ; r3 starting block ; ;- read: mov #rkrtry,(pc)+ ;init retry count retry: .blkw ;retry count 10$: ; compute starting sector addr mov r3,r1 ;copy block # mov #-1,r0 ;init track to 0 20$: inc r0 ;count the cyl sub #22.*3,r1 ;count a cyl's worth (3 surfaces @ 20 secs) bcc 20$ ;loop until we get there mov #3*400,r2 ;init to last surface +1 30$: sub #400,r2 ;count a surface add #22.,r1 ;add a surface's worth of sectors bcc 30$ bis r2,r1 ;compose track/sec word ; r0=cyl, r1=track,,sector mov bcsr,r2 ;get CSR mov r0,rkdc(r2) ;set desired cyl add #rkcs2,r2 ;point at CSR 2 mov bunit,(r2) ;set unit # mov r1,-(r2) ;disk addr mov r5,-(r2) ;bus addr mov r4,r0 ;fetch blk count swab r0 ;convert to word count neg r0 ;take 2's comp mov r0,-(r2) ;save mov rkdrvt,r0 ;get drive type bit bis #rkrdd!rkgo,r0 ;add command bits mov r0,-(r2) ;write cmd 40$: bit #rkerr!rkrdy,(r2) ;done? beq 40$ ;spin until it is bmi 50$ ;error rti 50$: ; read error mov rker(r2),r0 ;fetch error reg bpl 80$ ;not data check, skip bit #rkech,r0 ;correctable? bne 80$ ;no ; correct it using ECC mov r5,-(sp) ;save mov r4,-(sp) mov r3,-(sp) mov rkba(r2),r5 ;fetch addr of next sector sub #512.,r5 ;back up to the one with the error mov rkecps(r2),r4 ;get ECC starting bit position dec r4 ;make it start at 0 instead of 1 mov r4,r0 ;copy clc ;C=0 ror r0 ;right 4 bits asr r0 asr r0 asr r0 add r0,r5 ;advance to word containing first error bit mov rkecpt(r2),r0 ;get ECC error pattern (1 for each bad bit) clr r1 ;init 2nd word bic #^C17,r4 ;isolate starting bit # beq 70$ 60$: asl r0 ;left a bit rol r1 ;into r1 dec r4 ;count bits until we're lined up bne 60$ 70$: ; now XOR r0, r1 into (r5), 2(r5) mov (r5),r3 ;get a copy bic r0,(r5) ;clear bits that are set in both (AND NOT AND) bic r3,r0 bis r0,(r5)+ ;and OR in whatever's left mov (r5),r3 ;same for second word bic r1,(r5) bic r3,r1 bis r1,(r5) mov (sp)+,r3 ;that was fun, restore registers mov (sp)+,r4 mov rkba(r2),r5 ;get new bus addr mov r5,r0 ;make a copy sub (sp)+,r0 ;find # bytes already read (C=0) ror r0 ;make that words swab r0 ;convert to block count add r0,r3 ;update starting block sub r0,r4 ;subtract from count bne read ;continue where we left off, re-init retries rti 80$: ; should try offsets if DCK+ECH, otherwise just recal+retry mov rkdrvt,(r2) ;get drive type bit bis #rkrcl!rkgo,(r2) ;send recal command 90$: bit #rkerr!rkrdy,(r2) ;spin until some response beq 90$ dec retry ;time to give up? bne 10$ ;no bpt ;yes ; .end boot