
Find_Start_VBD  IDNT                     ; Title of  Cyclic Section

    SECTION   Sect_Find_Start_VBD,4,C    ; Declare a noncommon code section.
                                         ; Align to Longwords.

***************************************************************************
*                                                                         *
*   Find_Start_VBD                                     Rev.  3-APR-1993   *
*                                                                         *
***************************************************************************

***************************************************************************
*                                                                         *
*  Find Srart VBD  Cyclic Operation section.                              *
*                                                                         *
*        Set the search for free VBD buffer State Bit (StateSearchVBD).   *
*        Initialize the maximum wait counter to time how long is          *
*           required to find a free VBD Buffer.                           *
*        Examine the VBD Buffer Last Used Register (BufSelect) to learn   *
*           which VBD Buffer should be tested first.  If the first one    *
*           tested is not available then test the other one.              *
*           A VBD Buffer is free and ready to be used for this event      *
*           if both its CSR Port Status and DMA bits are zero.            *
*        Check for (and wait for) a free  VBD Buffer.                     *
*                                                                         *
*        If neither Buffer becomes available with in the maximum          *
*           wait then:                                                    *
*           send an error message to the VTC console screen.              *
*           Set the Trouble Warning Bit that says, "Can NOT find a        *
*             free VBD Buffer, both VBD Buffers are stuck trying to       *
*             Transfer to Level 2".                                       *
*           Clear all State Bits.                                         *
*           Return to calling routine.                                    *
*                                                                         *
*        Finding a free VBD Buffer within maximum wait time then:         *
*          Clear the Trouble Warning Bit that says, "Can NOT find a       *
*            free VBD Buffer, both VBD Buffers are stuck trying to        *
*            Transfer to Level 2".                                        *
*          Clear all of the State Bits.                                   *
*          Tell the selected free VBD Buffer to run the DMA list.         *
*          Send to the 68020 terminal either a "0" or a "1" to indicate   *
*            which VBD buffer was last used.                              *
*          Set the VBD Buffer Last Used Register (BufSelect) to indicate  *
*            which VBD Buffer is being used for this transfer to L2.      *
*          Return to the calling routine.                                 *
*                                                                         *
*                                                                         *
*  Control of the Trouble Warning Bits                                    *
*    If neither Buffer becomes available with in the maximum wait then:   *
*      Set the Trouble Warning Bit that says, "Can NOT find a free VBD    *
*      Buffer, both VBD Buffers are stuck trying to Transfer to Level 2". *
*    If a Buffer does become available with in the maximum wait then:     *
*      Clear the Trouble Warning Bit that says, "Can NOT find a free VBD  *
*      Buffer, both VBD Buffers are stuck trying to Transfer to Level 2". *
*      Note: You must clear these Trouble Warning Bits before starting    *
*            the VBD running its DMA engine or you will have to wait for  *
*            access to the bus to talk to the Ironics I/O Module.         *
*                                                                         *
*                                                                         *
*  Control of the State Bits                                              *
*    As soon as we enter this routine set the state bit StateSearchVBD.   *
*    When ever we exit this routine clear all state bits.                 *
*    Note: You must clear the State Bits before starting the VBD          *
*          running its DMA Engine or you will have to wait for access     *
*          to the bus to talk to the Ironics I/O Module.                  *
*                                                                         *
***************************************************************************


*************************************************************************
*       This section defines program-specific macros:                   *
*                                                                       *
*            WrIO:  Write bit(s) to the IRONICS I/O card                *
*                                                                       *
*************************************************************************

WrIO    MACRO                             ; Write byte to Ironics I/O Port.
        NOT.B   \1                        ; Complement data byte \1.
        MOVE.B  \1,\2                     ; Move to Ironics port at adrs \2.
        ENDM



*************************************************************************
*                                                                       *
*  Find Srart VBD  Cyclic Operation section.        Beginning Section   *
*                                                                       *
*    Set the state bits to indicate the  StateSearchVBD.                *
*                                                                       *
*    Initialize the maximum wait time for finding a free buffer.        *
*                                                                       *
*    Examine the VBD Buffer Last Used Register (BufSelect) to learn     *
*      which VBD Buffer should be tested first.  If the first one       *
*      tested is not available then test the other one.                 *
*                                                                       *
*************************************************************************

                ALIGN   4                   ; Align to Longword Address.

Begin_Find_Start_VBD  Move.B  #StateSearchVBD,StatePortAdrs  ; Set the State
                                                             ; Bits to
                                                             ; indicate VTC is
                                                             ; searching for
                                                             ; a free VBD Buf.

        Move.L  BBSMaxWait,D4               ; Load the maximum wait (times
                                            ;   tested) to find  a free
                                            ;   VBD  Buffer to use for this
                                            ;   transfer to Level 2.

        Move.L  BufSelect,D0                ; Move Buffer Select into D0.
        AndI.L  #$00000001,D0               ; Mask all but the lowest bit
                                            ;   of the Buffer Select.

        BEQ     UseBuf1                     ; The last buffer used was "0"
                                            ;   so test buff "1" first.
        JMP     UseBuf0                     ; The last buffer used was "1"
                                            ;   so test buff "0" first.


*************************************************************************
*                                                                       *
*  Find Srart VBD  Cyclic Operation section.        Test-Use Buffer 0   *
*                                                            =========  *
*                                                                       *
*  VBD buffer 0 will be tested to see if it is connected to the VME     *
*    port and to verify that it is not currently running a DMA cycle.   *
*                                                                       *
*  If everything is OK then a DMA cycle will be started, using VBD      *
*    Buffer 0 to move the Level 1 data to the Level 2 system.           *
*                                                                       *
*  If it is found that buffer 0 is either connected to the external     *
*    port or that buffer 0 is already doing a DMA cycle then the        *
*    program will jump to test the status of buffer 1 and try to use it.*
*                                                                       *
*  If the program has already tested both buffers many times            *
*    ( > BBSMaxWait ) and has not found a free buffer, then it will     *
*    branch to BBSTmOut.                                                *
*                                                                       *
*  If this buffer is free to use then clear the Trouble Warning Bits    *
*    that say, "Can't find a free VBD Buffer, both buffers stuck        *
*    sending to L2".  Also clear the State Bits.  All operations        *
*    requiring the VME backplane must be completed before starting      *
*    VBD running its DMA engine.                                        *
*                                                                       *
*  Once the DMA operation is started on buffer 0, a short message,      *
*    "0", will be sent to the VTC console screen, and the VBD Buffer    *
*    Last Used Register (BufSelect) will be set to "0".   Then this     *
*    routine will do a normal exit return to the calling routine.       *
*                                                                       *
*************************************************************************

          ALIGN   4                       ; Align to Longword Address.

UseBuf0   CLR.L   D0                      ; Clear all bits in data reg 0.
          Move.W  VBDCSR2,D0              ; Move the VBD CSR2 into D0.
          AND.L   MskBuf0Sta,D0           ; Mask all but the Buf 0 DMA and
                                          ;   Buf 0 port status bits.
          BEQ     Buf0Rdy                 ; If both CSR bits are 0 then,
                                          ;   Buffer 0 is ready to use.
                                          ; Else
          SUBI.L  #$1,D4                  ; Decrement the max wait counter
                                          ;   for finding a free VBD buffer.
          BEQ     BBSTmOut                ; If time is up and no free buffer
                                          ;   found then branch to time out.
                                          ; If max wait is not used up then
          JMP     UseBuf1                 ; Try to use buffer 1 it may
                                          ;   be free.


           ALIGN   4                    ; Align to Longword Address.

Buf0Rdy    Move.B  TWBData,D0           ; Get the Trouble Warning Bits and
           ANDI.B  #$F2,D0              ;   clear: No Slaves Ready, 68k Not
           Move.B  D0,TWBData           ;   Running, and Can't find a free VBD
                                        ;   Buff, i.e. can't Transfer to L2.
           WrIO    D0,TWBPortAdrs       ; Store and output the TWB's.

           Move.B  #AllBitsLow,StatePortAdrs    ; Set all of the State Bits
                                                ;   low to indicate no state.

           Move.W  Buf0DMAGo,VBDCSR0        ; Start the DMA running into Buf 0.

                                            ; Send out the one character
Chk30TxRDY    Move.B   AdrTxStat,D4         ; message "0"  --> VBD buffer #0.
              ANDI.L   #$00000080,D4        ; Read MFP Transmitter Status Reg.
              IF.B  D4 <NE> #$80  THEN.S    ; Mask all but Tx Buffr Empty Bit.
                JMP  Chk30TxRDY             ; Test if Buffer Empty bit is set,
              ENDI                          ; i.e. ready to send next charctr?
              Move.B   #$30,AdrTxBufr       ; Keep testing as needed.   Load
                                            ; character "0" into Tx Buffer.

        CLR.L   BufSelect                   ; Set the Last VBD Buffer Used
                                            ;   Register (BufSelect) to "0"
                                            ;   to indicate that VBD Buf 0
                                            ;   was the last buf used.

        RTS                                 ; The VBD has been started running
                                            ;   its DMA engine into buffer #0.
                                            ;   This is a normal exit.
                                            ;   Return to the calling routine.


*************************************************************************
*                                                                       *
*  Find Srart VBD  Cyclic Operation section.        Test-Use Buffer 1   *
*                                                            =========  *
*                                                                       *
*  VBD buffer 1 will be tested to see if it is connected to the VME     *
*    port and to verify that it is not currently running a DMA cycle.   *
*                                                                       *
*  If everything is OK then a DMA cycle will be started, using VBD      *
*    Buffer 1 to move the Level 1 data to the Level 2 system.           *
*                                                                       *
*  If it is found that buffer 1 is either connected to the external     *
*    port or that buffer 1 is already doing a DMA cycle then the        *
*    program will jump to test the status of buffer 0 and try to use it.*
*                                                                       *
*  If the program has already tested both buffers many times            *
*    ( > BBSMaxWait ) and has not found a free buffer, then it will     *
*    branch to BBSTmOut.                                                *
*                                                                       *
*  If this buffer is free to use then clear the Trouble Warning Bits    *
*    that say, "Can't find a free VBD Buffer, both buffers stuck        *
*    sending to L2".  Also clear the State Bits.  All operations        *
*    requiring the VME backplane must be completed before starting      *
*    VBD running its DMA engine.                                        *
*                                                                       *
*  Once the DMA operation is started on buffer 1, a short message,      *
*    "1", will be sent to the VTC console screen, and the VBD Buffer    *
*    Last Used Register (BufSelect) will be set to "1".   Then this     *
*    routine will do a normal exit return to the calling routine.       *
*                                                                       *
*************************************************************************

          ALIGN   4                       ; Align to Longword Address.

UseBuf1   CLR.L  D0                       ; Clear all bits in data reg 0.
          Move.W  VBDCSR2,D0              ; Move the VBD CSR2 into D0.
          AND.L   MskBuf1Sta,D0           ; Mask all but the Buf 1 DMA and
                                          ;   Buf 1 port status bits.
          BEQ     Buf1Rdy                 ; If both CSR bits are 0 then,
                                          ;   Buffer 1 is ready to use.
                                          ; Else
          SUBI.L  #$1,D4                  ; Decrement the max wait counter
                                          ;   for finding a free VBD buffer.
          BEQ     BBSTmOut                ; If time is up and no free buffer
                                          ;   found then branch to time out.
                                          ; If max wait is not used up then
          JMP     UseBuf0                 ; Try to use buffer 0 it may
                                          ;   be free.


           ALIGN   4                    ; Align to Longword Address.

Buf1Rdy    Move.B  TWBData,D0           ; Get the Trouble Warning Bits and
           ANDI.B  #$F2,D0              ;   clear: No Slaves Ready, 68k Not
           Move.B  D0,TWBData           ;   Running, and Can't find a free VBD
                                        ;   Buff, i.e. can't Transfer to L2.
           WrIO    D0,TWBPortAdrs       ; Store and output the TWB's.

           Move.B  #AllBitsLow,StatePortAdrs    ; Set all of the State Bits
                                                ;   low to indicate no state.

           MOVE.W  Buf1DMAGo,VBDCSR0        ; Start the DMA running into Buf 1.

                                            ; Send out the one character
Chk31TxRDY    Move.B   AdrTxStat,D4         ; message "1"  --> VBD buffer #1.
              ANDI.L   #$00000080,D4        ; Read MFP Transmitter Status Reg.
              IF.B  D4 <NE> #$80  THEN.S    ; Mask all but Tx Buffr Empty Bit.
                JMP  Chk31TxRDY             ; Test if Buffer Empty bit is set,
              ENDI                          ; i.e. ready to send next charctr?
              Move.B   #$31,AdrTxBufr       ; Keep testing as needed.   Load
                                            ; character "1" into Tx Buffer.

        Move.L  #$00000001,BufSelect        ; Set the Last VBD Buffer Used
                                            ;   Register (BufSelect) to "1"
                                            ;   to indicate that VBD Buf 1
                                            ;   was the last buf used.

        RTS                                 ; The VBD has been started running
                                            ;   its DMA engine into buffer #1.
                                            ;   This is a normal exit.
                                            ;   Return to the calling routine.



*************************************************************************
*                                                                       *
*  Find Srart VBD  Cyclic Operation section.       ERROR Exit Routine   *
*                                                                       *
*     Send a message to the VTC console screen that says that we        *
*       could not find a free VBD Buffer, that both VBD Buffers are     *
*       stuck trying to transfer to Level 2.                            *
*     Set the Trouble Warning Bit that says, "Can NOT find a            *
*       free VBD Buffer, both VBD Buffers are stuck trying to           *
*       Transfer to Level 2".                                           *
*     Clear all State Bits.                                             *
*     Return to the calling routine.                                    *
*                                                                       *
*************************************************************************

                                        ; To reach here a free VBD buffer
                                        ;   could NOT be found within the
                                        ;   maximum lenght of time that is
                                        ;   allowed to find a free buf.

              ALIGN   4                 ; Align to Longword Address.

BBSTmOut      PEA.L    BBSTmMsg1        ; Push NO Free VBD Buf message 1
              JSR      ChrStrgOut       ; on the stack and send it out.
              PEA.L    BBSTmMsg2        ; Push NO Free VBD Buf message 2
              JSR      ChrStrgOut       ; on the stack and send it out.

              Move.B  TWBData,D0        ; Get the Trouble Warning Bits.
              OrI.B   #$04,D0           ; OR the TWB that says "Can't find a
              Move.B  D0,TWBData        ; free VBD Buf, Can't Transfr to L2".
              WrIO    D0,TWBPortAdrs    ; Store and output the TWB's.

        Move.B  #AllBitsLow,StatePortAdrs   ; Set all of the State Bits
                                            ;   low to indicate no state.

        RTS                                 ; Return to the calling routine.



*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  Data used to send messages to the 68k terminal screen.               *
*                                                                       *
*************************************************************************

              ALIGN   4                ; Align to Longword Address.


BBSTmMsg1     DC.B    36,$0D,$0A,'Both VBD Buffers are stuck waiting'
BBSTmMsg2     DC.B    31,'to transfer on the Data Cable.',$0A


*************************************************************************
*  Define Constants:                 External References                *
*                                                                       *
*************************************************************************

       XDEF   Begin_Find_Start_VBD                  ; Export this symbol
                                                    ; to other modules.

       XREF   AdrTxBufr                             ; Symbols referenced
       XREF   AdrTxStat                             ; in this program
       XREF   AllBitsLOW                            ; module but defined
       XREF   BBSMaxWait                            ; in another module
       XREF   Buf0DMAGo                             ; Main_Symbols.Include
       XREF   Buf1DMAGo
       XREF   BufSelect
       XREF   ChrsTrgOut
       XREF   MskBuf0Sta
       XREF   MskBuf1Sta
       XREF   StatePortAdrs
       XREF   StateSearchVBD
       XREF   TWBData
       XREF   TWBPortAdrs
       XREF   VBDCSR0
       XREF   VBDCSR2

       END

