           ttl     SBC Floppy Disk Bootstrap

*
.   disk bootstrap program
.
loadscsi   proc

bootsec    equ     1                   sector number of ipl record
retries    equ     8                   set max number of retries
seclen     equ     512                 disk sector length
bootadr    equ     userseg<<12         logical bootstrap address
*
.   SBC drive select latch definitions
.
via29      equ     $E8A0               VIA containing drive sel, etc
ORB        equ     via29+0             output register B
ORA        equ     via29+1             output register A
DDRB       equ     via29+2             data dir reg A side
DDRA       equ     via29+3             data dir reg B side
PCR        equ     via29+12            periph control register
IFR        equ     via29+13            interrupt flag register
IER        equ     via29+14            interrupt enable register

*
.   rom based definitions for use by the internal boot and disk boot
.
SCSIdrvr   equ     *
           fdb     scsirst             controller reset
           fdb     sendscsi            command handler
           fdb     SCSIcmd+8           command pointer
           fdb     bootadr             address of boot
SCSIrom    fcb     $80                 controller address
           fcb     0
           fdb     SCSIcmd+8           24 bit address of command
           fcb     0
           fdb     bootadr             24 bit address of buffer
           fcb     0
           fcb     8,2<<5,0,1,1,0
           fcb     $c0,2<<5,0,0,$10,$8A define floppy drive
           fcb     $c2,2<<5,0,0,0,0
           fcb     0,3,$4c,$0f,0,0,0,$80,$80,0

adpcmd     fcb     $80,0
           fdb     ADPcmd+8
           fcb     0
           fdb     ADPcmd+8+6
           fcb     0
           fcb     $c2,2<<5,0,0,0,0
           fcb     4,0,0,5
           fdb     648,0,0
CMDlen     equ     *-SCSIrom
*
.   above adpcmd bytes are relocated to ADPcmd area
SCSIread   equ     SCSIcmd+8
SCSIdeffd  equ     SCSIread+6
SCSIadpfd  equ     SCSIdeffd+6
ADPcmd     equ     SCSIadpfd+10+6
ADPlun     equ     ADPcmd+9
ADPfcyl    equ     ADPcmd+18
ADPfhds    equ     ADPcmd+17

dcncyl     equ     0
dcnhds     equ     2
sdenf      equ     $3a                 density flag
ssidf      equ     $3B                 0-single sided,1-double,$ff-winny
swinc      equ     $42
*
.   reset the stack and set up direct addressing
.
loadipl:   scc     irq,firq            disable interrupts in boot *
           sta     SCSIerr
*
.   set up scsi board
.
           bsr     scsirst             reset and initialize the SCSI
           ldx     #SCSIrom
           ldy     #SCSIcmd            point at static command buffer
           ldb     #CMDlen
movcmd     lda     0,x+                14 bytes of required stuff
           sta     0,y+
           decb
           bne     movcmd
*
.   default out to assigning lun 2 as FD-DD
.
           ldx     #SCSIcmd
           ldd     #SCSIdeffd          DEFINE FLOPPY
           std     2,x                set command pointer
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1f
           bne     loadxit
           ldx     #SCSIcmd
           ldd     #SCSIadpfd          ASSIGN DISK PARMS (fd-dd+)
           std     2,x                set command pointer
           addd    #6
           std     5,x                set data pointer
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1f
           bne     loadxit
*
.   get the drive number to boot
.
           lda     SCSIerr             check for generic or implied boot
           bpl     dok                 if implied boot, skip
           bsr     gethex
           cmpa    #2                  check for max drive number
           bls     dok
*
.   invalid drive number
.
           pshs    a
           ldx     #baddrv             tell him
           bsr     pdata
           puls    a
           ccc     z
           rts
baddrv     fcb     ".  Invalid drive number: ",etx
*
.   drive number in a
.
dok        lsla;lsla;lsla;lsla;lsla    shift a<<5
           sta     SCSIcmd+9           save the logical unit
           cmpa    #2<<5               0-1 winny, 2-3 floppy (?)
           blo     iswinny
*
.   attempt to read sir block, and then use head count to
.   figure double or single sided disks
.
           ldx     #SCSIcmd
           ldd     #bootadr
           std     5,x                set data to boot buffer address
           ldd     #SCSIcmd+8          READ DISK
           std     2,x                set command pointer
           lda     #1
           sta     11,x                SIR block
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1F
           beq     chksides            check how many sides
*
.   change density here
.

*
.   check sir info for number of sides.
.
chksides   clr     11,x                say block zero
           lda     bootadr+ssidf       get flag
           bmi     iswinny           NOT a FLOPPY??? try winny
           beq     side0
           cmpa    #$13
           bne     loadxit
           anda    #$01                save only d0 for sides
*   *****CHANGE #$8A to density drive type for single or doble sided
side0      ora     #$8A                set for single or double sided
           sta     SCSIdeffd+5         say single or double sided
           ldx     #SCSIcmd
           ldd     #SCSIdeffd          DEFINE FLOPPY
           std     2,x                set command pointer
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1f
           bne     loadxit
           ldx     #SCSIcmd
           ldd     #SCSIadpfd          ASSIGN DISK PARMS (fd-dd+)
           std     2,x                set command pointer
           addd    #6
           std     5,x                set data pointer
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1f
           bne     loadxit
           bra     getboot
*
.   is a winchester drive, must get sir block and get device description
.
iswinny    ldx     #SCSIcmd
           ldd     #SCSIcmd+8
           std     2,x
           ldd     #bootadr
           std     5,x
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1f
           bne     loadxit             show croak
           ldx     #bootadr+swinc      get offset to device charac.
           ldd     dcncyl,x
           subd    #1
           std     ADPfcyl         set drive characteristics
           lda     dcnhds,x
           deca
           sta     ADPfhds
*   precomp....stuff must be added here for this drive
           lda     SCSIcmd+9
           sta     ADPcmd+9            save lun
           ldx     #ADPcmd
           bsr     sendscsi            go send adp command
           lda     7,x
           anda    #$1f
           bne     loadxit
*
.   now perform actual boot process
.
getboot    ldx     #SCSIcmd
           ldd     #bootadr
           std     5,x                set data to boot buffer address
           ldd     #SCSIcmd+8          READ DISK
           std     2,x                set command pointer
           clr     11,x                say block zero
           bsr     sendscsi
           lda     7,x                 get return status from guy
           anda    #$1F
           beq     booted
*
.   go here if the load failed
.
loadxit    ldx     #SCSIcmd
           lda     [2,x]
           sta     SCSIerr             save failed command
           ldd     #bootadr
           std     5,x                 set data to boot buffer address
           ldd     #SCSIcmd+8          READ DISK
           std     2,x                 set command pointer
           lda     #$03                REQUEST SENSE
           sta     SCSIcmd+8           set command number in here
           bsr     sendscsi
           lda     7,x                 get return status from guy
           cmpa    SCSIcmd+9           check for ok status
           bne     disaster            DISASTER
           ldx     #=(".  Internal Boot Failed, command: ",etx)
           bsr     pdata
           ldx     #SCSIcmd            point at block
           lda     SCSIerr             get saved command
           bsr     hexbyte             show command code that failed
           ldx     #=(", error: ",etx)
           bsr     pdata
           ldb     #$7F
           stb     IFR                 clear any pending stat in IFR
           lda     [SCSIcmd+5]         get first byte of returned sense
           ccc     z                   indicate load has failed
           rts
*
.   disaster error, got an error while checking out prior error
.
disaster   pshs    a                   save completion status
           ldx     #=(".  Internal Boot Disaster, completion status: ",etx)
           bsr     pdata
           puls    a                   restore completion status
           ccc     z
           rts

*
.   boot complete, set up stuff and exit
.
booted     ldx     #SCSIdrvr           load bootstrap address block pointer
           lda     [6,x]               pick up first byte of bootstrap
           cmpa    #$16                check for long branch instr
           beq     bexit               if ok, out with EQUAL
           ldx     #=(". Invalid Boot Block ",etx)
           bsr     pdata               TELL HIM BAD BOOT BLOCK
           lda     [SCSIdrvr+6]        get first byte of boot again
           cmpa    #$16                check for long branch instr
bexit      rts                         EQUAL, good boot, NE bad boot

           end
