; File: CC.PROM.LD.TEXT ; Date: 25-Jan-84 ; By: L. Franklin ; ; Lboot -- Local Corvus disk boot processing ; Lboot movea.l #CPsl1typ,a1 ;get pointer to slot 1 type moveq #1,d0 ;get initial slot number ; Lboot10 move.b -1(a1,d0),d1 ;get device type cmp.b #DTlocl,d1 ;is this a local disk interface? beq.s Lboot30 ;yes, use it for booting addq #1,d0 ;update slot number cmp.w #4,d0 ;have we looked at all slots? ble.s Lboot10 ;no, check next slot moveq #-1,d7 ;set error return code bra.s Lboot90 ;return (can not find local disk) ; Lboot30 move.b d0,CPbtslot.w ;set boot slot number clr.b CPbtsrvr.w ;set boot server number lea LDblkIO,a6 ;set boot disk blk i/o subr pointer move.l a6,CPblkio.w ;* lea LDdskIO,a6 ;set boot disk i/o subr pointer move.l a6,CPdskio.w ;* ; ; fall through to Lboot10 (used by OMNINET boot too) ; page ; ; Lboot80 -- Get 2 boot blocks from Corvus disk 0.8 ; (code shared by local disk boot and OMNINET disk boot) ; Entry : A6 = address of disk I/O routine 0.8 ; Exit : lt = error 0.8 ; ge = good 0.8 ; A0 = if good then address of entry to boot code 0.8 ; Lboot80 movea.l #USRbase,a0 ;get block buffer pointer move.b CPbtsrvr.w,d6 ;get boot server number blt.s Lboot90 ;just return if invalid server number lsl.w #8,d6 move.b CPbtslot.w,d6 ;get boot slot number ;setup boot command ;for Const II boot use Concept2 boot file - *kb 1/25/84 1.0 move.w #$4417,(a0) ;put in opcode & computer type 1.0 moveq #$01,d0 ;set boot block number 0.8 move.w #$203,d1 ;read 2nd block first bsr.s LDgetBB ;get next boot block blt.s Lboot90 ;just return if error moveq #$3,d1 ;read 1st block 2nd 0.8 bsr.s LDgetBB ;get next boot block blt.s Lboot90 ;just return if error adda.w #4+12,a0 ;get pointer to boot code 0.8 ; past cmd, rslt code and file header Lboot90 rts LDgetBB move.b d0,2(a0) ;set boot block number moveq #3,d2 ;get number of bytes to send moveq #DskWrit,d5 ;get "write" command jsr (a6) ;send command adda.w d1,a0 ;adr where to put boot code move.w #513,d2 ;get number of bytes to receive moveq #DskRead,d5 ;get "read" command jsr (a6) ;read results blt.s LDgetBX ;just return if error suba.w d1,a0 ;point back at command subq.l #1,d0 ;update boot block number 0.8 LDgetBX tst.b d7 rts ;return page ; ; LDblkIO - Read or write a local disk block subroutine ; ; Enter: A0.L - Buffer address ; D0.L - Block number 0.7 ; D1.W - Drive number ; D5.W - Read ($32) or Write ($33) command ; D6.B - Slot number ; ; Exit: A0.L - Next free location in buffer ; D0.L - Updated block number 0.7 ; D7.W - IORESULT (disk controller status) ; ; All other registers are preserved. ; ; Corvus controller status register [3(a1)]: ; ; bit 7: controller ready off - ready on - not ready ; bit 6: bus direction off - host to cntlr on - cntlr to host ; LDblkIO movem.l a1/d0-d2,-(sp) ;Save registers bsr SlotAdr ;A1 = I/O port address move.w d5,d2 ;Send a read ($32) or bsr.s LDsend1 ; write ($33) block command move.l d0,d2 ;Compute drive nmbr/MSN block nmbr 0.7 swap d2 ;* 0.7 lsl.w #4,d2 ;* 0.7 or.b d1,d2 ;* 0.7 bsr.s LDsend ;Send drive number move.w d0,d2 ; bsr.s LDsend ;Send LSB of block lsr.w #8,d2 ; bsr.s LDsend ;Send MSB of block cmpi.w #DskWrit,d5 ;Are we reading or writing? bne.s LDrio1 ;Reading ; ;Write block processing ; move.w #$1FF,d2 ;Block size - 1 LDwio1 btst #7,3(a1) ;Test controller status bon.s LDwio1 ;Wait until controller ready move.b (a0)+,1(a1) ;Send a byte dbra d2,LDwio1 ;Loop until done bsr.s LDwait ;Wait for line to turn move.b 1(a1),d7 ;Fetch result code bra.s LDrtrn ;Return page ; ;Read block processing ; LDrio1 bsr.s LDwait ;Wait for the line to turn move.b 1(a1),d7 ;Fetch result code ; LDrio3 btst #7,3(a1) ;Test controller status bon.s LDrio3 ;Wait until controller ready btst #6,3(a1) ;Test bus direction boff.s LDrtrn ;Finished if "host to controller" move.b 1(a1),(a0)+ ;Store next byte bra.s LDrio3 ;Go get any more ; LDrtrn movem.l (sp)+,a1/d0-d2 ;Restore registers addq.l #1,d0 ;Update block number 0.8 move.b d7,CPdiskRC.w ;Save current disk return code 0.7 ext.w d7 ;Set return condition code rts ;Return page ; ; LDsend -- Send a byte to the disk port subroutine ; ; Enter: A1.L - I/O port address ; D2.B - Byte to send ; ; All registers are preserved. ; LDsend btst #7,3(a1) ;Test controller status bon.s LDsend ;Wait until controller ready move.b d2,1(a1) ;Send the byte rts ;Return ; ; LDsend1 -- Send first byte to the disk port subroutine ; ; Enter: A1.L - I/O port address ; D2.B - Byte to send ; ; All registers are preserved. ; LDsend0 move.w (sp)+,sr ;enable interrupts nop ;leave some time for interrupt processing LDsend1 move.w sr,-(sp) ;save interrupt level ori.w #$0700,sr ;disable interrupts btst #7,3(a1) ;test controller status bon.s LDsend0 ;wait until controller ready move.b d2,1(a1) ;send first byte move.w (sp)+,sr ;enable interrupts rts ;return ; ; LDwait -- Wait for the line to turn subroutine ; ; Enter: A1.L - I/O port address ; LDwait move.l d0,-(sp) ;save register moveq #100,d0 ;wait a little bit LDwait1 dbra d0,LDwait1 ;* move.l (sp)+,d0 ;restore register bsr.s LDwait2 ;check two times in case of glitch nop ;* ; LDwait2 btst #7,3(a1) ;test controller status bon.s LDwait2 ;wait until controller ready btst #6,3(a1) ;test bus direction boff.s LDwait2 ;wait until "controller to host" rts ;return page ; ; LDdskIO - Read from/Write to Corvus disk ; ; Enter: A0.L - Buffer address ; D2.W - Count ; D5.W - Read ($32) or Write ($33) command ; D6.B - Slot number ; ; Exit: D7.W - IORESULT (disk controller status) ; ; All other registers are preserved. ; LDdskIO movem.l d0-d3/a0-a1,-(sp);Save registers bsr SlotAdr ;A1 = I/O port address move.w d2,d3 ;get count subq.w #1,d3 ;Set DBRA loop length cmpi.w #DskWrit,d5 ;Are we reading or writing? bne.s LDdsk2 ;Reading ; ; Write Corvus disk processing ; move.b (a0)+,d2 ;get first byte bsr.s LDsend1 ;send first byte bra.s LDdsk1a ;send rest of bytes LDdsk1 move.b (a0)+,d2 ;get next byte bsr LDsend ;send next byte LDdsk1a dbra d3,LDdsk1 ;loop until done moveq #0,d7 ;force successful result code bra.s LDdsk9 ;finished ; ; Read Corvus disk processing ; LDdsk2 bsr.s LDwait ;Wait for the line to turn move.b 1(a1),d7 ;Fetch result code move.b d7,(a0)+ ;Store first byte ; LDdsk3 btst #7,3(a1) ;Test controller status bon.s LDdsk3 ;Wait until controller ready btst #6,3(a1) ;Test bus direction boff.s LDdsk9 ;Finished if "host to controller" move.b 1(a1),(a0)+ ;Store next byte bra.s LDdsk3 ;Go get any more ; LDdsk9 movem.l (sp)+,d0-d3/a0-a1;Restore registers move.b d7,CPdiskRC.w ;Save current disk return code 0.7 ext.w d7 ;Set return condition code rts ;Return page ; ; LDsync -- Synchronize with Corvus disk controller ; ; Enter: D6.B - slot number ; ; Exit: D7.W - 0 = no timeout (EQ), -1 = timeout (NE) ; ; All other registers are preserved. ; LDsync movem.l d0/a1,-(sp) ;save registers bsr SlotAdr ;get slot address ; ---- move.w #2000,d7 ;set timeout counter 0.7 move.w #3000,d7 ;set timeout counter 0.7 ; LDsync1 move.b #$FF,1(a1) ;send invalid command to controller move.w #1024,d0 ;wait about 1 ms LDsync2 dbra d0,LDsync2 ;* btst #6,3(a1) ;test bus direction bon.s LDsync3 ;go on if "controller to host" dbra d7,LDsync1 ;send invalid command again bra.s LDsync5 ;set timeout error and return ; LDsync3 btst #7,3(a1) ;test controller status boff.s LDsync6 ;go on if controller ready dbra d7,LDsync3 ;check controller status again ; LDsync5 moveq #-1,d7 ;indicate controller timeout bra.s LDsync9 ;return ; LDsync6 cmpi.b #$8F,1(a1) ;did controller respond with error? bne.s LDsync1 ;no, send invalid command again moveq #0,d7 ;indicate no controller timeout ; LDsync9 movem.l (sp)+,d0/a1 ;restore registers tst.w d7 ;set return condition code rts ;return