; file : sboot.40.1.text
; last modified 01/25/84

        page

;
;
; MessOut - Output a message on the Display
;
; Parameters: A4.L - Address of string message
;
; Scratches: A4
;
;
MessOut movem.l a0-a1,-(sp)     ;save register
        move.l  CPdsputs.l,a1   ;get address of output string vector
        move.l  a4,a0           ;copy address of string buffer
        jsr     (a1)            ;jump to subroutine
        movem.l (sp)+,a0-a1     ;restore registers
        rts
;
;
; TTyOut  - Output a message on the TTY device
;
; Parameters: A4.L - Address of string message
;
; Scratches: A4
;
;
TtyOut  move.l  d0,-(sp)        ;Store registers
        move.b  (a4)+,d0        ;Fetch string length
TTYloop btst    #WrBit,UARTst.l ;Is UART output busy?
        boff.s  TTYloop         ;Yes. Try again
        move.b  (a4)+,UARTda.l  ;Output the character
        subq.b  #1,d0           ;More to write?
        bne.s   TTYloop         ;Yes. Go do it.
        move.l  (sp)+,d0        ;Restore register
        rts                     ;No. Return

        page
; DSKRD
;
; Parameters:   A0.L - Address of buffer
;               D0.L - Block Number
;               D2.L - Count
;
; Returns: D7.W = ioresult
;          ne = error
;          eq = good
;
DSKRD   movem.l a0-a4/d0-d6,-(sp);Save registers
        move.l  CPblkio.w,a4    ;Get pointer to block i/o subr
        move.b  bootdrv,d1      ;Get drive number
        moveq   #$32,d5         ;Get "read" command
        move.b  bootsrv,d6      ;Get boot disk server number
        lsl.w   #8,d6           ;*
        move.b  bootslt,d6      ;Get boot slot number
        move.w  #4,d4           ;retry count               *4.0

DR1     subi.l  #512,d2         ;Are there more whole blocks?
        blt.s   DR2             ;No. See if any partial blocks
DR1a    move.l  d4,-(sp)
        jsr     (a4)            ;Read block -- updates A0 and D0
        move.l  (sp)+,d4
        tst.w   d7
        bpl.s   DR1             ;no error, Process next block *3.6
        cmpi.b  #NoSocket, d7   ;uninited socket send err?    *3.6
        bne.s   DSKerr          ;no, then exit                *3.6
        bsr.s   DRretry         ;see if should retry          *3.6
        bne.s   DR1a            ;yes                          *3.6
        bra.s   DSKerr          ;no, error exit               *3.6
                                ;
DR2     addi.w  #512,d2         ;D2 = bytes to read
        beq.s   DSKdone         ;
        move.l  a0,a3           ;Save buffer pointer
        movea.l #$91000,a0      ;Get pointer to temp buffer
                                ;(OMNINET can't access below $80000)
DR2a    jsr     (a4)            ;Read a whole block
        bpl.s   DR2b            ;no error, move data          *3.6
        cmpi.b  #NoSocket, d7   ;uninited socket send err?    *3.6
        bne.s   DSKerr          ;no, then exit                *3.6
        bsr.s   DRretry         ;see if should retry          *3.6
        bne.s   DR2a            ;yes                          *3.6
DSKerr  moveq   #4,d7           ;Set IORESULT to 4            *3.6
        bra.s   DSKrtrn         ;Return                       *3.6
                                ;
DR2b    movea.l #$91000,a0      ;Get pointer to temp buffer
        subq.w  #1,d2           ;Set up DBRA inst
DR3     move.b  (a0)+,(a3)+     ;Copy byte to real dest
        dbra    d2,DR3          ;  and loop
DSKdone clr.l   d7              ;OK. Clear IORESULT
                                ;
DSKrtrn movem.l (sp)+,a0-a4/d0-d6;Restore registers
        tst.w   d7              ;set cc
        rts                     ;Return

;added for version 3.6
;DRretry - prepare for disk read retry and check if no more retries
;
DRretry subq.l  #1,d0           ;get back block number
        suba.w  #512, a0        ;get back address (blocksize)
        subq.l  #1, d4          ;more retries?
        beq.s   DRRexit         ;ran out exit
        move.b  CPtprnbr.w, d7  ;wait by transporter number
        lsl.w   #8, d7          ; times 512
        lsl.w   #1, d7
DRR010  dbra    d7, DRR010      ;everybody waits different time length
DRRexit tst.w   d4              ;show error codes
        rts


;added for version 3.6
;
; Valid8B8 - validate the Drive.Info table read from block 8
;
; Parameters: (A0) = pointer to drive.info table
;
; Returns   : (NE) = invalid
;             (EQ) = good table
;             (A0) = unchanged
;
; Scratches : D7
;
Valid8B8 CMPI.B    #1, DIdrvinit(A0)        ;boolean must = 1
         BNE.S     V8badEx                  ;no, table invalid
         CMPI.B    #1, DIonline(A0)         ;boolean must = 1
         BNE.S     V8badEx                  ;no, table invalid
         CMPI.W    #1982, DIspecial(A0)     ;word must = 1982
         BNE.S     V8badEx                  ;no, table invalid

; Drive number must be in the range of 1 to DrMax - 1
;
         CMPI.W    #1, DIdrvnmbr(A0)        ;greater than or equal 1
         BLT.S     V8badEx                  ;no, table invalid
         CMPI.W    #DrMax, DIdrvnmbr(A0)    ;less than DrMax
         BGE.S     V8badEx                  ;no, table invalid

; Table valid
;
         CLR.L     D7                       ;make cc = EQ
         BRA.S     V8exit

; Table invalid
;
V8badEx  MOVEQ     #-1, D7                  ;make cc = NE
V8exit   RTS

        page

;
;
;       write boot error codes
;
;
Berr2   lea     mess2,a4        ;
        bra.s   BootErr         ;Print message and halt.
Berr3   lea     mess3,a4        ;
        bra.s   BootErr         ;Print message and halt.
Berr4   lea     mess4,a4        ;
        bra.s   BootErr         ;Print message and halt.
Berr5   lea     mess5,a4        ;
                                ;
BootErr bsr     MessOut         ;
        trap    #15
        data.w  0
;
c2cvadr data.l  0               ;Corvus volume address
;
;
;       Initial boot stage error messages
;
;
mess2   data.b  'DRIVE.INFO read error.   ',CR,LF,0
mess3   data.b  'CORVUS VOLUME read error.',CR,LF,0
mess4   data.b  'Boot block 1 read error. ',CR,LF,0
mess5   data.b  'Invalid DRIVE.INFO table.',CR,LF,0
        data.w  0

        page
;
; START of secondary boot sequence
;
;
start   move.w  #$2700,sr           ;Disable interrupts
        lea     ptrs,a0             ;Get pointer to memory pointers
        move.l  #$C0000,d6          ;last addr + 1 of 256K system          *kb 1/23/84 4.0*
        move.l  d0,LODATA-ptrs(a0)  ;Save low data pointer
        addi.l  #$10000,d0          ;Compute data area size
        cmp.l   d6,d1               ; if 512K then data area = $2000 bytes *kb 1/23/84 4.0*
        blt.s   start1              ; if 256K then data area = $1000 bytes
        addi.l  #$10000,d0
        cmp.l   d6,d0               ; if locode not at or above $C0000     *kb 1/23/84 4.0*
        bge.s   start1              ;                                      *kb 1/23/84 4.0*
        move.l  d6,d0               ; then set locode and hidata to $C0000 *kb 1/23/84 4.0*
start1  move.l  d0,HIDATA-ptrs(a0)  ;Save high data pointer
        move.l  d0,LOCODE-ptrs(a0)  ;Save low code pointer
        move.l  d1,HICODE-ptrs(a0)  ;Save high code pointer
        move.b  d4,bootsrv-ptrs(a0) ;Save boot server number
        lsr.w   #8,d4               ;Save boot slot number
        move.b  d4,bootslt-ptrs(a0)
        move.b  CPextcrt.w,extcrt-ptrs(a0)  ;Save external CRT flag
;
; read drive info block from drive
; drive.info block is located at the block
; identified by the symbol 'DIOFSET
;
        lea     DirBuf,a0       ;Get pointer to input buffer
        moveq   #DiOfset,d0     ;Get Drive.Info block on drive
        move.l  #512,d2         ;Get Drive.Info block length
                                ;
        bsr     DskRd           ;Read Drive.Info block from drive
        bne     BErr2           ;Read failed, output error message
        bsr     Valid8B8        ;validate drive.info table
        bne     BErr5           ;bad, output error message
;
; get the address of the CORVUS volume from the
; DRIVE.INFO block on this drive. Use this location
; to read in the cold boot table located on rel. blocks
; 6 and 7 of the CORVUS volume
;
        lea     DirBuf,a0       ;Get pointer to input buffer
        move.l  #512,d2         ;Get disk block length
        move.l  CrvOfst(a0),d0  ;Get address of Corvus volume in D0
        move.l  d0,d1           ;Save addres of Corvus volume
        lea     c2cvadr,a3      ;Save address of Corvus volume in memory
        move.l  d0,(a3)         ;
        addq.l  #6,d0           ;Offset the corvus volume address by 6 to
                                ;obtain the cold boot table blocks which are always
                                ;located in the first file of the corvus volume
        bsr     DskRd           ;Read Cold boot table block from disk drive
        bne     BErr3           ;Read failed, output error message
        lea     DirBuf,a0       ;get address of cold boot block read from Corvus volume
        clr.l   d0              ;make sure hi word is clear  *4.0
        move.w  23*2(a0),d0     ;the first boot file block index is at offset 23 *4.0
        add.l   d1,d0           ;absolute block addr = CVRS volume addr + index
    page
;
;       Now read in the approapriate boot file blocks
;       Since the boot command was used to readin the first two
;       blocks of the boot code, these blocks must be skiped and the
;       rest of the boot code readin and branched to.
;
;       a0   -  address of first block of the boot file
;       d0   -  first block on drive containing boot file ( must
;               be offset by two)
;
;
rdboot  addq.l  #2,d0           ;offset block address by two to compensate
                                ;for the 2 blocks read in by the boot cmd
        move.l  #Nobtblk-2,d1   ;d1 contains number of additional boot blocks
        move.l  #512,d2         ;length of block is 512 bytes

        lea     ConBoot+1024-12, a0    ;boot rom loaded first 2 blocks which
                                       ;also includes 12 bytes of header
;
; this loop reads in the remaining blocks from the boot file
; area of the disk...
;
;
rdloop  bsr     DskRd           ;Read fist boot file block
        bne     BErr4           ;Read failed, output error message
        adda.w  #512,a0         ;increment buffer address
        addq.l  #1,d0           ;increment boot block address
        subq.l  #1,d1           ;decrement no. of boot blocks remaining
        bne.s   rdloop          ;loop back to read next block
