;+ ; ; 8" floppy boot device driver. ; ; By John Wilson. This file is hereby released into the public domain. ; ; Works with the following: ; RX11,RX01 ; RX211,RX02 (supports DS disks) ; RXT11,RX01 (PDT-11/150) ; ; 11/13/95 JMBW Created. ; 01/19/96 JMBW Fixed PDT-11/150 support. ; ;- rxcs= 0 ;(777170) control/status rxdb= 2 ;(777172) data buffer (function specific) pdsa= 4 ;(777174) track,,sector on PDT-11/150 only ; rxrtry= 5 ;max retry count ; rxerr= 100000 ;error bit rxini= 40000 ;control reset rx211= 4000 ;RX211 controller (vs. RX11) rxhs= 1000 ;head select rxdd= 400 ;double density select rxtr= 200 ;transfer request pddone= 200 ;PDT-11/150 uses bit 7 for DONE rxdone= 40 ;finished previous func rxus= 20 ;unit select ; rxemp= 1*2 ;empty buffer rxrds= 3*2 ;read sector rxgst= 5*2 ;get status register ; rxgo= 1 ;GO bit ; .btini ;assume PDT-11/150 until trap .enabl lsb ; start by sensing disk type (SS/DS, SD/DD) mov bcsr,r0 ;point at CSR mov (r0),r1 ;get it (assume DONE, since we got read) bic #^Crxus,r1 ;isolate unit # mov r1,(pc)+ ;save rxunit: .blkw ;unit #, 0 or RXUS cmp #0,r1 ;C=1 if unit #1 adc bunit ;unit=1 if so mov #nopdt,@#4 ;set up our own bus timeout handler tst pdsa(r0) ;look for PDT-11/150 sector addr reg mov #6,@#4 ;restore bit #rx211,(r0) ;is it an RX211? beq 10$ ;no, RX11 or PDT-11/150, must be SS SD incb bdev+1 ;change DX to DY mov (r0),r1 ;read CSR (again, assume DONE is set) bic #^Crxdd,r1 ;isolate density bit mov r1,(pc)+ ;save rxden: .word 0 ;density, 0 or RXDD beq 10$ ;skip if clear asl rxws ;double # words/sector 10$: .dsabl lsb ;end of symbol block .btfin ;+ ; ; RX11/RX211/PDT11 bootstrap read driver. ; ; r5 memory addr ; r4 block count ; r3 starting block ; ;- read: .enabl lsb ; compute starting sector, sector count asl r3 ;2 sectors per block if double density asl r4 tst rxden ;right? bne 10$ asl r3 ;single, 4 secs/block asl r4 10$: mov r3,(pc)+ ;save starting sector rxlsn: .blkw ;logical sector number, 0 to <76.*26.*2> mov r4,(pc)+ ;sector count rxctr: .blkw ;# of sectors left to do mov r5,(pc)+ ;init mem ptr rxptr: .blkw ;memory addr for next sector call intrlv ;figure out interleave 20$: ; fetch next sector (r0=track, r1=sector, r2=side) movb #rxrtry,(pc)+ ;init retry count retry: .blkw 30$: mov bcsr,r5 ;point at CSR mov #rxrds!rxgo,r4 ;read command bis rxunit,r4 ;set unit select tstb rxpdt ;PDT-11/150? bne 80$ ;yes, special (and can't have DS or DD) bis rxden,r4 ;get density bis r2,r4 ;and head mov r4,(r5) ;write the command 40$: bit #rxerr!rxtr,(r5) ;poll beq 40$ bmi 60$ ;error mov r1,rxdb(r5) ;write sector # 50$: bit #rxerr!rxtr,(r5) ;poll beq 50$ bmi 60$ ;error mov r0,rxdb(r5) ;write track # br 90$ 60$: ; error handler mov #rxini,(r5) ;reinit controller 70$: bit (pc)+,(r5) ;wait until ready done: .word rxerr!pddone ;PDDONE is changed to RXDONE if not PDT beq 70$ mov rxlsn,r3 ;restore curr sec call intrlv dec retry ;done all tries? bne 30$ bpt ;yes, bomb 80$: ; PDT-11/150 is special case, has a register for track/sector swab r0 ;track in LH bisb r1,r0 ;sector in RH mov r0,pdsa(r5) ;set sector addr mov r4,(r5) ;send command 90$: ; while we're waiting, calculate next sector # mov rxlsn,r3 ;get curr sector inc r3 ;+1 call intrlv ;update r0-r2 100$: bit done,(r5) ;poll beq 100$ bmi 60$ ;error ; got the sector OK, now transfer it to memory mov #rxemp!rxgo,(r5) ;empty silo mov rxptr,r4 ;get memory ptr mov (pc)+,r3 ;and word count rxws: .word 64. ;# words/sector (64. or 128.) tstb rxpdt ;PDT-11/150? bne 140$ ;yes bit #rx211,(r5) ;is it an RX211? bne 120$ ;yes ; RX11, use programmed I/O asl r3 ;make it a byte count 110$: tstb (r5) ;wait for TR bpl 110$ movb rxdb(r5),(r4)+ ;save a byte dec r3 ;loop through whole sector bne 110$ br 150$ 120$: ; RX211, use DMA tstb (r5) ;wait for TR bpl 120$ mov r3,rxdb(r5) ;write positive word count 130$: tstb (r5) ;wait for TR bpl 130$ mov r4,rxdb(r5) ;write bus addr br 150$ ;go await completion 140$: ; PDT-11/150, use programmed I/O (different from RX11) mov rxdb(r5),(r4)+ ;8085A takes all the time it needs dec r3 ;so nothing to poll bne 140$ ;(PDT has SOB, but what the heck) 150$: bit done,(r5) ;wait until done beq 150$ bmi 60$ ;error ; success, update core addr mov rxws,r3 ;get words/sector asl r3 ;*2 = byte count add r3,rxptr ;update pointer inc rxlsn ;already calc'ed new r0-r2, update LSN dec rxctr ;done all? bne 20$ rti .dsabl lsb ;+ ; ; Calculate sector loc according to interleave. ; ; r3 absolute sector number (starting at 0) ; ; On return: ; r0 track ; r1 sec ; r2 head ; ; ISEC=(ISEC-1)*2 ; IF(ISEC.GE.26) ISEC=ISEC-25 ; ISEC=MOD(ISEC+ITRK*6,26)+1 ; ITRK=ITRK+1 ; ; On DS disks, the whole mess starts over on side 1 after side 0 track 76. ; ;- intrlv: mov #-1.,r0 ;init track to -1 10$: inc r0 ;track +1 sub #26.,r3 ;subtract a track's worth of sectors bcc 10$ ;loop until it underflows add #13.,r3 ;partly undo last SUB rol r3 ;*2 (2:1 interleave), +1 if .GE. 13 add #13.*2,r3 ;finish undoing SUB clr r2 ;init head # cmp r0,#76. ;off side 0? blo 20$ mov #rxhs,r2 ;start over on side 1 sub #76.,r0 ;chop off side 0 20$: mov r0,r1 ;copy track asl r1 ;*2 add r0,r1 ;*3 asl r1 ;*6 (6-sector track-to-track skew) add r3,r1 ;add in sector 30$: sub #26.,r1 ;all of this is mod 26. bcc 30$ add #26.+1,r1 ;undo last SUB, start sectors at 1 inc r0 ;skip track 0 (dreaming of ANSI) rts pc ;+ ; ; Trap routine while checking for PDT-11/150 controller, must be RX11/RX211. ; ;- nopdt: clr (pc)+ ;177174 timed out rxpdt: .word 1 ;NZ if PDT-11/150 (not compatible with RX11) mov #"DX,bdev ;change device to DX: mov #rxerr!rxdone,done ;change which bit to poll for completion rti ; .end boot