           ttl     SCSI INTERFACE PROTOCOL DRIVERS
           proc
           lib     klscsi
*
.   Support for the low level protocol to the
.   OMTI 5x00 SCSI Controller Boards
.
.
*
.   Several Phases occur on the SCSI Bus for each command
.
.   0) Bus Free Phase
.   1) Selection Phase
.   2) Command Phase
.   3) Data In/Out Phase
.   4) Status Phase
.   5) Message In Phase
.
.
*
.   Initialize SCSI Bus
.
scsirst:   pshs    a                   save regs
           lda     #%11001110          CB2 low out, CA2 HIGH out
           sta     PCR                 set control lines
           lda     #HIGH               OUTPUT
           sta     DDRDATA             set ddr for data side
           lda     #%00000111          PB0-PB2 are output,rest input
           sta     DDRSTAT
           lda     #RST                RESET THE CONTROLLER
           sta     STATUS              write RST bit to scsi
           ldb     #10               .
rstwait    decb                       . delay at least 25 microsecs
           bne     rstwait           .
           lda     STATUS              get back bits
           anda    #~RST               clear RST bit
           sta     STATUS              clear reset for bus free
           ldb     #200              .
rstwait1   decb                       . delay a while (.5 millises)
           bne     rstwait1          .
           ret     a                   restore and return
*
.   Check for Bus Free Phase
.   Returns not equal if BUSY, equal if BUS FREE
.
chkfree:   pshs    a
           lda     STATUS              get status line
           bita    #BSY                check for busy
           ret     a
*
.   Select SCSI Controller number <a>
.
selscsi:   pshs    d                   save regs
           ldb     PCR
           andb    #%00010001          strip CB2 Bits
           orb     #%11001110          say LOW CB2 and HIGH CA2
           stb     PCR
           ldb     #HIGH
           stb     DDRDATA             set A side to output
selwait    ldb     STATUS              get STATUS lines
           bitb    #BSY+IO+CD+MSG+REQ  check for doing anything
           bne     selwait             wait for all deasserted
           sta     DATA                set controller address on A side
           lda     STATUS              get original status
           ora     #SEL                "SELECT"
           sta     STATUS              tell SCSI
.   wait roughly 18 microseconds here till BSY comes active
waitbsy    bsr     chkfree             wait for not free
           beq     waitbsy             wait till busy
           lda     #HIGH               set data lines high
           sta     DATA                on open collector A side
           lda     STATUS              get original status
           anda    #~SEL               turn off select
           sta     STATUS              save it
.   must now set up for REQ/ACK protocol by using CA2 for auto-ACK
           lda     PCR                 point at PCR register
           anda    #$F1                strip CA2 bits
           ora     #%00001010          say CA2 PULSE output handshake
           sta     PCR                 let rest be ACK method
           ret     d
*
.   deselect SCSI bus (really, just shut off auto handshake)
.
descsi:    lda     PCR                 point at PCR register
           anda    #$F1                strip CA2 bits
           ora     #%00001110          say CA2 LOW output
           sta     PCR                 shut off auto ACKs
           ret     a
*
.   send byte across to the SCSI guy
.
sendbyte:  pshs    b                   save regs
waitout    ldb     STATUS              get status
           bpl     waitout             not SCSI want's byte
           bitb    #IO
           bne     badrcv
           sta     DATA                go stuff byte, include the auto ACK
           clc
           ret     b
*
.   get byte across from the SCSI guy
.
rcvbyte:   pshs    b                   save regs
waitin     ldb     STATUS              get status
           bpl     waitin              not SCSI want's byte
           bitb    #IO
           beq     badrcv
           lda     DATA                go get byte, include the auto ACK
           clc
           ret     b
badrcv     sec
           ret     b
*
.   check for Input or Output  (equal if OUTPUT, not equal if INPUT)
.
chkio:     pshs    a                   save regs
ckio       lda     STATUS              get status
           bpl     ckio
           bita    #IO                 check for IN or OUT
           ret     a                   restore and return
*
.   check for Control or Data (equal if CONTROL, not equal if DATA)
.
chkcd:     pshs    a                   save regs
ckcd       lda     STATUS              get status
           bpl     ckcd
           bita    #CD                 check for CONTROL or DATA
           ret     a                   restore and return
*
.   check for Message or Information (equal if INFO, not equal if MESSAGE)
.
chkmsg:    pshs    a                   save regs
ckmsg      lda     STATUS              get status
           bpl     ckmsg
           bita    #MSG                check for Message
           ret     a                   restore and return
*
.   send complete command out to SCSI board
.
.   1--select BUS
.   2--send Command
.   3--transfer data
.   4--get status byte
.   5--get message byte
.   6--deselect BUS
.
.   X -- points at rmsbug command block
.
.   command block:
.     0,x -- scsi controller number    (1-7)
.     1,x -- scsi command descriptor address
.     4,x -- memory buffer address     (24 bit address)
.     7,x -- return status
.
sendscsi:  proc                        internal proc for clarity
           pshs    b,x,y,u             save regs
           lda     0,x                 get controller number
           bsr     selscsi             go select scsi bus
           ldy     2,x                 point at scsi cmd descriptor
scmd       ldb     STATUS              get STATUS bits
           bpl     scmd                wait for REQ
           bitb    #CD                 COMMAND or DATA?
           beq     notcmd              if data, skip out
           bitb    #IO                 check for direction of command bytes
           bne     getstatus           if returning status, skip out
           lda     0,y+                get command byte
           sta     DATA                get data
           bra     scmd
*
.   controller says we are all done with command bytes
.   move text now!
.
notcmd
           ldy     5,x                 point at memory buffer
           bsr     moveit              go move data
*
.   controller is giving us a status byte.
.
getstatus  lda     #LOW
           sta     DDRDATA             insure direction ok
           bsr     rcvbyte
           bcs     badstat
           sta     7,x                 save completion status byte
getmsg     bsr     rcvbyte             go get last message in byte
           bcs     badmsg
           sta     8,x
           clc
           ret     b,x,y,u
badstat    ldb     #HIGH
           stb     7,x
           bra     getmsg
badmsg     ldb     #HIGH
           stb     8,x
           sec
           ret     b,x,y,u


*
.   bus was not free when we started
.
notfree    scc     c,v                 say carry and overflow
           ret     d,x,y,u
*
.   move data bytes whichever way controller wants
.
moveit     bitb    #IO                 check for IO
           beq     moveout
           lda     #LOW                insure direction ok
           sta     DDRDATA             for input
.   read from controller
movein     lda     DATA                get data byte
           sta     0,y+                save it in buffer
waiti      ldb     STATUS              get STATUS
           bpl     waiti               wait for REQ
           bitb    #CD                 COMMAND or DATA?
           beq     movein              loop for more input
           rts
.   write to controller (REQ still pending from above)
moveout    lda     0,y+                get next data byte
           sta     DATA                stuff it
waito      ldb     STATUS              get STATUS
           bpl     waito               wait for REQ
           bitb    #CD                 COMMAND or DATA?
           beq     moveout             if data, loop
           rts                         back to caller

           end     sendscsi

           end
