;+
;
; RL11/RL01,RL02 boot device driver.
;
; By John Wilson. This file is hereby released into the public domain.
;
; 11/16/95 JMBW Created.
;
;-
rlcs= 0 ;(774400) control/status
rlba= 2 ;(774402) bus addr
rlda= 4 ;(774404) disk addr
rlmp= 6 ;(774406) multipurpose
;
rlrtry= 5 ;max retry count
;
rlerr= 100000 ;composite error
;
rlrdy= 200 ;ready
;
rlgst= 2*2 ;get status
rlsek= 3*2 ;seek
rlrdh= 4*2 ;read header
rlrdd= 6*2 ;read data
;
rldry= 1 ;drive ready
;
.btini
;RL11 init code
mov bcsr,r0 ;get base CSR
movb 1(r0),r1 ;get unit #
bic #^C3,r1 ;isolate
mov r1,bunit ;save
call getpos ;update RLPOS
.btfin ;finish up boot process
;+
;
; RL11/RL01,RL02 bootstrap read driver.
;
; r5 memory addr
; r4 block count
; r3 starting block
;
;-
read: mov #rlrtry,(pc)+ ;init retry count
retry: .blkw ;retry count
10$: ; compute starting sector addr
mov r3,r1 ;copy block #
mov #-64.,r0 ;init track to 0
20$: add #64.,r0 ;count the track
sub #20.,r1 ;bite off a track
bcc 20$ ;loop until we get there
add #20.,r1 ;undo last SUB
; r0=track, r1=sector -- seek if needed
cmp r0,rlpos ;same as curr head posn?
beq 50$ ;yes
mov rlpos,r2 ;get old posn
mov r0,rlpos ;save new posn
mov r3,-(sp) ;save
mov r0,r3 ;copy
ror r0 ;move HS into bit 4
ror r0
bic #^C20,r0 ;isolate
bic #100,r2 ;remove HS bits
bic #100,r3
sub r3,r2 ;assume moving heads out
bcc 30$ ;right
neg r2 ;wrong, take abs val (overflow works out OK)
bis #4,r0 ;set DIR bit
30$: bis r2,r0 ;get cylinder delta
inc r0 ;bits <1:0>=01 for "seek" cmd
mov bcsr,r2 ;get CSR
mov r0,rlda(r2) ;write cyl/head to disk addr register
mov bunit,r3 ;get unit
swab r3 ;in high half
bis #rlsek,r3 ;cmd=SEEK
mov r3,(r2) ;send cmd
mov (sp)+,r3 ;restore
40$: mov (r2),r0 ;poll CSR
bmi 80$ ;error
bic #^C,r0 ;isolate control ready and drive ready
cmp r0,#rlrdy!rldry ;both set?
bne 40$ ;wait until so
50$: ; drive is on-track, get on with the read, r1=starting sector #
; RL01/02 can't do spiral reads so we can only go till end of track
mov #20.,r0 ;# blocks per track
sub r1,r0 ;find # left on track
cmp r0,r4 ;do we have at least that many to do?
blo 60$
mov r4,r0 ;no, stop early
60$: mov bcsr,r2 ;point at CSR
add #rlmp,r2 ;point at MP reg
swab r0 ;convert blk count to WC
neg r0 ;negative WC
mov r0,(r2) ;write to multipurpose reg
asl r1 ;convert blk # to starting sec # (0-39.)
bis rlpos,r1 ;get cyl/head bits too
mov r1,-(r2) ;write to disk addr reg
mov r5,-(r2) ;write bus addr reg
mov bunit,r1 ;get unit
swab r1 ;in LH
bis #rlrdd,r1 ;cmd=read data
mov r1,-(r2) ;write to CSR
70$: bit #rlerr!rlrdy,(r2) ;poll
bmi 80$ ;error
beq 70$
; success, prepare for next track
neg r0 ;absolute WC
add r0,r5 ;update BA
add r0,r5
swab r0 ;convert WC to block count
add r0,r3 ;bump starting block
sub r0,r4 ;subtract from total
bne read
rti
80$: ; error
call getpos ;clear errors, double-check position
dec retry ;time to give up?
bne 10$ ;no
bpt ;yes
;+
;
; Clear errors, read a disk header to find out our cyl/head location.
;
; r3-r5 preserved
;
;-
getpos: mov #rlrtry,r2 ;init counter
mov bcsr,r1 ;get CSR addr
10$: mov #13,rlda(r1) ;reset error bits (if set)
mov bunit,r0 ;save
swab r0 ;back in LH
bis #rlgst,r0 ;get status
mov r0,(r1) ;send cmd
20$: bit #rlerr!rlrdy,(r1) ;wait until ready
bmi 40$
beq 20$
add #rlrdh-rlgst,r0 ;change cmd to "read header"
mov r0,(r1) ;send cmd
30$: bit #rlerr!rlrdy,(r1) ;wait until ready
beq 30$
bpl 50$
40$: dec r2 ;give up yet?
bne 10$ ;no
bpt ;failed
50$: mov rlmp(r1),r0 ;fetch header word
bic #37,r0 ;remove sector
mov r0,(pc)+ ;save
rlpos: .blkw ;current cyl/head
cmp rlmp(r1),rlmp(r1) ;flush out FIFO (is this needed?)
rts pc
;
.end boot