*************************************************************************
*                                                                       *
*                          LEVEL 1 TRIGGER                              *
*                       VBD  DATA_CABLE_DRIVER                          *
*                                                                       *
*                  VERSION: 1       DATE:  15-NOV-1990                  *
*                --------------------------------------                 *
*                                                                       *
*************************************************************************

*************************************************************************
*                                                                       *
*             MODIFICATION - ADDITION                  DATE      NAME   *
*   ----------------------------------------------   ---------   ----   *
*   Change the VME address of the "Event Number"                        *
*   and the "Spec Trig's Fired" to work with a VMX                      *
*   Driver that inverts VMX address line MDA01.                         *
*   The various bytes of these quantities now                           *
*   appear at "interlaced" addresses in VME.         18-OCT-90    DE    *
*                                                                       *
*   Add a time out so that if, after receiving a                        *
*   Slave Ready signal and then waiting for a few                       *
*   seconds, neither Buffer #0 or #1 is free to                         *
*   receive the data block (i.e. both buffers                           *
*   are stuck waiting to transfer on the data                           *
*   cable) then a Data Cable Driver Finished signal                     *
*   will be sent to COMINT and a message displayed                      *
*   on the 68020 console.                            20-OCT-90    DE    *
*                                                                       *
*   Add the subroutine and the Bus Error exception                      *
*   Handler to read the Calorimeter Pulser                              *
*   Programming Data via the Vertical Interconnect.  15-NOV-90    DE    *
*                                                                       *
*   Initialize the section of the MVME-214 memory                       *
*   that holds the Pulser Programming Data that                         *
*   will be read by the VBD with 5's and A's.        15-NOV-90    DE    *
*                                                                       *
*************************************************************************

***************************************************************************
*                                                                         *
*    Registers used:                                                      *
*               D0:     Temporary storage for macros/computation          *
*               D1:                                                       *
*               D2:                                                       *
*               D3:                                                       *
*               D4:     Loop timer count down                             *
*               A3:     Address Pointer                                   *
*               A4:                                                       *
*               A5:     Data stack for messages                           *
*                                                                         *
*                                                                         *
*    Address Map of the Level 1 Trigger VME Crate (133A's view)           *
*                                                                         *
*        0000 0000  through  000F FFFF     133A Module Memory             *
*        0030 0000  through  0030 7FFF     VME 214 Module for Trig Block  *
*        0038 0000  through  003F FFFF     VBD Buffer Memory              *
*                                                                         *
*        FFFF 9000  through  FFFF 97FF     Short 214 IO Space Memory      *
*        FFFF A000  through  FFFF BFFF     VBD Control Memory             *
*        FFFF C000  through  FFFF C0FF     Crate ID Register Card         *
*        FFFF F000  through  FFFF F00F     Ironics 1623 Digital IO Card   *
*                            FFFF ????     Vertical Interconnect Reg.     *
*                                                                         *
*                                                                         *
*    The VME 214 Module for the Trigger Block is utilized as follows      *
*                                                                         *
*        0030 0000  through  0030 0FFF     Current  Beam Crossing Data    *
*        0030 1000  through  0030 1FFF     Previous Beam Crossing Data    *
*                                                                         *
*        0030 4000  through  0030 40FF     Group #1 Pluser Data  CD       *
*        0030 4100  through  0030 41FF     Group #2 Pluser Data  CAL      *
*        0030 4200  through  0030 42FF     Group #3 Pluser Data  MUON     *
*                                                                         *
*        0030 5000  through  0030 501F     Crate Header Data 5 Long Words *
*                                                                         *
*                                                                         *
*                                                                         *
*    Constants used:                                                      *
*               Defined at the end of the program                         *
*                                                                         *
*                                                                         *
*                                                                         *
*    Program Outline:                                                     *
*                                                                         *
*       1. Get the Version Number and the Rivision Numbers                *
*            from include files.                                          *
*                                                                         *
*       2. Initialization section.                                        *
*             Display a Wake up message.                                  *
*             Initialize the section of the MVME-214 that holds Pulser    *
*                Programming Data (304000 thru 3042FF) with 5's and A's.  *
*             Initialize the Ironics I/O registers.                       *
*                Slave Ready to HIGH, Data Cable Driver Finished to LOW.  *
*             Initialize the VBD.                                         *
*                Un-Lock the CSR block load DMA time-out.                 *
*                Load the Crate Type.                                     *
*                Load the Event Number Address.                           *
*                Load the Crate ID Address.                               *
*                Load the D Control Register, the format for data reads.  *
*                Load the P Control Reg., the format for parameter reads. *
*                Load the I/O Address high order bits.                    *
*             Load the VBD withthe  pointer list to the Word Counts.      *
*             Load the Word Counts into their Short IO storage locations. *
*             Load the VBD with the list of data block Base Addresses.    *
*             Initialize the VBD (continued).                             *
*                Reset the VBD (make these parameters active).            *
*                Lock the VBD parameters and load DMA time-out.           *
*             Build words #2, #3, and #4 of the Crate Header and Display  *
*               the Crate ID, the Version Number and the Rivision Numbers.*
*             Initialize the VBD Buffer Select Counter to VBD Buffer 0.   *
*             Clear any old COMINT Slave Ready requests by pulsing the    *
*                Data Cable Driver signal line high and then low twice.   *
*             Display an Initialization Complete message.                 *
*                                                                         *
*       3. Cyclic Operation section.                                      *
*             Zero the loop counter that times the wait for Slave Ready.  *
*             Wait for the Slave Ready signal from the COMINT and verify  *
*                that Slave Ready is HIGH.  If it takes too long (e.g.    *
*                > 3 min) then pulse Data Cable Driver Finished to        *
*                "clear"  the COMINT card. Once Slave Ready is received:  *
*             Increment the Buffer Select Counter so that the least       *
*                recently used VBD Buffer will be tested first to see     *
*                if it is free.                                           *
*             Read the Specific Triggers Fired and make a Specific        *
*                Triggers Fired list in a longword.                       *
*             If this event is only a monitor Specific Trigger then:      *
*                Send a monitor data only message to the 68020 terminal.  *
*                Send the Data Cable Driver Finished signal to the COMINT.*
*                Wait for the COMINT Slave Ready signal to fall.          *
*                Drop the Data Cable Driver Finished signal.              *
*             If this event is any combination of Specific Triggers       *
*                including at least one besides monitor Spec Trigs then:  *
*                Make a 16 bit Event Number for the VBD to read and save  *
*                   information to display the Sync Bits if there is time.*
*                Build the Crate Header words #1 and #5.                  *
*                Call the Subroutine to read the Calorimeter Pulser       *
*                   Programming Data.                                     *
*                Initialize the maximum wait counter to time how long     *
*                   is required to find a free VBD Buffer.                *
*                Examine the VBD Buffer Select Counter to learn which     *
*                   VBD Buffer should be tested first.  If the first one  *
*                   tested is not available then test the other one.      *
*                Check for (and wait for) a free  VBD Buffer.             *
*                If neither Buffer becomes available with in the maximum  *
*                   wait then, send an message to the console, pulse the  *
*                   Data Cable Driver Finished line and return to the     *
*                   start of the cyclic section.                          *
*                Finding a free VBD Buffer within maximum wait then:      *
*                Tell the selected free VBD Buffer to run the DMA list.   *
*                Send to the 68020 terminal either a "0" or a "1".        *
*                Zero the DMA time out counter.                           *
*                Wait for the DMA to finish; increment the DMA time out   *
*                   counter with each loop of testing the DMA status.     *
*                If the DMA times out then send a message to the 68020    *
*                   terminal and continue. If it does not time out then   *
*                   when the DMA is finished just continue from here.     *
*                Send the Data Cable Driver Finished signal to the COMINT.*
*                Wait for the COMINT Slave Ready signal to fall.          *
*                Drop the Data Cable Driver Finished signal.              *
*                If the wait to receive the Slave Ready for this event    *
*                   was longer than SRMINDISP then the current event rate *
*                   is low enough to take the time to display a message.  *
*                   If it was a short wait then move on with no message.  *
*                      Display on the 68020 a message if there is time.   *
*                Return to the start of the cyclic section.               *
*                   (wait for Slave Ready).                               *
*                                                                         *
***************************************************************************

VBDDRV  IDNT                            ; title.
        ORG     $10000                  ; start of code (MVME133A).

        JMP     STRINT                  ; Jump to the start of initialization.

*************************************************************************
*  This sections calls all of the include files.                        *
*                                                                       *
*  68020_EQUATES.INC defines macros to be used to call MVME133ABUG ROM. *
*                                                                       *
*  Version Number information for making Crate Header Word #3 is        *
*  obtained from the VBD_VERSION_NUMBER.SRC include file.               *
*                                                                       *
*  Revision Number information for making Crate Header Word #5 is       *
*  obtained from the VBD_REVISION_NUMBER.SRC include file.              *
*************************************************************************

        INCLUDE 68020_EQUATES.INC        ; Get the MVME133A BUG ROM Calls.

        INCLUDE VBD_VERSION_NUMBER.SRC   ; Get the Version Num include file.
        INCLUDE VBD_REVISION_NUMBER.SRC  ; Get the Revision Num include file.

*************************************************************************
*       This section defines program-specific macros:                   *
*                                                                       *
*            RDIO:  Read bit from IRONICS I/O card and returns state    *
*            WRIO:  Write bit(s) to the IRONICS I/O card                *
*            SOFTWAIT:  Software delay timer for short waits            *
*                                                                       *
*************************************************************************

RDIO    MACRO                                 ; read byte from I/O port.
        CMPI.B  #BIT1HIGH,\1                  ; is selected line high?
        ENDM                                  ; set Z on result.

WRIO    MACRO                                 ; write byte to I/O port.
        NOT.B   \1                            ; complement input.
        MOVE.B  \1,\2                         ; and send to port.
        ENDM

SOFTWAIT   MACRO                              ; Software timer loop.
           LOCAL    WAITMORE                  ; Define a local symbol.
           MOVE.L   \1,D4                     ; Load delay time into D4.
WAITMORE   SUBI.L   #1,D4                     ; Decrement loop counter.
           BNE      WAITMORE                  ; Test for end of delay.
           ENDM                               ; Called with an argument
                                              ; of $1000 causes a delay
                                              ; of about 3 mill seconds.

*************************************************************************
*                                                                       *
*        **********     START OF THE PROGRAM     **********             *
*                                                                       *
*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Send the Wake-Up message to the 68k terminal.                        *
*                                                                       *
*************************************************************************

        ORG     $95000                  ; put the main routine up in memory.

STRINT  PEA.L   CS                            ; put clear screen on stack.
        SYSCALL .WRITE                        ; clear screen.
        PEA.L   HO                            ; put home cursor on stack.
        SYSCALL .WRITE                        ; home cursor.
        PEA.L   HELLO                         ; push message address on stack.
        SYSCALL .WRITELN                      ; and send it out.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Initialize the section of the MVME-214 Memory that holds the Pulser  *
*  Programming Data that will be read by the VBD with 5's and A's.      *
*************************************************************************

        MOVE.L  #$C0,D3             ; Load the number of longword to fill.
        MOVE.L  #$00304000,A3       ; Load the VME Pulser Data Base Address.


FVMPPD  MOVE.L  #$55555555,(A3)+    ; Fill with 5's   0101 0101 0101 0101
        MOVE.L  #$AAAAAAAA,(A3)+    ; Fill with A's   1010 1010 1010 1010

        SUBI.L  #$1,D3              ; Decrement the word count.
        BNE     FVMPPD              ; Done yet?

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Initialize the IRONICS card Slave Ready HI and DCDr Finished LOW.    *
*                                                                       *
*************************************************************************

        MOVE.B  #BIT1HIGH,D0                  ; initialize Slave Ready.
        WRIO    D0,SLVRDY                     ; to 01    HI.

        MOVE.B  #ALLBITSLOW,D0                ; initialize DCDr Finished.
        WRIO    D0,DCDRFIN                    ; to 00   LOW.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Initialize the VBD Control Registers.                                *
*                                                                       *
*************************************************************************

        MOVE.W  VBDDMATO,VBDCSR0          ; Load the VBD DMA time-out value.
        MOVE.W  CRATETYPE,CRATETYPEREG    ; Load the VBD Crate Type Register.
        MOVE.W  #EVTNMBADR,EVTNMBADRREG   ; Load pointer to the Event Number.
        MOVE.W  CRATEIDADRS,CRTIDADRREG   ; Load the pointer to the Crate ID.
        MOVE.W  DCTRLDATA,DCONTROLREG     ; Load data read format ctrl reg.
        MOVE.W  PCTRLDATA,PCONTROLREG     ; Load param read format ctrl reg.
        MOVE.W  IOUPADRS,IOUPADRSREG      ; Load upper adrs bits for IO reads.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Load the VBD with the list of the addresses of Word Count storage    *
*  locations in the Short IO Memory module  (i.e. the Word Counter      *
*  Pointer List).  A null terminates the list.                          *
*                                                                       *
*************************************************************************

        MOVE.L  #WCPNTLIST,A3             ; Load address of the start of the.
                                          ; VBD Word CNT Pointer list into A3.

        MOVE.W  #WCSTORE1,(A3)+           ; Load the pointer to the Header WC.
        MOVE.W  #WCSTORE2,(A3)+           ; Load the pointer to Trig DB WC.
        MOVE.W  #WCSTORE3,(A3)+           ; Load the pointer to 3rd WC.

        MOVE.W  #0000,(A3)+               ; Load a null to terminate
                                          ;     the WC list.

        MOVE.W  #WCSTORE4,(A3)+           ; Load the pointer to 4th WC.
        MOVE.W  #WCSTORE5,(A3)+           ; Load the pointer to 5th WC.

        MOVE.W  #0000,(A3)+               ; Load a null to terminate
                                          ;     the WC list.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Load the Word Counts into their storage locations in the Short IO    *
*  Address space Memory module  i.e. the Short 214.                     *
*************************************************************************

        MOVE.L   #$FFFF0000,A3           ; Make the 133A version of the Short
        MOVE.W   #WCSTORE1,A3            ; IO Address for the storage location.
        MOVE.W   WCHEADER,(A3)           ; for WC #1  and  store WC #1 in it.

        MOVE.L   #$FFFF0000,A3           ; Make the 133A version of the Short
        MOVE.W   #WCSTORE2,A3            ; IO Address for the storage location
        MOVE.W   WCL1TRGDB,(A3)          ; for WC #2  and  store WC #2 in it.

        MOVE.L   #$FFFF0000,A3           ; Make the 133A version of the Short
        MOVE.W   #WCSTORE3,A3            ; IO Address for the storage location.
        MOVE.W   WC3RDBLK,(A3)           ; for WC #3  and  store WC #3 in it.

        MOVE.L   #$FFFF0000,A3           ; Make the 133A version of the Short
        MOVE.W   #WCSTORE4,A3            ; IO Address for the storage location.
        MOVE.W   WC4THBLK,(A3)           ; for WC #4  and  store WC #4 in it.

        MOVE.L   #$FFFF0000,A3           ; Make the 133A version of the Short
        MOVE.W   #WCSTORE5,A3            ; IO Address for the storage location.
        MOVE.W   WC5THBLK,(A3)           ; for WC #5  and  store WC #5 in it.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Load the VBD with the list of the data block Base Addresses.         *
*                                                                       *
*************************************************************************

        MOVE.L  #DATAPNTLIST,A3         ; Load address of the start of the
                                        ;    VBD Data Pointer list into A3.
        MOVE.L  BAHEADER,(A3)+          ; Load pointer to Base Adrs of header.
        MOVE.L  BAL1TRGDB,(A3)+         ; Load pointer to Base Adrs of Trg DB.
        MOVE.L  BA3RDBLK,(A3)+          ; Load pointer to Base Adrs pulser
        MOVE.L  BA4THBLK,(A3)+          ; Load pointer to Base Adrs of
        MOVE.L  BA5THBLK,(A3)+          ; Load pointer to Base Adrs of

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Lock the VBD Control Memory.                                         *
*                                                                       *
*************************************************************************

        MOVE.W  VBDRESET,VBDCSR0          ; Reset the VBD and its err FIFO.

        SOFTWAIT  #$1000                  ; Wait about 5 mill seconds.

        MOVE.W  VBDTOLOCK,VBDCSR0         ; Load the VBD DMA time-out value
                                          ; and lock the VBD Control Memory.

*****************************************************************************
*  Initialization:                                                          *
*                                                                           *
*  Build words #2, #3 and #4 of the Crate Header.                           *
*  These Crate Header words are event to event static.   Words #1           *
*  and #5 are built for each event during the transfer to the VBD.          *
*                                                                           *
*    Crate Header Word 1   Sync Word   2 MSByts Evt Num  2 LSByts of F's    *
*    Crate Header Word 2   Controller Word  MSByte is the low byte Crate ID *
*    Crate Header Word 3   Version Number  4-JAN-1990 Document definition   *
*    Crate Header Word 4   Revision Number   defined in D0 Note #967        *
*    Crate Header Word 5   Specific Triggers Fired list    32 bits          *
*                                                                           *
*  Display these words on the 68k console as they are being built. This     *
*  display is part of the initialization message.                           *
*                                                                           *
*  Version Number information for making Crate Header Word #3 is obtained   *
*  from the VBD_VERSION_NUMBER.SRC include file which is called above.      *
*                                                                           *
*  Revision Number information for making Crate Header Word #4 is obtained  *
*  from the VBD_REVISION_NUMBER.SRC include file which is called above.     *
*                                                                           *
*****************************************************************************

        MOVE.L  #$00000000,D0            ; Clear D0 it will receive Crate ID.
        MOVE.L  #DATASTACK,A5            ; Data Stack for console display.

        MOVE.L  #$FFFF0000,A3            ; Make the 133A version of the Short
        MOVE.W  CRATEIDADRS,A3           ; IO Address for the Crate ID card.
        MOVE.W  (A3),D0                  ; Load the Crate ID into Data Reg 0.

        MOVE.L  D0,(A5)+                 ; Store Crate ID as read from Shea's
                                         ; brd on the data stack for display.

        ANDI.L  #$000000FF,D0            ; Mask off all but Low byte of Crt ID
        SWAP    D0                       ; Move the low byte of the Crate ID
        LSL.L   #$8,D0                   ; into the top byte of data reg D0.
        MOVE.L  D0,CRTHDWORD2            ; Store the Controller word as the
                                         ;   second word of the Crate Header.

        MOVE.L  D0,(A5)+                 ; Store the Controller word on the
                                         ;   data stack for display.
        PEA.L   DATASTACK                ; Push the pointer for the data stack.
        PEA.L   DISPCRATE                ; Push the Crate ID message format.
        SYSCALL .WRITDLN                 ; Call the system to output message.


        MOVE.L  VERSNUM,CRTHDWORD3       ; Store the Version Number in the
                                         ;   3rd word of the Crate Header.

        MOVE.L  #DATASTACK,A5            ; Data Stack for console display.
        MOVE.L  VERSNUM,(A5)+            ; Store the Version Number on the
                                         ;   data stack for display.
        PEA.L   DATASTACK                ; Push the pointer for the data stack.
        PEA.L   DISVERNUM                ; Push Version Number message format.
        SYSCALL .WRITDLN                 ; Call the system to output message.


        MOVE.L  #$00000000,D0            ; Clear Data Register D0.
        MOVE.B  VMECPUREVNUM,D0          ; Load the VME CPU Revision Number.
        LSL.L   #$8,D0                   ; SHIFT it to the left 8 places
        MOVE.B  COMINTPROMRN,D0          ; Load the COMINT PROM Revision Num.
        LSL.L   #$8,D0                   ; SHIFT it to the left 8 places
        MOVE.B  LOOKUPREVNUM,D0          ; Load the Look Up System Rev. Num.
        LSL.L   #$8,D0                   ; SHIFT it to the left 8 places
        MOVE.B  HARDWRREVNUM,D0          ; Load the Trigger Hardware Rev. Num.

        MOVE.L  D0,CRTHDWORD4            ; Store the Revision Number in the
                                         ;   4th word of the Crate Header.

        MOVE.L  #DATASTACK,A5            ; Data Stack for console display.
        MOVE.L  D0,(A5)+                 ; Store the Crate Header 4th word
                                         ;   (Rev. Num.) on display data stack.
        PEA.L   DATASTACK                ; Push the pointer for the data stack.
        PEA.L   DISREVNO1                ; Push Revision Number message 1 form.
        SYSCALL .WRITDLN                 ; Call the system to output message.

        MOVE.L  #DATASTACK,A5            ; Data Stack for console display.
        MOVE.L  #$00000000,D0            ; Load zero into data register 0.
        MOVE.B  VMECPUREVNUM,D0          ; Load VME CPU Program Revision Num.
        MOVE.L  D0,(A5)+                 ; Store the VME CPU Program Revision
                                         ;   Number on the display data stack.
        MOVE.L  #$00000000,D0            ; Load zero into data register 0.
        MOVE.B  COMINTPROMRN,D0          ; Load COMINT PROM Revision Num.
        MOVE.L  D0,(A5)+                 ; Store the COMINT PROM Revision
                                         ;   Number on the display data stack.
        PEA.L   DATASTACK                ; Push the pointer for the data stack.
        PEA.L   DISREVNO2                ; Push Revision Number message 2 form.
        SYSCALL .WRITDLN                 ; Call the system to output message.

        MOVE.L  #DATASTACK,A5            ; Data Stack for console display.
        MOVE.L  #$00000000,D0            ; Load zero into data register 0.
        MOVE.B  LOOKUPREVNUM,D0          ; Load Look Up System Revision Num.
        MOVE.L  D0,(A5)+                 ; Store the Look Up System Revision
                                         ;   Number on the display data stack.
        MOVE.L  #$00000000,D0            ; Load zero into data register 0.
        MOVE.B  HARDWRREVNUM,D0          ; Load Trigger Hardware Revision Num.
        MOVE.L  D0,(A5)+                 ; Store the Trigger Hardware Revision
                                         ;   Number on the display data stack.
        PEA.L   DATASTACK                ; Push the pointer for the data stack.
        PEA.L   DISREVNO3                ; Push Revision Number message 3 form.
        SYSCALL .WRITDLN                 ; Call the system to output message.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Set the Buffer Select to pick buffer 0.                              *
*                                                                       *
*************************************************************************

        MOVE.L  #$00000000,BUFSELECT     ; Set Buffer Select for buffer 0.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Clear any old COMINT Slave Ready requests by pulsing the Data Cable  *
*  Driver Finished line high and low and high and low.                  *
*                                                                       *
*************************************************************************

        MOVE.B  #BIT1HIGH,D0                  ; Send a Data Cable Driver
        WRIO    D0,DCDRFIN                    ;   Finished signal to COMINT.

        SOFTWAIT  #$1000                      ; Wait about 5 mill seconds.

        MOVE.B  #ALLBITSLOW,D0                ; Drop the Data Cable Driver
        WRIO    D0,DCDRFIN                    ;   Finished signal.

        SOFTWAIT  #$1000                      ; Wait about 5 mill seconds.

        MOVE.B  #BIT1HIGH,D0                  ; Send a Data Cable Driver
        WRIO    D0,DCDRFIN                    ;   Finished signal to COMINT.

        SOFTWAIT  #$1000                      ; Wait about 5 mill seconds.

        MOVE.B  #ALLBITSLOW,D0                ; Drop the Data Cable Driver
        WRIO    D0,DCDRFIN                    ;   Finished signal.

*************************************************************************
*  Initialization:                                                      *
*                                                                       *
*  Send the Initialization Complete Message to the 68k terminal.        *
*                                                                       *
*************************************************************************

        PEA.L   INITCMPT1                    ; push message address on stack.
        SYSCALL .WRITELN                     ; and send it out.
        PEA.L   INITCMPT2                    ; push message address on stack.
        SYSCALL .WRITELN                     ; and send it out.

*************************************************************************
*  Cyclic Section:                                                      *
*                                                                       *
*  Wait for a L1 trigger and for the COMINT Data Block Builder to       *
*  finish building a new L1 Data Block.   When COMINT is finished       *
*  building a Data Block it sets the Slave Ready signal High.           *
*                                                                       *
*  Count how long we have waited for Slave Ready to go High in the      *
*  location SRLOOPCNT.   This size of this count will let us know how   *
*  long of an information message can be sent to the 68k terminal after *
*  the transfer to the VBD and also let us know if there has not been   *
*  a Slave Ready signal in a very long time and thus we should pulse    *
*  the Data Cable Driver Finished line to clear something in COMINT.    *
*  After finding a Slave Ready, store the wait for Slave Ready count.   *
*                                                                       *
*  When Slave Ready goes high then increment BUFSELECT to alternate     *
*  which of the VBD buffers is used.                                    *
*                                                                       *
*************************************************************************

CYCLIC  MOVE.L  #$00000000,D1          ; Starting the wait for Slv Rdy so
                                       ;   zero the loop counter.

TESTSR  RDIO    SLVRDY                 ; Look for the Slave Ready  HI.
        BEQ     VERFSR                 ; If high, then verify that it is HI.
        ADD.L   #$1,D1                 ; Increment the wait for Slv Rdy count.
        CMP.L   SRMAXWAIT,D1           ; Test to see if it has been the max
        BEQ     STUCK                  ;   wait.  If so pulse the  Finished
                                       ;   line to wake up the COMINT.
        JMP     TESTSR                 ; Wait for the Slave Ready.

VERFSR  RDIO    SLVRDY                 ; Look for the Slave Ready  HI.
        BEQ     PROCEVT                ; If still high, then process the event.
        JMP     TESTSR                 ; Back to waiting for the Slave Ready.

STUCK   MOVE.B  #BIT1HIGH,D0           ; Send a Data Cable Driver
        WRIO    D0,DCDRFIN             ;   Finished signal to COMINT.
        SOFTWAIT  #$1000               ; Wait about 5 mill seconds.
        MOVE.B  #ALLBITSLOW,D0         ; Drop the Data Cable Driver
        WRIO    D0,DCDRFIN             ;   Finished signal.
        PEA.L   SRWAITMSG1             ; Send a message saying that SR not
        SYSCALL .WRITELN               ;   seen within Max Wait.
        PEA.L   SRWAITMSG2             ; Pulsing Data Cable Driver Finished
        SYSCALL .WRITELN               ;   to free up the COMINT card.
        JMP     CYCLIC                 ; Start looking for Slave Ready
                                       ;   again.  Zero the SR wait counter.

PROCEVT ADD.L   #$1,BUFSELECT          ; Alternate which VBD buffer is used.
        MOVE.L  D1,SRLOOPCNT           ; Store the count of how long we have
                                       ;   waited for a Slave Ready.

*************************************************************************
*  Cyclic Section:                                                      *
*                                                                       *
*  By reading locations in the MVME214 memory, build a longword which   *
*  contains the list of Specific Triggers fired for this L1 Data Block. *
*  If just a monitor Specific Trigger (e.g. #31) fired then this event  *
*  is only L1 monitor data and it should NOT be sent to the VBD and L2. *
*  If any other Specific Trigger, besides monitor Specific Trigger(s),  *
*  fired then send this L1 Data Block to the VBD and L2.                *
*                                                                       *
*************************************************************************

        MOVE.B  TRGFIRE+4,D0                ; get the SPTRG Fired 4th byte.
        LSL.L   #8,D0                       ; shift it up by 8 bits.
        MOVE.B  TRGFIRE+6,D0                ; get the SPTRG Fired 3rd byte.
        LSL.L   #8,D0                       ; shift it up by 8 bits.
        MOVE.B  TRGFIRE,D0                  ; get the SPTRG Fired 2nd byte.
        LSL.L   #8,D0                       ; shift it up by 8 bits.
        MOVE.B  TRGFIRE+2,D0                ; get the SPTRG Fired 1st byte.

        MOVE.L  D0,TRGSFIRED                ; Store the Spec Trigs Fired.

        AND.L   MSKMONSPTRG,D0              ; Test for Spec Trigs besides
                                            ;   just Monitor Spec Triggers.
        BEQ     ONLYMON                     ; Branch to service Monitor data
                                            ;   only "events".
        JMP     OTHERTRGS                   ; Jump to service events that have
                                            ;   a Spec Trig besides Mon trigs.

*************************************************************************
*  Cyclic Section:    START of service for Monitor Data only "events".  *
*                                                                       *
*  Service events in which only Monitor Specific Triggers have          *
*  fired.  This implies --> monitor data only events.                   *
*                                                                       *
*  Send a message to the 68k termanal that this is monitor data only.   *
*                                                                       *
*************************************************************************

ONLYMON  PEA.L    MONMESSAGE                 ; push message address on stack.
         SYSCALL .WRITELN                    ; and send it out.

*************************************************************************
*  Cyclic Section:                 Monitor Data only "events"           *
*                                                                       *
*  Tell COMINT that the VBD is finished and wait for SLV Ready to drop. *
*                                                                       *
*************************************************************************

        MOVE.B  #BIT1HIGH,D0                ; Send a Data Cable Driver
        WRIO    D0,DCDRFIN                  ;   Finished signal to COMINT.

STILHI  RDIO    SLVRDY                      ; Look for the Slave Ready.
        BEQ     STILHI                      ; If it is still high then keep
                                            ;   waiting until it drops then.

        MOVE.B  #ALLBITSLOW,D0              ; Drop the Data Cable Driver
        WRIO    D0,DCDRFIN                  ;   Finished signal.

*************************************************************************
*  Cyclic Section:      END of service for Monitor Data only "events".  *
*                                                                       *
*  Return to the begining of the Cyclic Section.                        *
*                                                                       *
*************************************************************************

        JMP     CYCLIC                       ; Return to the start of the
                                             ;   cyclic section.


*************************************************************************
*  Cyclic Section:          START of service for normal events.         *
*                                                                       *
*  Service events in which some combination of normal (non-Monitor)     *
*  Specific Triggers have fired.  In addition some Monitor Specific     *
*  Triggers may have fired.                                             *
*                                                                       *
*  Start by making a copy of the low order 16 bits of the Event         *
*  Number.   Put this 16 bit Event Number in Short IO Address Space     *
*  where the VBD can read it.  Also store it in TRGNUMSTORE.            *
*                                                                       *
*************************************************************************

OTHERTRGS  MOVE.L  #$00000000,D0         ; Clear Data Register 0.
           MOVE.B  TRGNUM,D0             ; Get the 2nd byte of the Evt Num.
           LSL.L   #$8,D0                ; Shift it up into place.
           MOVE.B  TRGNUM+2,D0           ; Get the Event Number first byte.
                                         ; D0 now holds the 16 bit Evt Num.

           MOVE.W  D0,EVTNMBADR133       ; Store the 16 bit Evt Num in the
                                         ;   Short IO Address memory space
                                         ;   for the VBD to read.

           MOVE.L  D0,TRGNUMSTORE        ; Store the 16 bit trigger number
                                         ;   in a longword.
*****************************************************************************
*                                                                           *
*  Cyclic Section:            Service Data Block for Normal Events          *
*                                                                           *
*  Build the words #1 and #5 of the Crate Header.                           *
*  Words #2, #3, and #4 of the Crate Header are event to event static       *
*  and have been built and stored in the Initialization Section above.      *
*                                                                           *
*    Crate Header Word 1   Sync Word   2 MSByts Evt Num  2 LSByts of F's    *
*    Crate Header Word 2   Controller Word  MSByte is the low byte Crate ID *
*    Crate Header Word 3   Version Number  4-JAN-1990 Document definition   *
*    Crate Header Word 4   Rivision Number   defined in D0 Note #967        *
*    Crate Header Word 5   Specific Triggers Fired list    32 bits          *
*                                                                           *
*****************************************************************************

                                         ; D0 still holds the 16 bit Evt Num.
        SWAP    D0                       ; Move the 16 bit Evt Num into
                                         ;   the high order 16 bits.
        MOVE.W  #$FFFF,D0                ; Pad the Sync Word with F's.
        MOVE.L  D0,CRTHDWORD1            ; Store the Sync Word in the
                                         ;   first word of the Crate Header.

        MOVE.L  TRGSFIRED,CRTHDWORD5     ; Store the Specific Triggers Fired
                                         ;   list in the 5th word of the
                                         ;   Crate Header.

*************************************************************************
*                                                                       *
*  Cyclic Section:            Service Data Block for Normal Events      *
*                                                                       *
*  Call the subroutine to read the Calorimeter Pulser Programming       *
*  Data via the Vertical Interconnect.                                  *
*************************************************************************

        JSR  GVPPD              ; Subroutine call to get Cal Pulser Data

*************************************************************************
*                                                                       *
*  Cyclic Section:            Service Data Block for Normal Events      *
*                                                                       *
*  All of the data and headers are now ready to be read by the VBD.     *
*  Examine BUFSELECT to determine which of the two buffers (0 or 1)     *
*  on the VBD should be used to DMA read this data.  The buffers are    *
*  used on alternate events.                                            *
*  Initialize the maximum wait time counter for finding a free buffer.  *
*************************************************************************

        MOVE.L  BBSMAXWAIT,D4               ; Load the maximum wait (times
                                            ; tested) to find a free Buffer.

        MOVE.L  BUFSELECT,D0                ; Move Buffer Select into D0.
        ANDI.L  #$00000001,D0               ; Mask all but the lowest bit
                                            ;   of the Buffer Select.
        BEQ     USEBUF0                     ; Bufselect even - use Buffer 0.
        JMP     USEBUF1                     ; Bufselect odd  - use Buffer 1.

*************************************************************************
*                                                                       *
*  Cyclic Section:  Service Data Block for Normal Events, use Buffer 0  *
*                                                             --------  *
*  If VBD buffer 0 has been selected for the transfer of this event     *
*  then this section takes care of testing that buffer 0 is connected   *
*  to the VME port and that it is not currently running a DMA cycle.    *
*  If everything is OK then a DMA cycle will be started to move VME     *
*  data into buffer 0.                                                  *
*                                                                       *
*  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.    *
*                                                                       *
*  Once the DMA operation is started on buffer 0, a short message,      *
*  "0", will be sent to the 68020 console.                              *
*                                                                       *
*  Next the program will test for the completion of the DMA cycle on    *
*  buffer 0.  If the DMA cycle completes in less than about 1/2 second  *
*  then everything is normal and execution proceeds to the NCYCEXIT     *
*  section.  If the DMA cycle does not complete within the 1/2 second   *
*  then an error message is displayed and then execution proceeds to    *
*  the NCYCEXIT section.                                                *
*                                                                       *
*************************************************************************

USEBUF0 MOVE.L  #$00000000,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.

BUF0RDY  MOVE.W  BUF0DMAGO,VBDCSR0        ; Start the DMA running into Buf 0.

        PEA.L    CHAR0                    ; Push message "0" on to the stack,
        SYSCALL .WRITE                    ; and send it out.

        MOVE.L  WAITDMA,D4                ; Initialize the register to wait
                                          ;  for the DMA cycle to finish.

        MOVE.L  #$00000000,D0             ; Clear all bits in data reg 0.
CHKDMA0 MOVE.W  VBDCSR2,D0                ; Move the VBD CSR2 into D0.
        AND.L   MSKBUF0DMA,D0             ; Mask all but the Buf 0 DMA status.

        BEQ     NCYCEXIT                  ; If DMA status is zero then the
                                          ;   Buffer 0 DMA cycle has finished.
                                          ;   Jump to the exit processing for
                                          ;   normal events.

        SUBI.L  #$1,D4                    ; DMA cycle has not finished.
                                          ;   Decrement its time out counter.
        BNE     CHKDMA0                   ; Not timed out, check status again.
        PEA.L   GIVEUP0                   ; Timed out, Push message on stack.
        SYSCALL .WRITELN                  ; Display Buf 0 DMA time out message
        JMP     NCYCEXIT                  ; Jump to the exit processing for
                                          ;   normal events.


*************************************************************************
*                                                                       *
*  Cyclic Section:  Service Data Block for Normal Events, use Buffer 1  *
*                                                             --------  *
*  If VBD buffer 1 has been selected for the transfer of this event     *
*  then this section takes care of testing that buffer 1 is connected   *
*  to the VME port and that it is not currently running a DMA cycle.    *
*  If everything is OK then a DMA cycle will be started to move VME     *
*  data into buffer 1.                                                  *
*                                                                       *
*  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.    *
*                                                                       *
*  Once the DMA operation is started on buffer 1, a short message,      *
*  "1", will be sent to the 68020 console.                              *
*                                                                       *
*  Next the program will test for the completion of the DMA cycle on    *
*  buffer 1.  If the DMA cycle completes in less than about 1/2 second  *
*  then everything is normal and execution proceeds to the NCYCEXIT     *
*  section.  If the DMA cycle does not complete within the 1/2 second   *
*  then an error message is displayed and then execution proceeds to    *
*  the NCYCEXIT section.                                                *
*                                                                       *
*************************************************************************

USEBUF1 MOVE.L  #$00000000,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.

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

        PEA.L    CHAR1                    ; Push message "1" on to the stack,
        SYSCALL .WRITE                    ; and send it out.

        MOVE.L  WAITDMA,D4                ; Initialize the register to wait
                                          ;  for the DMA cycle to finish.

        MOVE.L  #$00000000,D0             ; Clear all bits in data reg 0.
CHKDMA1 MOVE.W  VBDCSR2,D0                ; Move the VBD CSR2 into D0.
        AND.L   MSKBUF1DMA,D0             ; Mask all but the Buf 1 DMA status.

        BEQ     NCYCEXIT                  ; If DMA status is zero then the
                                          ;   Buffer 1 DMA cycle has finished.
                                          ;   Jump to the exit processing for
                                          ;   normal events.

        SUBI.L  #$1,D4                    ; DMA cycle has not finished.
                                          ;   Decrement its time out counter.
        BNE     CHKDMA1                   ; Not timed out, check status again.
        PEA.L   GIVEUP1                   ; Timed out, Push message on stack.
        SYSCALL .WRITELN                  ; Display Buf 1 DMA time out message
        JMP     NCYCEXIT                  ; Jump to the exit processing for
                                          ;   normal events.

*************************************************************************
*  Cyclic Section:          END of service for normal events.           *
*                                                                       *
*  The VBD DMA cycle has finished  (or timed out).  The VBD may still   *
*  be doing the transfer to L2 but, COMINT may access the MVME-214      *
*  memory again when it is ready to.                                    *
*                                                                       *
*  Because the VBD DMA operation has finished,  send a Data Cable       *
*  Driver Finished signal to the COMINT.                                *
*                                                                       *
*  If there has been a long time since the last data block then this    *
*  section will send a detailed message to the 68k's terminal screen.   *
*                                                                       *
*  Return to the begining of the Cyclic Section.                        *
*                                                                       *
*************************************************************************


NCYCEXIT  MOVE.B  #BIT1HIGH,D0              ; Send a Data Cable Driver
          WRIO    D0,DCDRFIN                ;   Finished signal to COMINT.

HISTIL  RDIO    SLVRDY                      ; Look for the Slave Ready.
        BEQ     HISTIL                      ; If it is still high then keep
                                            ;   waiting until it drops then.

        MOVE.B  #ALLBITSLOW,D0              ; Drop the Data Cable Driver
        WRIO    D0,DCDRFIN                  ;   Finished signal.


        MOVE.L  SRLOOPCNT,D0                ; Move loop count of how long of
                                            ;   a wait for Slave Ready to D0.
        SUB.L   SRMINDISP,D0                ; Subtract the minimum wait for a
                                            ;   full display from the wait.
        BMI     CYCLIC                      ; The result is negative --> not a
                                            ;   long enough wait for Sl Rdy -->
                                            ;   high transfer rate --> no time
                                            ;   to send full display --> start
                                            ;   waiting for the next Slave Rdy.

                                            ; The transfer rate is low so there
                                            ;   is enough time to send a full
                                            ;   display.
        MOVE.L  TRGNUMSTORE,D0              ; Recall the 16 bit trigger number.
         AND.L  LOW4LONG,D0                 ; Mask off the part of the Evt Num
                                            ;   that is not Sync Bits.
        MOVE.L  #DATASTACK,A5               ; Initialize A5 for data stack.
        MOVE.L  D0,(A5)+                    ; Get the SYNC Bits data.
        MOVE.L  TRGSFIRED,(A5)+             ; Get the SP TRG's Fired data.
        PEA.L   DATASTACK                   ; Push pointer to the data
        PEA.L   TRANSINFO                   ; Push pointer to message format.
        SYSCALL .WRITDLN                    ; System Call, write data message.

        PEA.L   DCDFHI                      ; Push Transfer Finished on stack.
        SYSCALL .WRITDLN                    ; System Call, write message.

        JMP     CYCLIC                      ; Return to the start of the
                                            ;   cyclic section.

*************************************************************************
*  Cyclic Section:   END because of time out looking for a free buffer. *
*                                                                       *
*  A free VBD Buffer was not found within the maximum wait time (number *
*  of test loops).  Both buffers must be stuck waiting to transfer on   *
*  the Data Cable.  Send a message to the 68020 console, then send a    *
*  Data Cable Driver Finished signal to the COMINT card, then return to *
*  the begining of the cyclic section.                                  *
*                                                                       *
*************************************************************************

BBSTMOUT  PEA.L    BBSTMMSG1                ; push message 1 address on stack.
          SYSCALL .WRITELN                  ; and send it out.
          PEA.L    BBSTMMSG2                ; push message 2 address on stack.
          SYSCALL .WRITELN                  ; and send it out.

        MOVE.B  #BIT1HIGH,D0                ; Send a Data Cable Driver
        WRIO    D0,DCDRFIN                  ;   Finished signal to COMINT.

LTSRHI  RDIO    SLVRDY                      ; Look for the Slave Ready.
        BEQ     LTSRHI                      ; If it is still high then keep
                                            ;   waiting until it drops then.

        MOVE.B  #ALLBITSLOW,D0              ; Drop the Data Cable Driver
        WRIO    D0,DCDRFIN                  ;   Finished signal.

        JMP     CYCLIC                      ; Return to the start of the
                                            ;   cyclic section.


*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section defines the Addresses of the Registers on the VBD card. *
*                                                                       *
*************************************************************************

VBDBASE       EQU     $FFFFA000        ; Base Address of the VBD's Registers

VBDCSR0       EQU     VBDBASE+$0000    ; VBD Control Status Reg 0
VBDCSR1       EQU     VBDBASE+$0002    ; VBD Control Status Reg 1
VBDCSR2       EQU     VBDBASE+$0004    ; VBD Control Status Reg 2
VBDCSR3       EQU     VBDBASE+$0006    ; VBD Control Status Reg 3
CRATETYPEREG  EQU     VBDBASE+$0008    ; Reg for Crate Type for VBD operation
EVTNMBADRREG  EQU     VBDBASE+$000A    ; Reg for the Adrs of the Event Number
CRTIDADRREG   EQU     VBDBASE+$000C    ; Reg for the Address of the Crate ID
DCONTROLREG   EQU     VBDBASE+$0010    ; Data Read Format Control Reg.
PCONTROLREG   EQU     VBDBASE+$0012    ; Parameter Read Format Control Reg.
IOUPADRSREG   EQU     VBDBASE+$0014    ; Parameter Read Adrs Bits 31-16
WCPNTLIST     EQU     VBDBASE+$1000    ; List of Pointers to Word Counts
DATAPNTLIST   EQU     VBDBASE+$1800    ; List of Base Adrs's of Data BLK's

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section defines the data loaded into registers on the VBD       *
*  card and masks used to test bits in status registers on the VBD.     *
*************************************************************************

VBDDMATO      DC.W    $000C          ; VBD DMA time-out value
VBDTOLOCK     DC.W    $001C          ; VBD DMA time-out value & Lock memory
VBDRESET      DC.W    $00CC          ; Reset the VBD and load DMA time-out
CRATETYPE     DC.W    $0001          ; Crate Type is 1  i.e. Calorimeter
DCTRLDATA     DC.W    $BD00          ; Control format of DMA reads A24-LW
PCTRLDATA     DC.W    $ED00          ; Control format of param reads A24-W
IOUPADRS      DC.W    $0000          ; Upper address bits for param reads

BUF0DMAGO     DC.W    $001D          ; Code to start the DMA running into
                                     ;   Buf 0,  also pick DMA time out and
                                     ;   keep the control memory write locked.
MSKBUF0STA    DC.L    $00000005      ; Mask to select from VBD CSR2 the bits
                                     ;   that indicate buf 0's  DMA status
                                     ;   and Buf 0's  port status.
MSKBUF0DMA    DC.L    $00000001      ; Mask to select from VBD CSR2 the bit
                                     ;   that indicate buf 0's  DMA status.

BUF1DMAGO     DC.W    $001F          ; Code to start the DMA running into
                                     ;   Buf 1,  also pick DMA time out and
                                     ;   keep the control memory write locked.
MSKBUF1STA    DC.L    $0000000A      ; Mask to select from VBD CSR2 the bits
                                     ;   that indicate buf 1's  DMA status
                                     ;   and Buf 1's  port status.
MSKBUF1DMA    DC.L    $00000002      ; Mask to select from VBD CSR2 the bit
                                     ;   that indicate buf 1's  DMA status.

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section specifies the storage location in Short IO Address      *
*  Space read by the VBD to obtain the crate ID from the Crate ID Card. *
*************************************************************************

CRATEIDADRS    DC.W    $C0D0          ; Address of Crate ID card in I/O space
                                      ; Address of Mike Shea's Crate ID card

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section defines the storage locations in the 2k byte Short IO   *
*  Address memory (Sort 214) that are used to store the Word Counts for *
*  the various Data Blocks, and the Event Number.                       *
*************************************************************************

IOMEMBASE     EQU     $9000            ; Base Address of the Short IO Memory
                                       ; i.e. starting adrs of the Short 214

EVTNMBADR     EQU     IOMEMBASE+$0010  ; Short IO Address Storage Location
                                       ; for Event Number for the VBD to read.

EVTNMBADR133  EQU     $FFFF0000+EVTNMBADR  ; MVME-133A version of the Short IO
                                           ; Address for the storage location
                                           ; for the Event Number.

WCSTORE1      EQU     IOMEMBASE+$0100  ; Storage location for the 1st Wrd Cnt
WCSTORE2      EQU     IOMEMBASE+$0102  ; Storage location for the 2nd Wrd Cnt
WCSTORE3      EQU     IOMEMBASE+$0104  ; Storage location for the 3rd Wrd Cnt
WCSTORE4      EQU     IOMEMBASE+$0106  ; Storage location for the 4th Wrd Cnt
WCSTORE5      EQU     IOMEMBASE+$0108  ; Storage location for the 5th Wrd Cnt

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section defines the list of Word Counts for the various blocks  *
*  of data from the Trigger Crate. (number of Long Words in each block) *
*************************************************************************

WCHEADER        DC.W    $0005          ; Define the Crate Header Word Count
WCL1TRGDB       DC.W    $0180          ; Define the L1 Trig Data Block WC
WC3RDBLK        DC.W    $00C0          ; Define the WC of the 3rd block
WC4THBLK        DC.W    $0010          ; Define the WC of the 4th block
WC5THBLK        DC.W    $0010          ; Define the WC of the 5th block

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section defines the list of Base Addresses for the various      *
*  blocks of data from the Trigger Crate.     (32 bit Base Addresses)   *
*************************************************************************

BAHEADER        DC.L    $002F5000      ; Define the Crate Header Base Address
                                       ; CRTHDWORD1
BAL1TRGDB       DC.L    $002F0000      ; Define the L1 Trig Data Block Base Ad
                                       ; TRGBUFFER
BA3RDBLK        DC.L    $002F4000      ; Define the Base Adrs of the 3rd block
BA4THBLK        DC.L    $002f0000      ; Define the Base Adrs of the 4th block
BA5THBLK        DC.L    $002f0000      ; Define the Base Adrs of the 5th block

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section specifies locations used the the 214 VMX to VME memory. *
*                                                                       *
*************************************************************************

TRGBUFFER    EQU   $00300000             ; L1 Data Block MVME214 base address

TRGFIRE      EQU   TRGBUFFER+$00000385   ; Spc Trig fired Adrs in MVME214.
                                         ; This is the 2nd byte of 4 bytes
                                         ; of Spc Trg Fired data.  It is the
                                         ; byte with the lowest address.

TRGNUM       EQU   TRGBUFFER+$00000285   ; Event Number Address in MVME214.
                                         ; This is the 2nd byte of the Event
                                         ; Number. It is the byte with the
                                         ; lowest address in the Data Block.

HEADBASE     EQU   $00305000             ; Crate Header  MVME214  Base Address

CRTHDWORD1   EQU   HEADBASE+$00000000    ; First long word of the Crate Header
                                         ;     This is the SYNC Word

CRTHDWORD2   EQU   HEADBASE+$00000004    ; 2nd long word of the Crate Header
                                         ;     This is the Controller word

CRTHDWORD3   EQU   HEADBASE+$00000008    ; 3rd long word of the Crate Header
                                         ;     This is the Version Number

CRTHDWORD4   EQU   HEADBASE+$0000000C    ; 4th long word of the Crate Header
                                         ;     This is the Revision Number

CRTHDWORD5   EQU   HEADBASE+$00000010    ; 5th long word of the Crate Header
                                         ;     This is the Spec Trig Fired Mask

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  Define miscellaneous constants.                                      *
*                                                                       *
*************************************************************************

DCDRFIN       EQU     $FFFFF003        ; addrs data cable driver finished port
SLVRDY        EQU     $FFFFF005        ; address of slave ready port

BIT1HIGH      EQU     $01              ; lowest bit in high state
ALLBITSLOW    EQU     $00              ; all bits low

LOW4LONG      DC.L    $0000000F        ; Low order 4 bits set, Mask for Sync.

TRGNUMSTORE   DC.L    $00000000        ; Store for 16 bit trigger number.

TRGSFIRED     DC.L    $00000000        ; Store Specific Trigs Fired longword.

MSKMONSPTRG   DC.L    $7FFFFFFF        ; Mask for non-monitor Spec Trigs
                                       ; a 1 in the mask -> normal Spec Trig
                                       ; a 0 in the mask -> monitor Spec Trig

SRLOOPCNT     DC.L    $00000000        ; Loop count of tests for Slave Ready
SRMAXWAIT     DC.L    $03000000        ; Max number of loops looking waiting
                                       ;   for Slave Ready to go high before
                                       ;   "resetting" COMINT by sending a
                                       ;   pulse on Data Cable Driver Finished.
                                       ;   $01000000 gives about 55 seconds.
SRMINDISP     DC.L    $00010000        ; Min number of loops waiting for Slave
                                       ;   Ready for the transfer rate to be
                                       ;   low enough to send full message
                                       ;   at the end of the transfer.
                                       ;   $00010000 implies a transfer rate
                                       ;   of 5 Hz or less for the full
                                       ;   message to be displayed.

BBSMAXWAIT    DC.L    $00200000        ; Max number of loops looking waiting
                                       ;   for a free VBD buffer before
                                       ;   concluding that both buffers are
                                       ;   stuck waiting to transfer on the
                                       ;   Data Cable. $0020000 implies max
                                       ;   wait of about 10 sec for a buffer.

WAITDMA       DC.L    $00040000        ; Maximum loop count to wait for the
                                       ;   VBD DMA cycle to complete.
                                       ;   About 1/2 second.

BUFSELECT     DC.L    $00000000        ; Buffer Select i.e. VBD BUFFER 0 or 1.

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

DATASTACK     DCB.L   8,$00000000      ; data stack for Write Line call

CS            DC.B    4,$1B,'[2J'      ; clear screan sequence.
HO            DC.B    6,$1B,'[1;1H'    ; home cursor sequence.

HELLO         DC.B    42,'Level 1 Trigger VBD Driver Program  Ver: 1'
INITCMPT1     DC.B    30,'Finished the initialization of'
INITCMPT2     DC.B    36,'the VBD, COMINT, and IRONICS modules'

DISPCRATE  DC.B  44,'Crate ID = |10,8|   Controller Word = |10,8|'
DISVERNUM  DC.B  56,'Version Number of the Trigger Data Block Format = |10,8|'
DISREVNO1  DC.B  53,'Revision Number in the Crate Header 4th word = |10,8|'
DISREVNO2  DC.B  57,'VME CPU Program Rev = |10,8Z|  COMINT PROMs Rev = |10,8Z|'
DISREVNO3  DC.B  57,'Look Up Sys Rev = |10,8Z|  Trigger Hardware Rev = |10,8Z|'

SRWAITMSG1    DC.B    43,$0D,$0A,'Slave Ready not seen within the max wait.'
SRWAITMSG2    DC.B    46,'Pulse the Data Cable Driver Finished signal.',$0D,$0A

MONMESSAGE  DC.B  51,$0D,$0A,'Data Block with only Monitor Data not transfered.'

GIVEUP0       DC.B    44,$0D,$0A,'The VBD Buffer 0 DMA cycle has timed out.',$0A
GIVEUP1       DC.B    44,$0D,$0A,'The VBD Buffer 1 DMA cycle has timed out.',$0A

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

CHAR0         DC.B    1,'0'            ; Character zero.
CHAR1         DC.B    1,'1'            ; Character one.

TRANSINFO   DC.B    48,$0D,$0A,'SYNC BITS = |10,2Z|   SPEC TRIG FIRED = |10,8|'
DCDFHI      DC.B    19,'Transfer Finished',$0D,$0A

*************************************************************************
*  Define Constants:                                                    *
*                                                                       *
*  This section defines the Base Address for the Pulsers for each of    *
*  the three Calorimeters and the Base Address where the Pulser         *
*  Programming Data is stored in the MVME-214 while it is waiting to    *
*  be readout by the VBD.                                               *
*************************************************************************

ECNPDBADR    EQU   $11FF1000             ; Cal ECN Pulser Data Base Adrs
CCPDBADR     EQU   $10FF1000             ; Cal CC  Pulser Data Base Adrs
ECSPDBADR    EQU   $12FF1000             ; Cal ECS Pulser Data Base Adrs

BLDPDBADR    EQU   $00304000             ; Pulser Data MVME-214 Base Adrs


*****************************************************************************
*  Subroutine Section                                                       *
*****************************************************************************

*****************************************************************************
*  Cyclic Section Subroutine   Get the Calorimeter Pulser Programming Data  *
*                              Start of the subroutine  GVPPD               *
*                                                                           *
*  Load a pattern into all of the Calorimeter Pulser data locations in      *
*  the MVME-214 module.  This pattern will be overwritten only if the       *
*  real pulsser data can be read over the Vertical Interconnect.            *
*****************************************************************************

GVPPD  MOVE.L  #$FFFFFFFF,BLDPDBADR+$100    ; Load $FFFF into the 1st longword
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$104    ; Load $FFFF into the 2nd longword
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$108
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$10C
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$110
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$114
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$118
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$11C
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$120
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$124
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$128
       MOVE.L  #$FFFFFFFF,BLDPDBADR+$12C

*****************************************************************************
*  Cyclic Section Subroutine   Get the Calorimeter Pulser Programming Data  *
*                                                                           *
*  Before trying to read the Calorimeter Pulser data via the Vertical       *
*  Interconnect change the Bus Error Vector to point to our own Bus         *
*  Error exception handler.   This routing starts at BUSEREXHD.             *
*****************************************************************************

       MOVE.L  #BUSEREXHD,$00000008          ; point the Bus Error vector
                                             ;  to our exception handler.

*****************************************************************************
*  Cyclic Section Subroutine   Get the Calorimeter Pulser Programming Data  *
*                                                                           *
*  Get the Pulser Programming Data from the 12 Calorimeter Pulsers.         *
*                                                                           *
*  Each Pulser contains 4 VME Words of data.  From each pulser read only    *
*  the 1st and the 3rd word.  Arrange these pulser programming data words   *
*  such that the 1st word is in the high part of a Longword and the 3rd     *
*  word is in the low part of the same Longword.                            *
*****************************************************************************

***       MOVE.W   ECNPDBADR+$0,BLDPDBADR+$100      ; CALN PLS0  1st word
***       MOVE.W   ECNPDBADR+$4,BLDPDBADR+$102      ; CALN PLS0  3rd word
***       MOVE.W  ECNPDBADR+$18,BLDPDBADR+$104      ; CALN PLS1  1st word
***       MOVE.W  ECNPDBADR+$1C,BLDPDBADR+$106      ; CALN PLS1  3rd word

       MOVE.W    CCPDBADR+$0,BLDPDBADR+$108      ; CALC PLS2  1st word
       MOVE.W    CCPDBADR+$4,BLDPDBADR+$10A      ; CALC PLS2  3rd word
       MOVE.W   CCPDBADR+$18,BLDPDBADR+$10C      ; CALC PLS3  1st word
       MOVE.W   CCPDBADR+$1C,BLDPDBADR+$10E      ; CALC PLS3  3rd word

***       MOVE.W   ECSPDBADR+$0,BLDPDBADR+$110      ; CALS PLS4  1st word
***       MOVE.W   ECSPDBADR+$4,BLDPDBADR+$112      ; CALS PLS4  3rd word
***       MOVE.W  ECSPDBADR+$18,BLDPDBADR+$114      ; CALS PLS5  1st word
***       MOVE.W  ECSPDBADR+$1C,BLDPDBADR+$116      ; CALS PLS5  3rd word
***       MOVE.W  ECSPDBADR+$10,BLDPDBADR+$118      ; CALS PLS6  1st word
***       MOVE.W  ECSPDBADR+$14,BLDPDBADR+$11A      ; CALS PLS6  3rd word
***       MOVE.W   ECSPDBADR+$8,BLDPDBADR+$11C      ; CALS PLS7  1st word
***       MOVE.W   ECSPDBADR+$C,BLDPDBADR+$11E      ; CALS PLS7  3rd word

       MOVE.W   CCPDBADR+$10,BLDPDBADR+$120      ; CALC PLS8  1st word
       MOVE.W   CCPDBADR+$14,BLDPDBADR+$122      ; CALC PLS8  3rd word
       MOVE.W    CCPDBADR+$8,BLDPDBADR+$124      ; CALC PLS9  1st word
       MOVE.W    CCPDBADR+$C,BLDPDBADR+$126      ; CALC PLS9  3rd word

***       MOVE.W  ECNPDBADR+$10,BLDPDBADR+$128      ; CALN PLSA  1st word
***       MOVE.W  ECNPDBADR+$14,BLDPDBADR+$12A      ; CALN PLSA  3rd word
***       MOVE.W   ECNPDBADR+$8,BLDPDBADR+$12C      ; CALN PLSB  1st word
***       MOVE.W   ECNPDBADR+$C,BLDPDBADR+$12E      ; CALN PLSB  3rd word

*****************************************************************************
*  Cyclic Section Subroutine   Get the Calorimeter Pulser Programming Data  *
*                                                                           *
*  We are finished using the Vertical Interconnect so Restore the           *
*  normal 133A Bug Bus Error Vector.                                        *
*****************************************************************************

       MOVE.L  #$FFF149E2,$00000008          ; Restore normal 133A Bug
                                             ;  Bus Error vector.

*****************************************************************************
*  Cyclic Section Subroutine   Get the Calorimeter Pulser Programming Data  *
*                                                                           *
*  Return from this subroutine call.                                        *
*****************************************************************************

       RTS



*************************************************************************
*  Bus Error Exception Handler                                          *
*                                                                       *
*  Mask the rerun bit in the Special Status Word and then just return.  *
*************************************************************************

        ORG     $20000              ; start of the Bus Error Exception Handler

BUSEREXHD  MOVE.W  (SP)+,D0                ; pull the Status Register
           MOVE.L  (SP)+,D1                ; pull the Program Counter
           MOVE.W  (SP)+,D2                ; pull the Format - Vector Offset
           MOVE.W  (SP)+,D3                ; pull the Internal Register
           MOVE.W  (SP)+,D4                ; pull the Special Status Register

           ANDI.W  #$FEFF,D4               ; Mask the rerun bus cycle bit

           MOVE.W  D4,-(SP)                ; push the Special Status Register
           MOVE.W  D3,-(SP)                ; push the Internal Register
           MOVE.W  D2,-(SP)                ; push the Format - Vector Offset
           MOVE.L  D1,-(SP)                ; push the Program Counter
           MOVE.W  D0,-(SP)                ; push the Status Register

           RTE


        END

