          IDENT SPI
          CIPPU
          TITLE OSM$SPI PP DRIVER
          COMMENT *SMD* LVL=01
          COMMENT COPYRIGHT CONTROL DATA SYSTEMS INC. 1992
          SPACE 4
**  NAME SPI, DECK NAME IS OSM$SPI_PP_DRIVER.
*
** PURPOSE: THE PURPOSE OF THIS PROGRAM IS TO READ THE CPU
*         PROGRAM REGISTER FROM THE MAINTENANCE CHANNEL AND  PLACE THE RESULT
*         IN A CENTRAL MEMORY BUFFER.
*
** DETAILS: THE PP GETS ITS INSTRUCTION FROM ONE OF TWO PLACES.
*         1) THE PP INTERFACE TABLE FOR IDLE AND RESUME.
*         2) THE COMMUNICATION BUFFER FOR SPI DATA COLLECTION.
*
*         THE COMMUNICATION BUFFER INITIALLY PROVIDES THE INFORMATION ON THE
*         TYPE OF COLLECTION THAT WILL BE PROCESSED BY THE PP. THIS INCLUDES
*         THE SPI IDENTIFIER FOR SELECTED SAMPLES, THE NUMBER OF SAMPLES,
*         THE INTERVAL BETWEEN SAMPLES, THE PP INTERRUPT PORT AND THE LOCATION
*         OF THE CENTRAL MEMORY BUFFERS. AS TIME PROGRESSES THE CP STATUS WILL
*         CHANGE TO ONE OF THE FOLLOWING STATES: 1) START 2) STOP OR
*         3) TERMINATE. THE PP WILL RESPOND TO THE CP STATES BY PLACING THE
*         PP STATE IN THE PP STATUS WORD OF THE COMMUNICATION BUFFER. THE DATA
*         COLLECTION WILL BE TO A POOL OF 2O48 BYTE BUFFERS. EACH BUFFER WILL BE
*         WITHIN A SINGLE PAGE. WHEN THE BUFFER IS FILLED THE STATUS IS CHANGED
*         TO FILLED WITH DATA, AN INTERRUPT IS GIVEN TO THE CP AND THE NEXT
*         BUFFER IS SELECTED. IF THE STATE OF THE NEXT BUFFER IS NOT AVAILABLE
*         FOR USE THEN THE PP WAITS FOR THE BUFFER TO BECOME AVAILABLE.
*         THE PAUSE LOOP IS MACHINE DEPENDENT AND ANY CHANGES TO THAT ROUTINE
*         SHOULD TAKE THE MACHINE DEPENDENCIES INTO ACCOUNT. THIS PROGRAM WAS
*         WRITTEN TO BE EASILY CHANGED WHEN VE SUPPORTS MORE THAN 2 PROGESSORS
*         ON A SINGLE CLUSTER.
          SPACE   4
*copyc IODMAC1 "{RECORD DEFINITION MACROS}
*copyc IODMAC2 "{LOAD/STORE MACROS}
*copyc IODMAC3 "{GENERAL MACROS}
*copyc IODMAC4 "{GENERAL MACROS}
*copyc dsi$maintenance_register_macros
*copyc dsa$hardware_table_definitions
*copyc dsi$pp_macros
*COPYC DSC$PP_MR_AND_TPM_CONSTANTS
*COPYC CTI$DFT_ANALYSIS_CODES
*COPYC CTC$EI_CONTROL_BLOCK
          EJECT


* EQUATES

 C.CHCNT  EQU    37          NUMBER OF REQUESTS TO PROCESS BEFORE
                             CLEARING CHANNEL LOCK
 RR       EQU    400000B     R-REGISTER ACTIVATION

* INTERFACE ERROR CODES.
 E501     EQU    2401B       INVALID COMMAND CODE
          SPACE  10
* SS TABLE DEFINITIONS. INFORMATION SAVED FOR EACH UNIT.

 SS       RECORD PACKED

* WORD 1

 CHAN     SUBRANGE 0,77B     CHANNEL NUMBER
 FILL1    SUBRANGE 0,77B
 SEEK     BOOLEAN            SEEK ISSUED
 CUR      BOOLEAN            CURRENT REQUEST HAS BEEN SELECTED (IF SET)
 DV       SUBRANGE 0,3       DEVICE TYPE

* WORDS 2 - 6 = PARAMETERS FOR LOAD COMMAND BLOCK FUNCTION.

 FILL2    SUBRANGE 0,7
 SMALL    BOOLEAN            512 BYTE SECTOR, IF SET
 PRIOV    BOOLEAN            PRIORITY OVERRIDE IF SET
 FILL3    SUBRANGE 0,37B
 CMOD     SUBRANGE 0,7       CONTROL MODULE NUMBER
 UNIT     SUBRANGE 0,7       UNIT NUMBER
*
 FUNC     PPWORD             FUNCTION CODE
*
 CYL      PPWORD             CYLINDER ADDRESS
*
 TRACK    SUBRANGE 0,377B    TRACK ADDRESS
 SECTOR   SUBRANGE 0,377B    SECTOR ADDRESS
*
 TLFLG    BOOLEAN            NONZERO MEANS USE TRANSFER LENGTH
 LENGTH   SUBRANGE 0,77777B  TRANSFER LENGTH

* WORD 7 - END = SAVED INFORMATION PER UNIT.

 FNC      PPWORD             FUNCTION CODE  READ = 0
                                            WRITE = 1
                                            WRITE INITIALIZE = 2
 REQ      STRUCT 4           CURRENT REQUEST (UNFORMATTED RMA)
 PVA      STRUCT 6           PVA OF CURRENT REQUEST

 LASTC    PPWORD             OFFSET OF COMMAND IN REQUEST
 QSEL     PPWORD             REQUEST SELECTION ALGORITHM
 FRST     PPWORD             = 0, IF FIRST TIME THROUGH UNCMND
 NUMCM    PPWORD             NUMBER OF COMMANDS LEFT TO PROCESS IN
                             THIS REQUEST
 LISTL    PPWORD             NUMBER OF CM WORDS IN ADDRESS-LENGTH PAIR LIST.
                             (INCLUDES THE NUMBER OF WORDS WHICH HAVENT
                             BEEN READ FROM CM.)
 TOTAL    STRUCT 4           TOTAL CM WORDS LEFT TO TRANSFER BEFORE TERMINATING
 FCOMRQ   STRUCT 4           FIRST COMPLETED REQUEST (RMA)
 CURRQ    STRUCT 4           CURRENT REQUEST (RMA)
 PRERQ    STRUCT 4           PREVIOUS REQUEST (RMA)
 NCOMRQ   PPWORD             NUMBER OF COMPLETED REQUESTS
 NCOMW    PPWORD             NUMBER OF COMPLETED WRITE REQUESTS
 CURTRK   PPWORD             CURRENT TRACK
 CURSEC   PPWORD             CURRENT SECTOR
 SWFLG    PPWORD             NONZERO IF A STREAMING REQUEST SWITCH WAS MADE
 RVCNT    PPWORD             COUNT OF RECOVERED ERRORS PER REQUEST
 RQTRY    PPWORD             REQUEST RETRY COUNT
 ADERR    PPWORD             ADAPTER ERROR
 NR       PPWORD             NOT READY RETRY COUNT
 LAD      PPWORD             LOAD ADAPTER RETRY COUNTER
 CMLD     PPWORD             CM LOAD RETRY COUNTER
 PRELD    PPWORD             PRELOAD OF CONTROL MODULE IF NONZERO
 DIAG     PPWORD             NONZERO IF RUNNING LEVEL II DIAGNOSTICS
 DIAGS    PPWORD             NONZERO IF RUNNING DIAGNOSTICS COMMAND 72
 RECOV    PPWORD             NONZERO IF IN RECOVERY


* CURRENT REQUEST.  MUST BE ALIGNED ON A WORD BOUNDARY.

          ALIGN  0,64
 RQ       STRUCT 40          REQUEST

 CMLIST   STRUCT 8           CURRENT DATA ADDRESS OR CURRENT COMMAND

* RESPONSE.

 RS       STRUCT 152         RESPONSE
          MGEN   N.CUR
 M.CUR    EQU    MASK$
          MGEN   N.SEEK
 M.SEEK   EQU    MASK$
          MASKP  SEEK
 K.SEEK   EQU    MSK
          MASKP  CUR
 K.CUR    EQU    MSK
          MGEN   N.CHAN
 M.CHAN   EQU    MASK$
          MGEN   N.DV
 M.DV     EQU    MASK$
          MASKP  SMALL
 K.SMALL  EQU    MSK
          MGEN   N.SMALL
 M.SMALL  EQU    MASK$
          MASKP  PRIOV
 K.PRIOV  EQU    MSK
          MGEN   N.UNIT
 M.UNIT   EQU    MASK$
          MASKP  UNIT
 K.UNIT   EQU    MSK
          MASKP  CMOD
 K.CMOD   EQU    MSK
          MGEN   N.CMOD
 M.CMOD   EQU    MASK$
          MGEN   N.TRACK
 M.TRACK  EQU    MASK$
          MGEN   N.SECTOR
 M.SECTOR EQU    MASK$

 SS       RECEND
          SPACE  6
* PP TABLE.

 PT       RECORD PACKED

 PPNO     PPWORD             PP NUMBER
 PART     PPWORD             PARTNER PP NUMBER
 PIT      RMA                PP INTERFACE TABLE ADDRESS (RMA)
 PITPVA   STRUCT 24          PP INTERFACE TABLE ADDRESS (PVA)

 PT       RECEND
          SPACE  6
* PP INTERFACE TABLE
 PIT      RECORD PACKED

 PPNO     PPWORD             PP NUMBER
 FLU      PPWORD             FIRST LOGICAL UNIT
 UNITC    PPWORD             NUMBER OF UNITS
          ALIGN  0,64
 INT      RMA                INTERRUPT WORD (RMA)
 CHAN     RMA                CHANNEL TABLE (RMA)
          ALIGN  16,64
 CBUFL    PPWORD             COMMUNICATION BUFFER LENGTH
 CBUF     RMA                COMMUNICATION BUFFER (RMA)
 LOCK     BOOLEAN            PP REQUEST QUEUE LOCK
          ALIGN  48,64
 LOCKPP   PPWORD             PP REQUEST QUEUE LOCK OWNER
          ALIGN  16,64
 PPQPVA   STRUCT 6           NEXT QUEUED PP REQUEST (PVA)
          ALIGN  32,64
 PPQ      RMA                NEXT QUEUED PP REQUEST (RMA)
          ALIGN  16,64
 RSPVA    STRUCT 14          RESPONSE BUFFER (PVA)
          ALIGN  32,64
 RSBUF    RMA                RESPONSE BUFFER (RMA)
          ALIGN  48,64
 IN       PPWORD             IN POINTER
          ALIGN  48,64
 OUT      PPWORD             OUT POINTER
          ALIGN  48,64
 LIMIT    PPWORD             LIMIT POINTER

 PIT      RECEND
          SPACE  6
* PP REQUESTS.

 RQ       RECORD PACKED

          ALIGN  16,64
 NEXTPV   STRUCT 6           NEXT REQUEST ON UNIT QUEUE (PVA)
          ALIGN  32,64
 NEXT     RMA                NEXT REQUEST ON UNIT QUEUE (RMA)
 LEN      PPWORD             REQUEST LENGTH
 LU       PPWORD             LOGICAL UNIT
 RECOV    SUBRANGE 0,3       ERROR RECOVERY OPTIONS
                               0 - ATTEMPT RECOVERY
                               1 - SUPPRESS RECOVERY, TERMINATE WITH
                                    ABNORMAL STATUS.
                               2 - RESERVED FOR FUTURE USE.
                               3 - SUPPRESS RECOVERY, CONTINUE THE REQUEST
                                    IGNORING ERROR CONDITIONS.
 INT      BOOLEAN            INTERRUPT CPU (IF SET)
 PORT     SUBRANGE 0,37B     MEMORY PORT USED FOR INTERRUPTS
          ALIGN  40,64
 PRIOR    SUBRANGE 0,377B    PRIORITY
          ALIGN  48,64
          ALIGN  49,64       ALERT MASK
 COMPAR   BOOLEAN            COMPARE NOT SATISFIED ON COMPARE/SWAP COMMAND
          ALIGN  0,64
 SWIT     BOOLEAN            SWITCH TO NEXT REQUEST
          ALIGN  16,64
 CYL      PPWORD             CYLINDER ADDRESS
 TRACK    PPWORD             TRACK ADDRESS
 SECTOR   PPWORD             SECTOR ADDRESS
 CMND     INTEGER            COMMAND SEQUENCE


          MASKP  INT
 K.INT    EQU    MSK
          MGEN   N.PORT
 M.PORT   EQU    MASK$

 RQ       RECEND
          SPACE  6
* PP COMMAND.

 CM       RECORD PACKED

 CODE     SUBRANGE 0,377B    COMMAND CODE
 STOR     BOOLEAN            STORE RESPONSE (IF SET)
 INDIR    BOOLEAN            INDIRECT ADDRESS (IF SET)
          ALIGN  16,64
 LEN      PPWORD             LENGTH OF CM AREA (EITHER DATA AREA OR
                             LENGTH/ADDRESS WORD PAIR LIST)
 RMA      RMA                ADDRESS OF CM AREA
          MGEN   N.CODE
 M.CODE   EQU    MASK$

 CM       RECEND
          SPACE  6
* COMMAND CODES.

 C.IDLE   EQU    4           IDLE
 C.RESUME EQU    5           RESUME
          SPACE  6
* PP RESPONSE.

 RS       RECORD PACKED

* WORD 1.
          ALIGN  16,64
 PVA      STRUCT 6           PVA OF REQUEST

* WORD 2.
          ALIGN  32,64
 REQ      RMA                RMA OF REQUEST  (NOT USED)

* WORD 3.
 RESPL    PPWORD             RESPONSE LENGTH  (8-BIT BYTES)
 LU       PPWORD             LOGICAL UNIT
 RECOV    SUBRANGE 0,3       ERROR RECOVERY OPTIONS (FROM REQUEST) (NOT USED)
 INT      BOOLEAN            INTERRUPT CPU (IF SET)  (NOT USED)
 PORT     SUBRANGE 0,37B     MEMORY PORT USED FOR INTERRUPTS  (NOT USED)
          ALIGN  40,64
 PRIOR    SUBRANGE 0,377B    PRIORITY  (NOT USED)
          ALIGN  48,64
          ALIGN  49,64       ALERT MASK
 COMPAR   BOOLEAN            COMPARE NOT SATISFIED ON COMPARE/SWAP COMMAND
                             (NOT USED)

* WORD 4.
          ALIGN  0,64
 ABALRT   BOOLEAN            ABNORMAL ALERT CONDITION DETECTED  (NOT USED)
 INTERR   BOOLEAN            LOGICAL INTERFACE ERROR (INCLUDE INTERFACE
                             ERROR CODE)
 FORC     BOOLEAN            FORCED TERMINATION AS A RESULT OF STOP UNIT COMMAND
                             (NOT USED)
 CHERR    BOOLEAN            CHANNEL PARITY ERROR
 DATOV    BOOLEAN            DATA OVERRUN. A LOST DATA CONDITION
                             OCCURRED ON INPUT OR INADEQUATE DATA RATE ON OUTPUT
                             (NOT USED)
 DATERR   BOOLEAN            UNCORRECTABLE PARITY OR CHECKWORD ERROR
                             ON AN ADDRESS OR DATA FIELD.
 HDWR     BOOLEAN            UNCORRECTABLE HARDWARE MALFUNCTION IN A
                             CONTROLLER OR UNIT  (NOT USED)
 NRDY     BOOLEAN            INTERVENTION REQUIRED BY OPERATOR ON A
                             HARDWARE MALFUNCTION.  EX: UNIT NOT READY,
                             UNIT NOT CONNECTED.  (NOT USED)
 FTO      BOOLEAN            FUNCTION TIMEOUT
 CHERO    BOOLEAN            CHANNEL OUTPUT PARITY ERROR
          ALIGN  16,64
 IEC      PPWORD             INTERFACE ERROR CODE
 RC       SUBRANGE 0,3       RESPONSE CODE
                               0 - UNSOLICITED RESPONSE
                               1 - INTERMEDIATE RESPONSE
                               2 - NORMAL REQUEST TERMINATION
                               3 - ABNORMAL REQUEST TERMINATION
 RCON     SUBRANGE 0,3       ADDITIONAL RESPONSE CONDITIONS
                             (= 0 FOR UNSOLICITED RESPONSE)
                               0 - NO ADDITIONAL CONDITION
                               1 - RECOVERED ERROR
                               2 - COMMAND HAD EXPLICIT RESPONSE FLAG SET
                               3 - BOTH CONDITIONS 1 AND 2
 K.REC    EQU    1           RECOVERED ERROR
          ALIGN  40,64
 URC      SUBRANGE 0,377B    UNSOLICITED RESPONSE CODE  (NOT USED)
                               1 - UNIT CHANGED FROM READY TO NOT READY
                               2 - UNIT CHANGED FROM NOT READY TO READY
                               3 - ABNORMAL CONDITION DURING HOUSEKEEPING CYCLE,
                                   (CHECK ABNORMAL STATUS OR INTERFACE ERROR CODE)
                               4 - CONTROLLER RESERVED
                               5 - UNIT RESERVED TO ANOTHER ACCESS
                               6 - RECOVERED ABNORMAL CONDITION
          ALIGN  49,64       ALERT CONDITIONS
 COMPRC   BOOLEAN            COMPARE NOT SATISFIED ON COMPARE/SWAP COMMAND
                             (NOT USED)

* WORD 5.
          ALIGN  0,64
 XFER     STRUCT 4           TRANSFER COUNT
 LASTC    RMA                LAST COMMAND (RMA)

 CHAN     PPWORD             CHANNEL NUMBER
 SCYL     PPWORD             STARTING CYLINDER
 STRK     PPWORD             STARTING TRACK
 SSEC     PPWORD             STARTING SECTOR

 UNIT     PPWORD             UNIT NUMBER
 RTRY     PPWORD             REQUEST RETRY COUNT
 FTRK     PPWORD             FAILING TRACK
 FSEC     PPWORD             FAILING SECTOR

 DET      PPWORD             =1, IF DETAILED STATUS PRESENT
 ID       PPWORD             ERROR IDENTIFIER
 K.CMLD   EQU    1           RELOAD OF CONTROL MODULE WAS ATTEMPTED
 K.CMLDS  EQU    2           CONTROL MODULE RELOADED SUCCESSFULLY
 K.XD     EQU    4           EXECUTING LEVEL II DIAGNOSTICS
 K.XDP    EQU    10B         LEVEL II DIAGNOSTICS PASSED
 K.PU     EQU    20B         POWERING UP SPINDLE
 K.PUC    EQU    40B         SPINDLE POWERED UP
 K.PTO    EQU    100B        PP TIMED OUT A COMMAND
 K.UDN    EQU    20000B      UNIT DOWN
 K.CMDN   EQU    40000B      CONTROL MODULE DOWN
 K.CHDN   EQU    100000B     CHANNEL DOWN
 FILL2    PPWORD
 STRY     PPWORD             SECTOR RETRY COUNT

 GENST1   PPWORD             GENERAL STATUS OF THE FIRST TIME ERROR
                               WAS ENCOUNTERED
 GENST2   PPWORD             GENERAL STATUS OF THE LAST TIME ERROR
                               WAS ENCOUNTERED
 FUNTO    PPWORD             FUNCTION CODE IF FUNCTION TIMEOUT ERROR
 ERRID    PPWORD             ERROR IDENTIFIER
 K.IST    EQU    1           INCOMPLETE SECTOR TRANSFER
 K.CRES   EQU    2           CLEAR UNIT RESERVE ON OPPOSITE ACCESS
 K.RAM    EQU    4           RAM PARITY ERROR
 K.CLOAD  EQU    10B         CONTROLWARE LOAD WAS ATTEMPTED
 K.AFT    EQU    20B         AUTOLOAD FUNCTION TIMEOUT
 K.CEMPT  EQU    40B         CHANNEL DOESNT GO EMPTY AFTER SENDING
                             PARAMETERS / DATA
 K.CINAC  EQU    100B        CHANNEL NOT INACTIVE AFTER
                             RECEIVING PARAMETERS / DATA
 K.MEDIA  EQU    200B        MEDIA FAILURE, REREAD SECTOR
 K.UNMED  EQU    400B        UNRECOVERED MEDIA ERROR
 K.RERR   EQU    1000B       READ ERROR.  STATUS BEFORE SUSPEND/TERMINATE .NE.
                             4XXXB.
 K.CF     EQU    2000B       POLL STATUS NONZERO AFTER SENDING CONTROLWARE
 K.DE     EQU    4000B       POLL STATUS NONZERO AFTER LOADING ATTENTION DELAY
 K.NR     EQU    10000B      NOT READY
 K.URS    EQU    20000B      UNIT RESERVED
 K.CRS    EQU    40000B      CONTROLLER RESERVED
 K.ADPT   EQU    100000B     ADAPTER CONTROLWARE ERROR
          ALIGN  0,64
 DETAIL   STRUCT 40          DETAILED STATUS OF THE FIRST TIME ERROR
                             WAS ENCOUNTERED
 DET2     STRUCT 40          DETAILED STATUS OF THE LAST TIME ERROR
                             WAS ENCOUNTERED.


          MASKP  INT
 K.INT    EQU    MSK
          MGEN   N.PORT
 M.PORT   EQU    MASK$
          MASKP  INTERR
 K.INTERR EQU    MSK
          MASKP  DATOV
 K.DATOV  EQU    MSK
          MASKP  DATERR
 K.DATERR EQU    MSK
          MASKP  HDWR
 K.HDWR   EQU    MSK
          MASKP  CHERR
 K.CHERR  EQU    MSK
          MASKP  CHERO
 K.CHERO  EQU    MSK
          MASKP  NRDY
 K.NRDY   EQU    MSK
          MASKP  FTO
 K.FTO    EQU    MSK

 RS       RECEND
          SPACE  6
* RESPONSE CODES.
 R.UNS    EQU    0           UNSOLICITED RESPONSE
 R.INT    EQU    1           INTERMEDIATE RESPONSE
 R.NRM    EQU    2           NORMAL REQUEST TERMINATION
 R.ABN    EQU    3           ABNORMAL REQUEST TERMINATION
          SPACE  10
* PP COMMUNICATION BUFFER.

 CB       RECORD PACKED

 PPBUF    PPWORD             BUFFER NUMBER BEING PROCESSED BY PP
 B.LOW    EQU    1           VALUE OF THE LOWEST BUFFER NUMBER
 B.HIGH   EQU    16D         VALUE OF THE HIGHEST BUFFER NUMBER
 PPOFF    PPWORD             OFFSET INTO PP BUFFER
 PPSTAT   PPWORD             PP GENERAL OPERATION STATUS
 S.PWAIT  EQU    6           WAITING TO START PROCESSING
 S.PCOL   EQU    7           COLLECTING DATA
 S.PSTOP  EQU    8           STOPPED COLLECTING DATA
 S.PTERM  EQU    9           TERMINATED DATA COLLECTING
          PPWORD

* SECOND WORD OF CB

 CPBUF    PPWORD             BUFFER NUMBER LAT PROCESSED BY CP
 CPSTAT   PPWORD             CP COLLECTOR STATUS REQUEST
 S.INIT   EQU    1           COMMUNICATION BUFFER IS INITIALIZED
 S.START  EQU    2           START COLLECTING
 S.STOP   EQU    3           STOP COLLECTING
 S.TERM   EQU    4           TERMINATE COLLECTING
 S.COMP   EQU    5           PROCESS COMPLETE
 SPIID    PPWORD             SPI ID NUMBER
 P0       BOOLEAN            PROCESSOR SELECT FLAG
 P1       BOOLEAN            PROCESSOR SELECT FLAG
 P2       BOOLEAN            PROCESSOR SELECT FLAG FUTURE USE
 P3       BOOLEAN            PROCESSOR SELECT FLAG FUTURE USE
 P4       BOOLEAN            PROCESSOR SELECT FLAG FUTURE USE
 P5       BOOLEAN            PROCESSOR SELECT FLAG FUTURE USE
 P6       BOOLEAN            PROCESSOR SELECT FLAG FUTURE USE
 P7       BOOLEAN            PROCESSOR SELECT FLAG FUTURE USE
 IPORT    CHARC              INTERRUPT PORT FOR INTERRUPT INSTRUCTION

* THIRD WORD OF CB

 SAMP     STRUCT 4           NUMBER OF SPI SAMPLES
 TIME     STRUCT 4           TIME BETWEEN SAMPLES

* FOURTH WORD OF CB

 BOFF1    PPWORD             OFFSET IN BUFFER
 BST1     PPWORD             STATUS OF BUFFER
 S.AVAIL  EQU    1           BUFFER IS AVAILABLE FOR PP USE
 S.INUSE  EQU    2           BUFFER IN USE BY PP
 S.DATA   EQU    3           BUFFER HAS DATA FOR CPU TO COPY
 BRMA1    RMA                RMA OF BUFFER
 BPVA1    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF2    PPWORD             OFFSET IN BUFFER
 BST2     PPWORD             STATUS OF BUFFER
 BRMA2    RMA                RMA OF BUFFER
 BPVA2    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF3    PPWORD             OFFSET IN BUFFER
 BST3     PPWORD             STATUS OF BUFFER
 BRMA3    RMA                RMA OF BUFFER
 BPVA3    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF4    PPWORD             OFFSET IN BUFFER
 BST4     PPWORD             STATUS OF BUFFER
 BRMA4    RMA                RMA OF BUFFER
 BPVA4    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF5    PPWORD             OFFSET IN BUFFER
 BST5     PPWORD             STATUS OF BUFFER
 BRMA5    RMA                RMA OF BUFFER
 BPVA5    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF6    PPWORD             OFFSET IN BUFFER
 BST6     PPWORD             STATUS OF BUFFER
 BRMA6    RMA                RMA OF BUFFER
 BPVA6    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF7    PPWORD             OFFSET IN BUFFER
 BST7     PPWORD             STATUS OF BUFFER
 BRMA7    RMA                RMA OF BUFFER
 BPVA7    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF8    PPWORD             OFFSET IN BUFFER
 BST8     PPWORD             STATUS OF BUFFER
 BRMA8    RMA                RMA OF BUFFER
 BPVA8    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF9    PPWORD             OFFSET IN BUFFER
 BST9     PPWORD             STATUS OF BUFFER
 BRMA9    RMA                RMA OF BUFFER
 BPVA9    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF10   PPWORD             OFFSET IN BUFFER
 BST10    PPWORD             STATUS OF BUFFER
 BRMA10   RMA                RMA OF BUFFER
 BPVA10   STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF11   PPWORD             OFFSET IN BUFFER
 BST11    PPWORD             STATUS OF BUFFER
 BRMA11   RMA                RMA OF BUFFER
 BPVA11   STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF12   PPWORD             OFFSET IN BUFFER
 BST12    PPWORD             STATUS OF BUFFER
 BRMA12   RMA                RMA OF BUFFER
 BPVA12   STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF13   PPWORD             OFFSET IN BUFFER
 BST13    PPWORD             STATUS OF BUFFER
 BRMA13   RMA                RMA OF BUFFER
 BPV13    STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF14   PPWORD             OFFSET IN BUFFER
 BST14    PPWORD             STATUS OF BUFFER
 BRMA14   RMA                RMA OF BUFFER
 BPVA14   STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF15   PPWORD             OFFSET IN BUFFER
 BST15    PPWORD             STATUS OF BUFFER
 BRMA15   RMA                RMA OF BUFFER
 BPVA15   STRUCT 6           PVA OF BUFFER
          PPWORD

 BOFF16   PPWORD             OFFSET IN BUFFER
 BST16    PPWORD             STATUS OF BUFFER
 BRMA16   RMA                RMA OF BUFFER
 BPVA16   STRUCT 6           PVA OF BUFFER
          PPWORD

 CB       RECEND
          EJECT
          CON    INIT-1


* DIRECT CELLS

 CM.PIT   BSSZ   3           CM ADDRESS OF PP INTERFACE TABLE (REFORMATED)

 T1       BSSZ   1
 T2       BSSZ   1
 T3       BSSZ   1
 T4       BSSZ   1
 T5       BSSZ   1
 T6       BSSZ   1
 T7       BSSZ   1
 T8       BSSZ   1
 CM       BSSZ   4

 CMADR    BSSZ   3           CM ADDRESS
 CHAN     BSSZ   1           CHANNEL NUMBER
 P0       BSSZ   1           P SERIES USED BY PP DRIVER CODE
 W0       EQU    P0          W SERIES USED BY THE DEADSTART CODE
 P1       BSSZ   1
 W1       EQU    P1
 P2       BSSZ   1
 W2       EQU    P2
 P3       BSSZ   1
 W3       EQU    P3
 P4       BSSZ   1
 W4       EQU    P4
 P5       BSSZ   1
 W5       EQU    P5
 P6       BSSZ   1
 W6       EQU    P6
 WC       BSSZ   1           WORD COUNT TO READ/WRITE CM WORDS
 TM       BSSZ   2           TIMER COUNT DOWN UNTIL NEXT SAMPLE
 BN       BSSZ   1           CURRENT PROCESSING BUFFER NUMBER
 BA       BSSZ   1           ADDRESS OF REFORMATTED CENTRAL BUFFER
 FNC      BSSZ   1           FUNCTION CODE (INTERNAL)
 RESPC    BSSZ   1           RESPONSE CODE
 SSUN     CON    7777B       UX VALUE OF CURRENT SS TABLE
 CHLOCK   BSSZ   1           SET NONZERO IF CHANNEL LOCK IS SET
 IDLE     BSSZ   1           NONZERO IF IDLE COMMAND RECEIVED,
                               RESUME COMMAND RESETS IT TO 0
 PPRQ     BSSZ   1           PP REQUEST FLAG
 EC       BSSZ   1           MAINTENANCE REGISTER EQUIPEMENT CODE
 EC0      BSSZ   1           EQUIPEMNT CODE FOR PROCESSOR 0
 EC1      BSSZ   1           EQUIPMENT CODE FOR PROCESSOR 1
 MD       BSSZ   1           MODEL NUMBER
 RN       BSSZ   1           REGISTER NUMBER
 IB       BSSZ   2           EICB ACCESS
 HP       BSSZ   2           HOLD R REGISTER
 LFF00    BSSZ   1
          SPACE  3
          ORG    72B

 DSRTP    CON    0           HCS REAL MEMORY WORD-ADDRESS
          CON    1
 NODEL    EQU    DSRTP       DON'T DELINK REQUEST FLAG
 INPNT    EQU    DSRTP+1     IN POINTER FOR RESPONSE BUFFER
 LIM      BSSZ   1           LIMIT OF RESPONSE BUFFER (IN 8-BIT BYTES)
 PPNO     CON    1           LOGICAL PP NUMBER
          ORG    76B
          CON    5           TEMPORARY, PP TYPE USED BY DEADSTART
 LDCMF    EQU    76B         LOAD CONTROL MODULE, IF NONZERO
 ON       CON    1           CONSTANT 1 MAINLY USED FOR SINGLE WORD TRANSFERS
          EJECT
          ORG    100B
 START    LJM    INIT
          SPACE  6
 CM.CB    BSSZ   3           CM ADDRESS OF PP COMMUNICATION BUFFER (REFORMATTED)
 CM.RS    BSSZ   3           CM ADDRESS OF RESPONSE BUFFER (REFORMATTED)
 CM.INT   BSSZ   3           CM ADDRESS OF INTERRUPT WORD
 CM.CHAN  BSSZ   3           CM ADDRESS OF CHANNEL INTERLOCK TABLE
 CM.BF1   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF2   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF3   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF4   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF5   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF6   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF7   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF8   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF9   BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF10  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF11  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF12  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF13  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF14  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF15  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.BF16  BSSZ   3           CM ADDRESS OF SPI DATA BUFFER (REFORMATTED)
 CM.CBUF  BSSZ   3           CM ADDRESS OF CURRENT SPI BUFFER (REFORMATTED)
 BUFS     BSSZ   4
 MAXOFF   CON    256D        MAXIMUM NUMBER OF WORDS IN ONE SPI COLLECTION PAGE
 RDATA    BSSZ   8           CONTENTS OF P REGISTER
          BSSZ   3           REQUIRED TO BE BEFORE HBUF. DO NOT CHANGE OR MOVE.
 HBUF     BSSZ   CMXLEN      HARDWARE ELEMENT BUFFER
          SPACE  2
          EJECT
 SPI      BSS

** NAME - MAIN   THE MAIN PROCESSING LOOP
*
** PURPOSE THIS IS THE MAIN PROCESSING LOOP FO THE SPI DATA COLLECTOR.
*         IT CHECKS FOR ANY COMMANDS ON THE PP REQUEST QUEUE AND WILL
*         PROCESS THOSE REQUESTS. IF THE PP HAS NOT BEEN IDLED THEN
*         THE PP WILL COLLECT P REGISTER SAMPLES. AFTER THAT IT WILL
*         WAIT FOR 1 MS BEFORE TRYING AGAIN. THE ONLY VALID COMMANDS
*         FOR THIS PP FROM THE PP INTERFACE TABLE ARE IDLE AND RESUME.
*
** USES   MACRO PAUSE


 MAIN10   BSS
          RJM    PPREQ       CHECK FOR ANY PP REQUESTS
          ZJN    MAIN40      IF NO PP REQUESTS
          RJM    SRESP       SET UP RESPONSE BUFFER
 MAIN20   RJM    UNCMND      GET PP COMMAND AND SET UP TO PROCESS
          ZJN    MAIN35      IF NO MORE COMMANDS
          LDML   UCMDPR,FNC  GET COMMAND PROCESSOR. FNC SET BY UNCMND.
          STML   MAINA
          RJM    **          PROCESS COMMAND
 MAINA    EQU    *-1
          LDDL   RESPC       CHECK FOR ABNORMAL RESPONSE CODE
          SBN    R.ABN
          NJK    MAIN20      IF NO ERROR, LOOK FOR ANOTHER COMMAND

 MAIN35   RJM    TERMP       SEND TERMINATION RESPONSE

 MAIN40   BSS
          LDDL   IDLE
          NJK    MAIN10      IF IDLE COMMAND, ONLY PROCESS PP REQUESTS

          RJM    COLP        COLLECT P SAMPLES
          PAUSE  1000D       WAIT 1 MS BEFORE TRYING AGAIN
          UJK    MAIN10


* PP COMMAND PROCESSORS.

 UCMDPR   BSS
          CON    IDLEP       IDLE
          CON    RESUME      RESUME
          EJECT
** NAME-- SRESP
*
** PURPOSE-- SET UP STATUS RESPONSE BUFFER.
          SPACE  6
 SREX     LJM    **
 SRESP    EQU    *-1
          RJM    ZRESP         ZERO OUT RESPONSE BUFFER
          LDML   SS+/SS/P.PVA  PUT PVA OF REQUEST IN RESPONSE BUFFER
          STML   RS+/RS/P.PVA
          LDML   SS+/SS/P.PVA+1
          STML   RS+/RS/P.PVA+1
          LDML   SS+/SS/P.PVA+2
          STML   RS+/RS/P.PVA+2
*
          LDN    0
          STML   RS+/RS/P.XFER  CLEAR TRANSFER COUNT
          STML   RS+/RS/P.XFER+1
          UJK    SREX           RETURN
          EJECT
** NAME-- UNCMND
*
** PURPOSE-- GET NEXT COMMAND.
*
** INPUT-- NUMCM, FRST, RS+/RS/P.LASTC
*
** OUTPUT-- CMLIST, FNC, RQ+/RQ/P.CMND
*           LISTL.
*
** EXIT-- (A) = 0, IF NO MORE COMMANDS.
*         (A) .NE. 0, IF NEXT COMMAND PRESENT.
*         EXIT VIA ATERM IF COMMAND IS NOT IDLE OR RESUME
          SPACE  6
 UNCX     LJM    **
 UNCMND   EQU    *-1
          LDML   SS+/SS/P.NUMCM
          ZJN    UNCX        IF NO MORE COMMANDS, EXIT, A REGISTER = 0
          SOML   SS+/SS/P.NUMCM  DECREMENT COMMAND COUNT
          LDML   SS+/SS/P.FRST  HAS FIRST COMMAND BEEN PROCESSED
          ZJN    UNC10       IF FIRST COMMAND HASN'T BEEN PROCESSED

*         READ NEXT COMMAND FROM CM.

          AOML   SS+/SS/P.LASTC  INCREMENT OFFSET OF LAST COMMAND
          LDN    C.CM
          STDL   WC
          LOADF  SS+/SS/P.REQ  LOAD CM ADDRESS AND REFORMAT
          ADML   SS+/SS/P.LASTC  ADD OFFSET OF COMMAND
          CRML   CMD,WC       READ COMMAND FROM CM

*         IF INDIRECT ADDRESS, READ CM ADDRESS LIST.

 UNC10    BSS
          LDML   CMD+/CM/P.LEN  MAKE SURE IT IS AN EVEN NUMBER OF CM WORDS
          ADN    7
          SCN    7
          STML   CMD+/CM/P.LEN
          STML   CMLIST+/CM/P.LEN
          SHN    -3          CHANGE BYTE COUNT TO WORD COUNT
          STML   SS+/SS/P.LISTL  LENGTH OF CM ADDRESS AREA  (CM WORDS)
          LDML   CMD+/CM/P.INDIR
          SHN    /CM/L.INDIR+2
          MJN    UNC15       IF INDIRECT ADDRESS
          LDN    1
          STML   SS+/SS/P.LISTL  IF NOT INDIRECT, ONLY 1 COMMAND.
          LDML   CMD+/CM/P.RMA
          STML   CMLIST+/CM/P.RMA
          LDML   CMD+/CM/P.RMA+1
          STML   CMLIST+/CM/P.RMA+1
          UJN    UNC20

 UNC15    BSS
          RJM    GLIST       GET CM ADDRESS LIST OF DATA AREA

* IF SWITCH FLAG IS SET, EXIT.

 UNC20    BSS

*         SET UP INTERNAL FUNCTION CODE, FNC.

          LDN    0
          STDL   FNC         SET UP INTERNAL FUNCTION CODE
 UNC30    LDML   CMD+/CM/P.CODE  GET COMMAND CODE
          SHN    -16+/CM/N.CODE+/CM/L.CODE
          ERRNZ  /CM/L.CODE
          SBML   UCMD,FNC    COMPARE COMMAND CODE
          ZJN    UNC40       IF COMMAND FOUND
          AODL   FNC
          SBN    UCMDL
          MJN    UNC30       IF MORE COMMANDS TO CHECK
 UNC35    BSS
          LDC    E501        ERROR IN COMMAND CODE
          RJM    ATERM       ABNORMAL TERMINATION (NO RETURN)
*         (NO RETURN FROM ATERM)

 UNC40    BSS
          LDDL   FNC
          STML   SS+/SS/P.FNC  SAVE COMMAND CODE
          AOML   SS+/SS/P.FRST  SET FIRST COMMAND FLAG NONZERO
          UJK    UNCX        RETURN A REGISTER NONZERO

* PP COMMANDS.

 UCMD     BSS
          CON    C.IDLE
          CON    C.RESUME
 UCMDL    EQU    *-UCMD
          EJECT
** NAME -- COLP COLLECT P REGISTER VALUES
*
** PURPOSE COLLECT P REGISTER SAMPLES
*
** READS COMMUNICATION BUFFER FOR OPERATING STATUS
*  READS THE P VALUE AT THE APPROPRIATE TIME
*  UPDATE THE SPI DATA BUFFER IN CENTRAL MEMORY
*  GET NEXT BUFFER WHEN NEEDED.

 COLPX    LJM    **
 COLP     EQU    *-1
          LDM    CBT+/CB/P.PPSTAT GET PP SURRENT STATUS
          SBN    /CB/S.PTERM
          ZJN    COLPX       IF THE PP STATUS IS PP TERMINATED
          LOADC  CM.CB       LOAD R REGISTER WITH ADDRESS COMMUNICATION BUFFER
          ADN    /CB/C.CPBUF
          CRML   CBT+/CB/P.CPBUF,ON  GET CP OPERATION STATUS
          LDM    CBT+/CB/P.CPSTAT
          SBN    /CB/S.TERM
          MJN    COLP1       IF CP STATUS IS INITIALIZE START OR STOP

* PROCESS TERMINATION REQUEST

          LDN    /CB/S.PTERM SET PP STATUS TO TERMINATE
          STM    CBT+/CB/P.PPSTAT SET THE CURRENT PP STATUS
          LOADC  CM.CB       LOAD ADDRESS OF CM COMMUNICATION BUFFER
          ADN    /CB/C.PPBUF  ADD OFFSET FOR PP STATUS
          CWML   CBT+/CB/P.PPBUF,ON  UPDATE PP STATUS
          RJM    GNB         WRITE OUT CURRENT BUFFER
          UJN    COLP4       UPDATE PP STATUS

* DETERMINE START REQUEST

 COLP1    ADN    /CB/S.TERM-/CB/S.START
          MJN    COLP4       IF CP STATUS IS TABLE INITIALIZED
          NJN    COLP2       IF STATUS IS NOT START
          LDK    /CB/S.PCOL  SET PP STATUS TO COLLECTING
          UJN    COLP3

* PROCESS STOP REQUEST

 COLP2    LDK    /CB/S.PSTOP  SET THE STATUS TO STOP COLLECTING

* UPDATE PP STATUS WORD IN COMMUNICATION BUFFER

 COLP3    STM    CBT+/CB/P.PPSTAT SET THE CURRENT PP STATUS
          LOADC  CM.CB       LOAD ADDRESS OF CM COMMUNICATION BUFFER
          ADN    /CB/C.PPBUF  ADD OFFSET FOR PP STATUS
          CWML   CBT+/CB/P.PPBUF,ON  UPDATE PP STATUS
          LDM    CBT+/CB/P.PPSTAT
          SBN    /CB/S.PCOL  SUBTRACT COLLECTION STATUS
          ZJN    COLP5       IF PP STATUS IS COLLECTING P DATA
 COLP4    LJM    COLPX       EXIT COLP

* CHECK IF IT IS TIME TO COLLECT P SAMPLES

 COLP5    SODL   TM+1        DECREMENT TIMER COUNT
          PJN    COLP4       IF NOT TIME TO COLLECT P SAMPLE
          AOML   TM+1        RESET TO MAXIMUM INTEGER
          SODL   TM          DECREMENT TIMER COUNT
          PJN    COLP4       IF NOT TIME TO COLLECT P SAMPLE

* RESTORE TIMMER COUNT TO INITIAL VALUE FOR NEXT SAMPLE

          LDML   CBT+/CB/P.TIME
          STDL   TM
          LDML   CBT+/CB/P.TIME+1
          STDL   TM+1        RESET THE COUNT DOWN TIMER

*  READ AND PROCESS THE P REGISTER FOR PROCESSOR 0

          LDD    EC0         GET CONNECT CODE FOR PROCESSOR 0
          ZJK    COLP9       IF DONT COLLECT FOR PROCESSOR 0
          STD    EC          SAVE CONNECT CODE
          READMR RDATA       READ P REGISTER
          LDM    CBT+/CB/P.SPIID GET THE SPI IDENTIFIER
          ZJN    COLP6       IF PROCESS ANY SPI IDENTIFIER
          SBM    RDATA       SUBTRACT THE GLOBAL KEY OF THE P REGISTER
          NJK    COLP9
 COLP6    STM    RDATA+1     STORE PROCESSOR NUMBER IN LOCAL LOCKS
          RJM    PAC         PACK THE P REGISTER INTO 4 PP WORDS

* UPDATE THE CENTRAL MEMORY BUFFER

          LOADC  CM.CBUF     LOAD R REGISTER WITH CURRENT BUFFER ADDRESS
          ADM    CBT+/CB/P.PPOFF ADD IN THE WORD OFFSET COUNT TO CENTRAL MEMORY
          CWML   MRVAL,ON    WRITE P TO CENTRAL MEMORY
          SOML   CBT+/CB/P.SAMP+1
          PJN    COLP7       IF NOT END OF COLLECTION COUNT
          AOML   CBT+/CB/P.SAMP+1
          SOML   CBT+/CB/P.SAMP
          PJN    COLP7       IF NOT END OF COLLECTION COUNT
          LDN    /CB/S.PTERM
          STML   CBT+/CB/P.PPSTAT SET THE PP STATUS TO TERMINATE
          RJM    GNB         CLEAR OUT CURRENT BUFFER
          LJM    COLPX       FINISED PROCESSING

* CHECK BUFFER POSITION FOR END OF BUFFER

 COLP7    AOM    CBT+/CB/P.PPOFF INCREMENT OFFSET TO NEXT WORD
          SBM    MAXOFF      SUBTRACT OFF PAGE BOUNDRY
          NJN    COLP9       IF NOT END OF BUFFER
 COLP8    RJM    GNB         GET NEXT BUFFER

*  READ AND PROCESS THE P REGISTER FOR PROCESSOR 1

 COLP9    LDD    EC1         GET CONNECT CODE FOR PROCESSOR 1
          ZJK    COLP13      IF DONT COLLECT FOR PROCESSOR 1
          STD    EC          SAVE CONNECT CODE
          READMR RDATA       READ P REGISTER
          LDM    CBT+/CB/P.SPIID GET THE SPI IDENTIFIER
          ZJN    COLP10      IF PROCESS ANY SPI IDENTIFIER
          SBM    RDATA       SUBTRACT THE GLOBAL KEY OF THE P REGISTER
          NJK    COLP13
 COLP10   LDN    1
          STM    RDATA+1     STORE PROCESSOR NUMBER IN LOCAL LOCK
          RJM    PAC         PACK THE P REGISTER INTO 4 PP BYTES

* UPDATE THE CENTRAL MEMORY BUFFER

          LOADC  CM.CBUF     LOAD R REGISTER WITH CURRENT BUFFER ADDRESS
          ADM    CBT+/CB/P.PPOFF ADD IN THE WORD OFFSET COUNT TO CENTRAL MEMORY
          CWML   MRVAL,ON    WRITE P TO CENTRAL MEMORY
          SOML   CBT+/CB/P.SAMP+1
          PJN    COLP11      IF NOT END OF COLLECTION COUNT
          AOML   CBT+/CB/P.SAMP+1
          SOML   CBT+/CB/P.SAMP
          PJN    COLP11      IF NOT END OF COLLECTION COUNT
          LDN    /CB/S.PTERM
          STML   CBT+/CB/P.PPSTAT SET THE PP STATUS TO TERMINATE
          UJN    COLP12      GET NEXT BUFFER AND TERMINATE PROCESS

* CHECK BUFFER POSITION FOR END OF BUFFER

 COLP11   AOM    CBT+/CB/P.PPOFF INCREMENT OFFSET TO NEXT WORD
          SBM    MAXOFF      SUBTRACT OFF PAGE BOUNDRY
          NJN    COLP13      IF NOT END OF BUFFER
 COLP12   RJM    GNB         GET NEXT BUFFER
 COLP13   LJM    COLPX       EXIT
          EJECT
** NAME MRERR  MAINTENANCE REGISTER ERROR ROUTINE
*
* PURPOSE - ERROR RECOVERY FOR READMR OF P ADDRESS VALUE

 MRERR    SOM    COLPA       DECREMENT MAXIMUM ERROR COUNT
          PJN    COLP13      CONTINUE PROCESSING
          LDN    /CB/S.PTERM
          STML   CBT+/CB/P.PPSTAT SET THE PP STATUS TO TERMINATE
          UJN    COLP12

 COLPA    CON    100D        MAXIMUM NUMBER OF P REGISTER READ ERRORS

          EJECT
** NAME-- GNB GET NEXT BUFFER
*
** PURPOSE
*   1) UPDATE CURRENT BUFFER STATUS CONTROL
*   2) ISSUE INTERRUPT TO CENTRAL VIA UNSOLICITED RESPONSE
*   3) GET NEXT AVAILABLE BUFFER
*   4) UPDATE ADDRESS POINTERS
*
** EXIT  (BA) = POINTER TO RMA OF NEXT CENTRAL MEMORY BUFFER
*

 GNBX    LJM    **
 GNB     EQU    *-1
         LDM    CBT+/CB/P.PPBUF LOAD CURRENT BUFFER
         SBN    /CB/B.HIGH+1 SUBTRACT HIGHEST POSSIBLE BUFFER PLUS ONE
         PJK    GNB1         IF FIRST TIME INTO GET NEXT BUFFER
         LDK    /CB/S.DATA
         STM    BUFS+1       SET BUFFER STATUS TO HAVE DATA
         LDM    CBT+/CB/P.PPOFF
         STM    BUFS         SET BUFFER OFFSET TO CURRENT OFFSET

* UPDATE CURRENT BUFFER STATUS TO HAS DATA AND SEND UNSOLICITED MESSAGE

         LOADC  CM.CB        SET CENTRAL ADDRESS OF COMMUNICATIONS BUFFER
         ADK    /CB/C.BOFF1  ADD FIRST BUFFER OFFSET
         ADD    BN           ADD IN BUFFER NUMBER (0 .. 15)
         ADD    BN           ADD IN BUFFER NUMBER
         CWML   BUFS,ON      UPDATE BUFFER STATUS

* SET UP INTERRUPT INSTRUCTION BASED ON THE INTERRUPT PORT NUMBER

         LOAD   CBT,CB,IPORT GET THE INTERRUPT PORT MASK
         NJN    GNB0         IF INTERRUPT THEN ISSUE A INTERRUPT INSTUCTION
         LDC    2400B        2400 IS PASS INSTUCTION
         UJN    GNB00
 GNB0    ADC    102600B      ADD IN THE OPCODE FOR INTERRUPT INSTUCTION
 GNB00   STML   INTPRC       STORE INTERRUPT OR PASS INSTURCTION IN RESPIN
         RJM    SNMSG        SEND UNSOLICITED RESPONSE

*  POSITION TO NEXT BUFFER

         AOD    BN           INCREMENT TO NEXT BUFFER NUMBER
         SBN    /CB/B.HIGH
         MJN    GNB2         IF NOT PAST LAST BUFFER IN POOL

* PAST END POSITION FO FIRST BUFFER

 GNB1    LDC    CM.BF1       GET ADDRESS OF FIRST REFORMATTED ADDRESS
         STD    BA           SET POINTER TO FIRST REFORMATTED BUFFER ADDRESS
         LDN    0
         STD    BN           SET BUFFER NUMBER TO 0
         STM    CBT+/CB/P.PPBUF

*  GET UNFORMATTED RMA OF NEW BUFFER

 GNB2    LDIL   BA
         STML   CM.CBUF       UPDATE CM BUFFER ADDRESS
         AOD    BA
         LDIL   BA
         STML   CM.CBUF+1     UPDATE SECOND PART OF BUFFER ADDRESS
         AOD    BA
         LDIL   BA
         STML   CM.CBUF+2     UPDATE THIRD PART OF BUFFER ADDRESS
         AOD    BA            INCREMENT POINTER TO NEXT BUFFER ADDRESS

* WAIT FOR NEXT BUFFER TO BECOME AVAILABLE

 GNB3    LOADC  CM.CB         GET ADDRESS OF COMMUNICATIONS BUFFER
         ADK    /CB/C.BOFF1   ADD OFFSET TO FIRST BUFFER CONTROL
         ADD    BN
         ADD    BN            HAVE OFFSET TO CURRENT BUFFER CONTROL
         CRML   BUFS,ON       READ CURRENT BUFFER STATUS
         LDM    BUFS+1        GET CURRENT BUFFER STATUS
         SBN    /CB/S.AVAIL
         ZJN    GNB4          IF CURRENT BUFFER STATUS IS AVIALABLE
         PAUSE  1000          WAIT FOR BUFFER STATUS
         UJN    GNB3          TRY BUFFER STATUS AGAIN

* SET BUFFER STATUS TO IN USE BY PP

 GNB4    LDK    /CB/S.INUSE
         STM    BUFS+1        SET BUFFER STATUS TO IN USE BY PP
         LDN    0             SET OFFSET TO ZERO
         STM    CBT+/CB/P.PPOFF
         STM    BUFS
         LOADC  CM.CB         LOAD COMMUNICATION BUFFER ADDRESS
         ADK    /CB/C.BOFF1   ADD IN OFFSET TO FIRST BUFFER
         ADD    BN
         ADD    BN            NOW HAVE OFFSET OF CURRENT BUFFER CONTROL
         CWML   BUFS,ON       UPDATE BUFFER STATUS

* UPDATE PP STATUS TO INDICATE NEW BUFFER IN USE

         AOM    CBT+/CB/P.PPBUF UPDATE PP BUFFER STATUS IN COMMUNICATION BUFFER
         LOADC  CM.CB
         CWML   CBT+/CB/P.PPBUF,ON        UPDATE PP STATUS TO CENTRAL
         LJM    GNBX

         EJECT
** NAME-- GLIST
*
** PURPOSE-- READ THE CM ADDRESS LIST PORTION OF A COMMAND.
*
** INPUT-- LISTL
*
** OUTPUT-- CMLIST, CMD+/CM/P.RMA
          SPACE  6
 GLIX     LJM    **
 GLIST    EQU    *-1
          LDML   SS+/SS/P.LISTL  NO OF CM WORDS IN ADDRESS-LENGTH-PAIR LIST
          ZJN    GLIX        IF NO WORDS TO READ
          LOADF  CMD+/CM/P.RMA  LOAD CM ADDRESS AND REFORMAT
          CRML   CMLIST,ON
          LDN    8
          RAML   CMD+/CM/P.RMA+1  UPDATE RMA ADDRESS FOR NEXT READ
          SHN    -16
          RAML   CMD+/CM/P.RMA
          LDML   CMLIST+/CM/P.LEN  MAKE SURE IT IS AN EVEN NUMBER OF CM WORDS
          ADN    7
          SCN    7
          STML   CMLIST+/CM/P.LEN
          UJK    GLIX
          EJECT
** NAME-- ATERM
*
** PURPOSE-- ABNORMAL TERMINATION FOR INTERFACE ERRORS.
          SPACE  6
 ATERM    CON    0
          STML   RS+/RS/P.IEC  INTERFACE ERROR CODE
          LDK    /RS/K.INTERR
          STDL   T1          SAVE ERROR ID
          LMC    -0
          STDL   T2
          LDML   RS+/RS/P.CHERR
          LPDL   T2
          ADDL   T1          ADD ERROR FLAG
          STML   RS+/RS/P.CHERR SAVE ERROR CODE
          LDK    C.RS*8
          STML   RS+/RS/P.RESPL RESPONSE LENGTH
          LDML   RS+/RS/P.PVA
          ADML   RS+/RS/P.PVA+1
          ADML   RS+/RS/P.PVA+2
          NJN    ATERM10        IF UNRECOVERED REQUEST
          RJM    SNMSG          SEND UNSOLICITED MESSAGE
          LJM    MAIN35

 ATERM10  BSS
          LDN    R.ABN          ABNORMAL TERMINATION
          STDL   RESPC          RESPONSE CODE
          LJM    MAIN35
          EJECT
** NAME-- TERMP
*
** PURPOSE-- TERMINATE PP REQUEST.
*
** OUTPUT-- RS+/RS/P.RC = RESPONSE CODE
          SPACE  6
 TERX     LJM    **
 TERMP    EQU    *-1
          RJM    PUTRC       PUT RESPONSE CODES IN RESPONSE
          RJM    RESP        SEND RESPONSE TO CPU
          RJM    RESPIN      UPDATE 'IN' POINTER IN RESPONSE BUFFER
          LDN    0
          STDL   PPRQ        ZERO OUT PP REQUEST FLAG
          RJM    ZRESP       ZERO OUT RESPONSE BUFFER
          UJK    TERX
          EJECT
** NAME-- PUTRC
*
** PURPOSE-- PUT RESPONSE CODES IN RESPONSE
          SPACE  6
 PUTRCX   LJM    **
 PUTRC    EQU    *-1
          LDDL   RESPC       RESPONSE CODE
          SHN    /RS/L.RCON-/RS/L.RC+/RS/N.RCON-/RS/N.RC
          ADML   RCON        RESPONSE CONDITION
          SHN    /RS/L.URC-/RS/L.RCON+/RS/N.URC-/RS/N.RCON
          ERRNZ  /RS/P.URC-/RS/P.RCON
          ERRNZ  /RS/P.RC-/RS/P.URC
          STML   RS+/RS/P.URC
          UJK    PUTRCX
          EJECT
** NAME-- RESP
*
** PURPOSE-- WRITE STATUS BUFFER TO CM RESPONSE BUFFER.
*
** INPUT-- CM.PIT, CM.RS, LIM, /PIT/IN, /PIT/OUT, RS+/RS/P.RESPL
*
** OUTPUT-- /PIT/IN, RESPONSE BUFFER
          SPACE  6
          SPACE  6
 RESPX    LJM    **
 RESP     EQU    *-1

* CHECK IF RESPONSE SHOULD BE SENT TO CM.

          LDN    0
          STML   STORS       SET FLAG TO STORE RESPONSE
          LDML   CMD+/CM/P.STOR  CHECK IF CALLER WANTS RESPONSE
          SHN    /CM/L.STOR+2
          MJN    RESP10      IF STORE RESPONSE FLAG IS SET
          LDDL   RESPC       CHECK FOR NORMAL RESPONSE
          SBN    R.NRM
          NJN    RESP10      IF NOT NORMAL RESPONSE, STORE RESPONSE
          AOML   STORS       NONZERO MEANS DO NOT STORE RESPONSE
 RESP5    UJK    RESPX

* READ IN AND OUT POINTERS OF RESPONSE BUFFER.

 RESP10   BSS
          LOADC  CM.PIT      LOAD ADDRESS OF PP INTERFACE TABLE
          ADN    /PIT/C.OUT  OFFSET OF OUT POINTER
          CRDL   P2          READ OUT POINTER
          SBN    /PIT/C.OUT-/PIT/C.IN  OFFSET OF 'IN' POINTER
          CRDL   P1          READ 'IN' POINTER

* CHECK IF THERE IS ROOM FOR THE RESPONSE IN THE RESPONSE BUFFER.

          LDN    0
          STDL   T5          NUMBER OF WORDS IN 2ND BLOCK WRITE
          LDDL   P4
          SBDL   P5
          MJN    RESP20      IF IN .LT. OUT
          LDDL   LIM         IN .GE. OUT, SET OUT = OUT + LIMIT
          RADL   P5
 RESP20   LDML   RS+/RS/P.RESPL  GET RESPONSE LENGTH
          ZJK    RESP5       IF RESPONSE LENGTH = 0
          ADDL   P4
          STDL   INPNT       IN + RESPONSE LENGTH
          SBDL   P5          CHECK IF ENOUGH ROOM IN BUFFER FOR RESPONSE
          PJK    RESP10      IF NOT ENOUGH ROOM IN BUFFER, LOOP
          LDDL   P4
          SHN    -3
          STDL   T3          'IN' POINTER IN WORDS
          LDML   RS+/RS/P.RESPL  CONVERT RESPONSE LENGTH TO WORDS
          SHN    -3
          STDL   T4          RESPONSE LENGTH IN WORDS
          LDDL   INPNT
          SBDL   LIM
          MJN    RESP50      IF IN + RESPONSE LENGTH .LT. LIMIT
                             ONLY 1 BLOCK WRITE
          STDL   INPNT       IN + RESPONSE LENGTH - LIMIT = NEW 'IN' POINTER
          SHN    -3
          STDL   T5          NUMBER OF WORDS IN 2ND BLOCK WRITE

* WRITE RESPONSE TO CM.

          LDDL   LIM         FIRST BLOCK WRITE = (LIMIT - IN) WORDS
          SBDL   P4
          SHN    -3
          STDL   T4          NUMBER OF WORDS TO TRANSFER ON 1ST BLOCK
          SHN    2           CONVERT TO NUMBER OF PP WORDS
          ADC    RS
          STML   RESPA       RESPONSE ADDRESS FOR 2ND BLOCK WRITE
 RESP50   BSS
          LOADC  CM.RS       LOAD CM ADDRESS OF RESPONSE BUFFER
          STDL   T6          SAVE CM ADDRESS
          ADDL   T3          ADD 'IN' OFFSET
          CWML   RS,T4       WRITE RESPONSE TO CM
          LDDL   T5          RESPONSE LENGTH
          ZJN    RESP70      IF ONLY 1 BLOCK WRITE REQUIRED
          LDDL   T6          LOAD ADDRESS OF RESPONSE BUFFER
          LMC    400000B
          CWML   **,T5       WRITE 2ND PART OF RESPONSE TO CM
                             (BEGINNING OF RESPONSE BUFFER)
 RESPA    EQU    *-1

 RESP70   BSS
          LJM    RESPX
          EJECT
** NAME-- RESPIN
*
** PURPOSE-- UPDATE THE 'IN' POINTER IN THE CM RESPONSE BUFFER.
*
** INPUT-- INPNT = NEW 'IN' POINTER.
          SPACE  6
 RESNX    LJM    **
 RESPIN   EQU    *-1

* CHECK IF RESPONSE SHOULD BE SENT TO CM.

          LDML   STORS       CHECK IF CALLER WANTS RESPONSE
          NJK    RESNX       IF NO RESPONSE WAS SENT

* UPDATE THE 'IN' POINTER.

          LDN    0
          STDL   P1
          STDL   P2
          STDL   P3
          LDDL   INPNT       NEW 'IN' POINTER
          STDL   P4
          LOADC  CM.PIT      LOAD ADDRESS OF PP INTERFACE TABLE
          ADN    /PIT/C.IN   OFFSET OF 'IN' POINTER
          CWDL   P1          WRITE NEW 'IN' POINTER TO CM

* INTERRUPT PROCESSOR. RESP ROUTINE SETS UP THIS INSTRUCTION.

          LOADC  CM.INT      CM ADDRESS OF INTERRUPT WORD
          CWDL   PPNO-3      SET LAST BYTE NONZERO
          LDN    0           CLEAR A-REGISTER FOR S0 HARDWARE PROBLEM
 INTPRC   INPN   1           THIS INSTRUCTION IS MODIFIED BY GNB
          CRDL   T1          THIS INSTRUCTION IS BECAUSE OF AN 810/830 PROBLEM
          UJK    RESNX
          EJECT
** NAME SNMSG - SEND UNSOLICITED MESSAGE.
*
** PURPOSE-- SEND AN UNSOLICITED MEAAGE TO THE CENTRAL PROCESSOR
          SPACE  6
 SNMSGX   LJM    **
 SNMSG    EQU    *-1
          LDK    C.RS*8      SET RESPONSE LENGTH FOR ERROR
          STML   RS+/RS/P.RESPL
          LDN    0           UNSOLICITED MESSAGE
          STDL   RESPC       RESPONSE CODE
          STML   RS+/RS/P.IEC  INTERFACE ERROR CODE
          RJM    TERMP       SEND RESPONSE TO CM
          UJK    SNMSGX
          EJECT
** NAME-- ZRESP
*
** PURPOSE-- ZERO OUT PART OF THE RESPONSE BUFFER.
*
** NOTE-- THIS ROUTINE IS ALSO CALLED FOR RECOVERED ERROR RESPONSES.
          SPACE  6
 ZREX     LJM    **
 ZRESP    EQU    *-1
          LDN    0
          STML   RCON        RESPONSE CONDITION
          STDL   NODEL       DON'T DELINK REQUEST FLAG
          STML   RS+/RS/P.HDWR  ABNORMAL STATUS
          STML   RS+/RS/P.IEC  INTERFACE ERROR CODE

          LDK    P.RS-/RS/P.FTRK
          STDL   T1
 ZER10    LDN    0
          STML   RS+/RS/P.FTRK-1,T1 ZERO OUOT PART OF RESPONSE BUFFER
          SODL   T1
          NJN    ZER10
          LDK    /RS/C.LASTC*8+8  SET RESPONSE LENGTH FOR NORMAL RESPONSE
          STML   RS+/RS/P.RESPL
          LDN    R.NRM       SET RESPONSE CODE = NORMAL
          STDL   RESPC
          SHN    16-/RS/N.RC-/RS/L.RC
          STML   RS+/RS/P.RC  PUT REPONSE CODE IN RESPONSE
          UJK    ZREX
          EJECT
** NAME-- SCLOCK
*
** PURPOSE-- SETS THE CHANNEL LOCK.
*
** EXIT-- (A) = 0, IF LOCK WAS SUCCESSFULLY SET.
*         (A) .NE. 0, IF LOCK COULD NOT BE SET.
          SPACE  6
 SCL40    LDN    0           SET LOCK SUCCESSFUL
 SCLX     LJM    **
 SCLOCK   EQU    *-1
          LDDL   CHLOCK
          NJN    SCL40       IF CHANNEL LOCK IS NOT SET

 SCL10    BSS
          LDK    C.CHCNT
          STML   CHLCNT      NUMBER OF REQUESTS TO PROCESS BEFORE
                             GIVING UP CHANNEL
          LDN    6           SET TIMEOUT DELAY TO 5 SECONDS ON S1
          STDL   P1
          STDL   P2
 SCL20    BSS
          LDC    CM.CHAN     CM ADDRESS OF CHANNEL INTERLOCK TABLE
          STDL   T7
          LDDL   CHAN        CHANNEL NUMBER IS OFFSET IN TABLE
          STDL   T5
          RJM    LOCKW       SET LOCKWORD
          NJN    SCL30       IF LOCK WAS NOT SET
          AODL   CHLOCK      SET FLAG IF LOCK WAS SET
          UJK    SCL40       EXIT, LOCK WAS SET

 SCL30    BSS
          SODL   P1
          NJK    SCL20
          SODL   P2
          NJK    SCL20
          LDN    1           TIMEOUT ON TRYING TO GET CHANNEL LOCK
          UJK    SCLX        EXIT A REGISTER NONZERO
          EJECT
** NAME-- SPLOCK
*
** PURPOSE-- SETS THE PP REQUEST QUEUE LOCK IN THE
*            PP INTERFACE TABLE.
*
** EXIT-- A REGISTER = 0, IF LOCK WAS SUCCESSFULLY SET.
*                    .NE. 0, IF LOCK COULD NOT BE SET.
          SPACE  6
 SPLX     LJM    **
 SPLOCK   EQU    *-1
          LDC    7777B
          STDL   SSUN        INVALIDATE SS TABLE
          LDK    CM.PIT      PP INTERFACE TABLE ADDRESS
          STDL   T7
          LDN    /PIT/C.LOCK  OFFSET OF PP QUEUE LOCKWORD
          STDL   T5
          RJM    LOCKW       SET THE LOCKWORD
          NJK    SPLX        IF LOCK COULD NOT BE SET
          RJM    SCLOCK      SET CHANNEL LOCK
          UJK    SPLX
          EJECT
** NAME-- LOCKW SET CENTRAL LOCK WORD
*
** PURPOSE-- TO SET CENTRAL LOCK WORD

 LOCKX    LJM    **
 LOCKW    EQU    *-1

* SET LOCK BIT.

          LDC    100000B     SET UNIT LOCK BIT
          STDL   T1
          STDL   T2
          LDN    0
          STDL   T3
          STDL   T4
          LOADR  0,T7        UNIT/PP INTERFACE TABLE ADDRESS
          ADDL   T5          ADD LOCKWORD OFFSET, SAVE CM ADDRESS
          STDL   T6          SAVE CM ADDRESS
          RDSL   T1          SET LOCK BIT IN UNIT LOCKWORD

* CHECK IF LOCK WAS OBTAINED.

          LDDL   T1
          ADDL   T4
          ZJN    LOCK20      IF LOCK COULD BE SET
          LDDL   T4
          SBDL   PPNO        CHECK IF LOCK ALREADY SET
          NJN    LOCK10      IF LOCK COULD NOT BE SET, EXIT A .NE. 0
          LDDL   T1
          ADC    -100000B
 LOCK10   UJK    LOCKX       EXIT WITH LOCK VALUE

* SET PP NUMBER IN LOCKWORD.

 LOCK20   BSS
          LDDL   PPNO
          STDL   T4
          LDDL   T6          CM ADDRESS OF UNIT LOCK.
          LMC    RR
          RDSL   T1          SET PP NUMBER IN LOCKWORD

* CHECK IF LOCK WAS CORRECT BEFORE LAST RDSL OPERATION.

          LDDL   T1
          ADC    -100000B
          NJN    LOCK40
          LDDL   T4
          ZJK    LOCK10      IF NO ERROR, EXIT

 LOCK30   UJN    *           ERROR IN LOCKWORD

* CHECK FOR LOCKWORD = FFFF FFFF XXXX XXXX(16).

 LOCK40   BSS
          LDDL   T1
          ADDL   T2
          ADC    -177777B-177777B
          NJN    LOCK30
          AODL   LFF00
          LDN    0
          STDL   T1
          STDL   T2
          STDL   T3
          UJK    LOCK20
          EJECT
** NAME-- CCLOCK
*
** PURPOSE-- CLEARS CHANNEL LOCK.
*
          SPACE  6
 CCLX     LJM    **
 CCLOCK   EQU    *-1
          LDDL   CHLOCK
          ZJK    CCLX        IF CHANNEL LOCK WAS NOT SET
          LDC    CM.CHAN     CM ADDRESS OF CHANNEL INTERLOCK TABLE
          STDL   T7
          LDDL   CHAN        CHANNEL NUMBER = OFFSET IN TABLE
          STDL   T5
          RJM    CLOCK       CLEAR CHANNEL LOCKWORD
          LDN    0
          STDL   CHLOCK      CLEAR CHANNEL LOCK FLAG
          UJK    CCLX
          EJECT
** NAME-- CPLOCK
*
** PURPOSE-- CLEARS THE PP QUEUE LOCK IN THE PP INTERFACE TABLE.
*
          SPACE  6
 CPLX     LJM    **
 CPLOCK   EQU    *-1
          LDK    CM.PIT      PP INTERFACE TABLE ADDRESS
          STDL   T7
          LDN    /PIT/C.LOCK  OFFSET OF PP QUEUE LOCKWORD
          STDL   T5
          RJM    CLOCK       CLEAR THE LOCKWROD
          UJK    CPLX
          EJECT
** NAME - CLOCK
*
** PURPOSE - CLEAR A CENTRAL LOCK
*
** EXIT CONDITIONS - (A) = 0 IF LOCK IS CLEARED
*                    (A) .NE. 0 IF LOCK NOT CLEARED

 CLKX     LJM    **
 CLOCK    EQU    *-1

* MAKE SURE THIS PP IS THE ONE WHO HAS THE LOCK SET.

 CLK10    BSS
          LOADR  0,T7        UNIT/PP INTERFACE TABLE ADDRESS
          ADDL   T5          ADD LOCKWORD OFFSET, SAVE CM ADDRESS
          STDL   T6          SAVE CM ADDRESS
          CRDL   T1          READ UNIT LOCK
          LDDL   T4          CHECK PP NUMBER
          SBDL   PPNO
          ZJN    CLK30       IF THIS PP HAS THE LOCK SET

* CHECK IF LOCKWORD = FFFF FFFF XXXX XXXX(16).

          LDDL   T1
          ADDL   T2
          ADC    -177777B-177777B
          NJN    CLK20       ERROR, THIS PP DOES NOT HAVE THE UNIT RESERVED
          AODL   LFF00
          UJK    CLK10

 CLK20    BSS
          UJK    CLKX        EXIT, A REGISTER = 0, IF LOCK WAS CLEARED
                             EXIT, A REGISTER .NE. 0, IF LOCK COULD NOT
                               BE CLEARED

* CLEAR UNIT LOCKWORD IN UNIT INTERFACE TABLE.

 CLK30    BSS
          LDN    0
          STDL   T1
          STDL   T2
          STDL   T3
          STDL   T4
          LDDL   T6          CM ADDRESS OF UNIT LOCK
          LMC    RR
          RDCL   T1          CLEAR LOCK

* CHECK IF LOCK WAS CORRECT BEFORE THE CLEAR OPERATION.

          LDDL   T1
          ADC    -100000B
          NJN    CLK50
          LDDL   PPNO
          SBDL   T4
          ZJK    CLK20       IF LOCK WAS OK
 CLK40    BSS
          UJN    *           LOCK WAS MESSED UP

* CHECK IF LOCKWORD = FFFF FFFF XXXX XXXX(16).

 CLK50    BSS
          LDDL   T1
          ADDL   T2
          ADC    -177777B-177777B
          NJK    CLK40
          AODL   LFF00
          UJK    CLK30
          EJECT
** NAME-- FORMA
*
** PURPOSE-- FORMAT A CM REAL MEMORY ADDRESS.
*
** CALLING SEQUENCE-- LDC    ADDRESS
*                     RJM    FORMA
*
** INPUT-- - A REGISTER- IS THE ADDRESS OF A 2-WORD CM BYTE ADDRESS.
*
** OUTPUT-- -CMADR- IS THE ADDRESS OF THE RESULTING 3-WORD REFORMATED
*                CM ADDRESS.  THE FORMAT CAN BE USED BY THE LOADC MACRO.
*           -ADDRESS-, WORD 0, BITS 0-13 AND
*                      WORD 1, BITS 3-15, ARE REFORMATTED TO-
*           -CMADR-,   WORD 0, BITS 0-9,
*                      WORD 1, BITS 0-11,
*                      WORD 2, BITS 0-5.
*
          SPACE  6
 FORX     LJM    **
 FORMA    EQU    *-1
          STDL   T1
          LDML   1,T1
          LPN    7
          NJN    *           RMA ADDRESS ERROR, PERMANENT HALT
          LDIL   T1
          LPN    37B
          SHN    16
          LMML   1,T1
          SHN    9
          STD    CMADR+1
          SHN    6
          LPN    77B
          STDL   CMADR+2
          LDIL   T1
          SHN    -5
          STD    CMADR
          LRD    CMADR
          LDDL   CMADR+2
          LMC    RR
          UJK    FORX
          EJECT
** NAME-- PAUS
*
** PURPOSE-- DELAY PROGRAM EXECUTION FOR A SPECIFIED NUMBER OF
*            MICROSECONDS.
*
** INPUT-- A REGISTER (BITS 00-06) SPECIFIES NUMBER OF MICROSECONDS
*          TO BE DELAYED.
*
** NOTE-- THIS CODE IS MODIFIED BY THE INITIALIZATION ROUTINE.
*         THE INSTRUCTION ARE DEPENDANT ON THE TYPE OF MAINFRAME
*         THE CODE IS EXECUTED ON.
*
** CODE SEQUENCE FOR THE DIFFERENT MACHINES.
*         FOR THE S0
*         ENTRY
*         WAIT    (101700)
*         PASS
*         EXIT
*
*         FOR THE S1
*         ENTRY
* LOOP    SUBTRACT 1
*         GO TO LOOP IF NOT ZERO
*         EXIT
*
*         FOR OTHER MACHINES
*         ENTRY
* LOOP    SUBTRACT 1
*         PASS
*         PASS
*         GO TO LOOP IF NOT ZERO
*         EXIT
*

          SPACE  6
 PAUSX    LJM    **
 PAUS     EQU    *-1
*         THE FOLLOWING INSTRUCTION BECOMES A WAIT ON AN S0.
*         A WAIT IS AN 101700 INSTRUCTION
 PAUS10   SBN    1           EACH ITERATION OF THIS SBN-(PASS-PASS)-NJN LOOP
*         THE FOLLOWING INSTRUCTION BECOMES A PASS ON ANY NON S1 MACHINES.
 PAUS20   NJN    PAUS10      UTILIZES 1 MICROSECOND
*         THE FOLLOWING INSTRUCTION BECOMES A PASS ON ANY I2 OR I4 MACHINES
 PAUS30   UJK    PAUSX       EXIT FOR S0 AND S1 MACHINES
          NJN    PAUS10      UTILIZES 1 MICROSECOND ON AN I2 OR I4
          UJK    PAUSX       EXIT FOR S2, S3, AND THETA MACHINES
          EJECT
*copyc dsa$hardware_table_definitions
*copyc dsi$find_cip_module
*copyc dsi$get_hardware_element
*copyc dsi$maintenance_register_access
*copyc dsi$pack_unpack_registers
*copyc dsi$pp_utility_subroutines
          EJECT
** NAME-- PPREQ
*
** PURPOSE-- CHECK FOR ANY PP REQUESTS ON THE PP QUEUE.
*
** EXIT-- (A) = 0, IF NO PP REQUESTS.
*         (A) .NE. 0, IF A PP REQUEST WAS FOUND
          SPACE  6
 PPRQX    LJM    **
 PPREQ    EQU    *-1
          LOADC  CM.PIT      CM ADDRESS OF PP INTERFACE TABLE
          ADN    /PIT/C.PPQ  CM ADDRESS OF PP REQUEST QUEUE POINTER
          CRDL   P1          READ PP QUEUE POINTER
          LDDL   P3          RMA OF NEXT QUEUED PP REQUEST
          ADDL   P4
          ZJN    PPRQX       IF NO PP REQUESTS

* SET PP QUEUE LOCKWORD.

          RJM    SPLOCK      SET PP QUEUE LOCKWORD
          ZJN    PPRQ20      IF LOCK WAS SET

 PPRQ15   BSS
          LDN    0
          UJK    PPRQX       EXIT, A REGISTER = 0

* GET THE RMA OF THE FIRST PP REQUEST IN THE CHAIN.

 PPRQ20   BSS
          LDN    2
          STDL   WC
          LOADC  CM.PIT
          ADN    /PIT/C.PPQPVA
          CRML   T1,WC       READ PVA AND RMA OF FIRST REQUEST IN CHAIN

* PUT PVA AND RMA OF REQUEST IN SS TABLE.

          LDDL   T2          PUT PVA OF REQUEST IN SS TABLE
          STML   SS+/SS/P.PVA
          LDDL   T3
          STML   SS+/SS/P.PVA+1
          LDDL   T4
          STML   SS+/SS/P.PVA+2
          LDDL   T7          PUT RMA OF REQUEST IN SS TABLE
          STML   SS+/SS/P.REQ
          LDDL   T8
          STML   SS+/SS/P.REQ+1
          LDN    0
          STML   SS+/SS/P.FRST  SET FLAG WHEN REQUEST IS READ

* READ THE PP REQUEST.

          LDN    C.RQ
          STDL   P1
          LOADF  T7          CM ADDRESS OF FIRST PP REQUEST
          CRML   RQ,P1       READ PP REQUEST

* DELINK THE FIRST PP REQUEST FROM THE CHAIN.

 PPRQ30   BSS
          LOADC  CM.PIT
          ADN    /PIT/C.PPQPVA  CM ADDRESS OF PP QUEUE POINTER
          CWML   RQ,WC       WRITE PVA AND RMA POINTERS OF NEXT REQUEST
          RJM    CPLOCK      CLEAR PP QUEUE LOCKWORD
          LDML   RQ+/RQ/P.LEN  DETERMINE NUMBER OF COMMANDS
          SHN    -3
          SBN    /RQ/C.CMND
          STML   SS+/SS/P.NUMCM  NUMBER OF COMMANDS

          AODL   PPRQ        SET PP REQUEST FLAG
          UJK    PPRQX       EXIT, A REGISTER NONZERO
          EJECT
** NAME-- IDLEP
*
** PURPOSE-- PROCESS IDLE COMMAND.
          SPACE  6
 IDLX     LJM    **
 IDLEP    EQU    *-1
          AODL   IDLE        SET IDLE FLAG
          RJM    CCLOCK      CLEAR CHANNEL LOCK
          UJK    IDLX
          EJECT
** NAME-- RESUME
*
** PURPOSE-- PROCESS RESUME COMMAND.
          SPACE  6
 RESX     LJM    **
 RESUME   EQU    *-1
          LDN    0
          STDL   IDLE        CLEAR IDLE FLAG
          UJK    RESX



 IPIT     EQU    *           PP INTERFACE TABLE
 CBT      EQU    IPIT+P.PIT
          ORG    CBT+P.CB
 STORS    BSSZ   1           STORE RESPONSE FLAG (USED BY RESPIN)
                               = 0, IF A RESPONSE IS SENT TO CM
                               = NONZERO, IF NO RESPONSE WAS SENT TO CM
 RCON     BSSZ   1           ADDITIONAL RESPONSE CONDITION
 CHLCNT   BSSZ   1           NUMBER OF REQUESTS TO PROCESS BEFORE
                             CLEARING CHANNEL LOCK
 SS       BSSZ   P.SS        INFORMATION SAVED IN UNIT COMMUNICATION BUFFER
 RQ       EQU    SS+/SS/P.RQ  REQUEST
 CMD      EQU    RQ+/RQ/P.CMND  CURRENT COMMAND
 CMLIST   EQU    SS+/SS/P.CMLIST  INDIRECT RMA LIST
 RS       EQU    SS+/SS/P.RS  RESPONSE BUFFER
          BSSZ   3           MUST FOLLOW RS, FOR ZEROING OUT RS

          EJECT
** NAME-- INIT
*
** PURPOSE-- INITIALIZE THE DRIVER AFTER DEADSTART.
*
** INPUT-- DSRTP = CM BYTE-ADDRESS OF THE PP INTERFACE TABLE.
          SPACE  6
 INIT     BSS
          RJM    PIB         PREPARE INTERFACE BLOCK
          RJM    PHT         PREPARE HARDWARE TABLES
          LDN    PROCID
          RJM    FHE         FIND PROCESSOR IN MRT
          MJN    *           HANG HERE, CANT FIND PROCESSOR CODE
          LDM    HBUF+CPRPC
          STD    EC0         SAVE EQUIPMENT CONNECT CODE
          LDM    HBUF+CPRE+EM
          SHN    -8
          STD    MD          SAVE MAINFRAME MODEL NUMBER
          SBN    5
          ZJN    INIT10      IF MODEL IS S0 THEN
          LDC    PPRG
          UJN    INIT11      PROCESS NON S0 MODEL NUMBER
 INIT10   LDC    S0PPRG
 INIT11   STD    RN          SAVE P REGISTER NUMBER
          LDC    PROCID1
          RJM    FHE         FIND HARDWARE ELEMENT FOR PROCESSOR 1
          MJN    INIT15      PROCESSOR 1 DOES NOT EXIST
          LDM    HBUF+CPRPC
          STD    EC1         SAVE CONNECT CODE FOR PROCESSOR 1

 INIT15   REFAD  DSRTP,CM.PIT   REFORMAT ADDRESS OF PP INTERFACE TABLE
                               AND SAVE.


* REFORMAT ADDRESS OF COMMUNICATION BUFFER.
* INITIALIZE CM.CB.

          LOADC  CM.PIT      ADDRESS OF PP INTERFACE TABLE
          ADN    /PIT/C.CBUF  OFFSET OF PP COMMUNICATION BUFFER ADDRESS
          CRDL   P1          READ ADDRESS OF PP COMMUNICATION BUFFER
          REFAD  P3,CM.CB    REFORMAT CM ADDRESS OF PP COMMUNICATION BUFFER

* READ COMMUNICATION BUFFER AND PROCESS WHEN BUFFER IS INITIALIZED.

 INIT20   LDN    C.CB
          STD    WC          SAVE WORD COUNT FOR COMMUNICATION BUFFER
          LOADC  CM.CB       ADDRESS OF COMMUNICATION BUFFER
          CRML   CBT,WC      READ COMMUNICATION BUFFER
          LDML   CBT+/CB/P.CPSTAT GET CP STATUS OF COMMUNICATION BUFFER
          SBN    /CB/S.INIT
          ZJN    INIT30      IF COMMUNICATION BUFFER INITIALIZED
          PAUSE  1000
          UJN    INIT20

* NOTE, DO NOT USE BUFFERS BEFORE THIS POINT, UNLESS THE PP IS
* HALTED AFTERWARD.

 INIT30   LDK    P.RS        ZERO OUT FULL RESPONSE BUFFER
          STDL   T1
 INIT98   BSS
          LDN    0
          STML   RS-1,T1     ZERO OUT RESPONSE BUFFER
          SODL   T1
          NJN    INIT98

          RJM    ZRESP       ZERO OUT RESPONSE BUFFER

* READ PP_INTERFACE_TABLE.

          LDN    C.PIT
          STDL   WC
          LOADC  CM.PIT      LOAD CM ADDRESS OF PP INTERFACE TABLE
          CRML   IPIT,WC     READ PP INTERFACE TABLE
          LDML   IPIT+/PIT/P.PPNO  GET PP NUMBER
          STDL   PPNO

* REFORMAT ADDRESS OF RESPONSE BUFFER.
* INITIALIZE CM.RS, LIM.

 INIT80   BSS
          REFAD  IPIT+/PIT/P.RSBUF,CM.RS  REFORMAT CM ADDRESS OF RESPONSE
                             BUFFER
          LDML   IPIT+/PIT/P.LIMIT  GET LIMIT OF RESPONSE BUFFER
          STDL   LIM

* REFORMAT ADDRESS OF INTERRUPT WORD.

          REFAD  IPIT+/PIT/P.INT,CM.INT  REFORMAT CM ADDRESS OF
                             INTERRUPT WORD

* REFORMAT ADDRESS OF CHANNEL TABLE.

          REFAD  IPIT+/PIT/P.CHAN,CM.CHAN  REFORMAT CM ADDRESS OF
                             CHANNEL TABLE

* REFORMAT ADDRESS OF CM BUFFERS
* INITIALIZE CM.BF1 TO CM.BF16

          REFAD  CBT+/CB/P.BRMA1,CM.BF1
          REFAD  CBT+/CB/P.BRMA2,CM.BF2
          REFAD  CBT+/CB/P.BRMA3,CM.BF3
          REFAD  CBT+/CB/P.BRMA4,CM.BF4
          REFAD  CBT+/CB/P.BRMA5,CM.BF5
          REFAD  CBT+/CB/P.BRMA6,CM.BF6
          REFAD  CBT+/CB/P.BRMA7,CM.BF7
          REFAD  CBT+/CB/P.BRMA8,CM.BF8
          REFAD  CBT+/CB/P.BRMA9,CM.BF9
          REFAD  CBT+/CB/P.BRMA10,CM.BF10
          REFAD  CBT+/CB/P.BRMA11,CM.BF11
          REFAD  CBT+/CB/P.BRMA12,CM.BF12
          REFAD  CBT+/CB/P.BRMA13,CM.BF13
          REFAD  CBT+/CB/P.BRMA14,CM.BF14
          REFAD  CBT+/CB/P.BRMA15,CM.BF15
          REFAD  CBT+/CB/P.BRMA16,CM.BF16

* ZERO OUT CONNECT CODES FOR PROCESSORS NOT SELECTED

          LOAD   CBT,CB,P0   LOAD PROCESSOR ZERO SELECT FLAG
          NJN    INIT83      IF PROCESSOR IS SELECTED
          STD    EC0         DESELECT PROCESSOR ZERO
 INIT83   LOAD   CBT,CB,P1   LOAD PROCESSOR ONE SELECT FLAG
          NJN    INIT85      IF PROCESSOR IS SELECTED
          STD    EC1         DESELECT PROCESSOR ONE

* STORE THE NAME SPI IN WORDS 100 AND 101

 INIT85   LDC    2R_SP
          STML   START
          LDC    2R_I
          STML   START+1

* COPY OVER THE INITIAL TIMMER VALUE AND SET UP THE SPI IDENTIFIER
* FOR THE PROPER MAINFRAME.

          LDML   CBT+/CB/P.TIME
          STDL   TM
          LDML   CBT+/CB/P.TIME+1
          STDL   TM+1
          LDD    MD          GET THE MACHINE IDENTIFIER
          SBN    5           SUBTRACT THE S0 IDENTIFIER
          NJN    INIT90      IF NOT S0 TYPE MAINFRAME
          STML   CBT+/CB/P.SPIID ON S0 ONLY USE SPI ID OF ZERO

*  INITIALIZE PP STATUS OF COMMUNICATION BUFFER

 INIT90   LDN    /CB/B.HIGH+1 SET THE PP BUFFER NUMBER FOR START OF PROGRAM
          STM    CBT+/CB/P.PPBUF
          LDN    /CB/S.PWAIT SET THE STATUS TO IN USE
          STM    CBT+/CB/P.PPSTAT
          LDN    0           SET THE BUFFER OFFSET TO START OF BUFFER
          STM    CBT+/CB/P.PPOFF
          RJM    GNB         GET THE FIRST BUFFER

* SET ERROR ADDRESS PROCESSING FOR READMR ROUTINE

          EXITMR MRERR       SET ERROR EXIT ADDRESS

* THIS PART OF THE CODE INITIALIZES THE PAUSE DELAY LOOP FOR THE
* MACHINE THE CODE IS EXECUTED ON. THE INSTRUCTION MODIFICATION IS
* BASED ON THE MACHINE MODEL NUMBER OBTAINED ABOVE.

          LDD    MD          GET THE MACHINE MODEL NUMBER
          SBN    1
          ZJK    INIT94      IF THE SYSTEM IS ANY TYPE OF S1
          SBN    5-1
          ZJK    INIT92      IF THE SYSTEM IS AN S0

* SET UP PAUSE INSTRUCTIONS FOR I2 AND I4

          LDN    0           OP CODE FOR PASS INSTRUCTION
          STM    PAUS20      REPLACE NON ZERO JUMP WITH PASS INSTRUCTION
          STM    PAUS30      REPLACE EXIT JUMP WITH PASS INSTUCTION
          UJK    INIT94

* SET UP PAUSE INSTUCTIONS FOR S0

 INIT92   STM    PAUS20      REPLACE NON ZERO JUMP WITH PASS INSTRUCTION
          LDC    101700B     LOAD OP CODE FOR HOLD INSTRUCTION
          STML   PAUS10      REPLACE SUBTRACT WITH HOLD INSTRUCTION
 INIT94   LJM    SPI
          EJECT
 SAVAX    LJM    **
 SAVAD    EQU    *-1
          STML   2,T2
          LDDL   CMADR
          STI    T2
          LDDL   CMADR+1
          STML   1,T2
          UJK    SAVAX
 CONCH2   BSS
 TDC+40B  HERE
 T40B+DC  HERE
 TDC      HERE
          CON    0
          END    SPI
/EOR
