*COMDECK MODE4TIP 
_$J+
  
  
  
  
 MMMM         MMMM    OOOOOOOOOOO    DDDDDDDDDDDDDD     EEEEEEEEEEEEEEE 
  MMMM       MMMM    OOOOOOOOOOOOO    DDDDDDDDDDDDDD    EEEEEEEEEEEEEEE 
  MMMMM     MMMMM   OOOO       OOOO   DDD        DDDD   EEE           E 
  MMM MM   MM MMM   OOO         OOO   DDD         DDD   EEE 
  MMM  MM MM  MMM   OOO         OOO   DDD         DDD   EEE 
  MMM   MMM   MMM   OOO         OOO   DDD         DDD   EEEEEEEEEEEE
  MMM    M    MMM   OOO         OOO   DDD         DDD   EEEEEEEEEEEE
  MMM         MMM   OOO         OOO   DDD         DDD   EEE 
  MMM         MMM   OOO         OOO   DDD         DDD   EEE 
  MMM         MMM   OOOO       OOOO   DDD        DDDD   EEE           E 
 MMMMM       MMMMM   OOOOOOOOOOOOO    DDDDDDDDDDDDDD    EEEEEEEEEEEEEEE 
 MMMMM       MMMMM    OOOOOOOOOOO    DDDDDDDDDDDDDD     EEEEEEEEEEEEEEE 
  
  
  
  
                                       444
                                     44444
                                   444 444
                                 444   444
                               444     444
                             4444444444444444 
                           444444444444444444 
                                       444
                                       444
                                       444
                                      44444 
                                      44444 
  
  
  
  
     TTTTTTTTTTTTTTTTTT      IIIIIIIIIIIIIII      PPPPPPPPPPPPPPP 
     TTTTTTTTTTTTTTTTTT      IIIIIIIIIIIIIII       PPPPPPPPPPPPPPP
     T      TTT       T            III             PPP          PPP 
            TTT                    III             PPP           PPP
            TTT                    III             PPP          PPP 
            TTT                    III             PPPPPPPPPPPPPPP
            TTT                    III             PPPPPPPPPPPPPP 
            TTT                    III             PPP
            TTT                    III             PPP
            TTT                    III             PPP
           TTTTT             IIIIIIIIIIIIIII      PPPPP 
           TTTTT             IIIIIIIIIIIIIII      PPPPP 
  
  
  
  
                                                            XXXX : CJR
?_$J+                                                       DOWN UNDER
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T M O D E 4 T I P                                 * 
*                                                                     * 
*     MODE 4 TERMINAL INTERFACE PROGRAM     (OPS LEVEL)               * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THE TIP SUPPORTS TERMINALS CONFORMING TO THE CDC       * 
*              MODE 4 PROTOCOL. SEVERAL VARIANTS OF THE PROTOCOL      * 
*              EXIST, AND THE FOLLOWING LIST SHOWS THE SUPPORTED      * 
*              VARIANTS AND CDC TERMINALS TO WHICH THE VARIANTS       * 
*              APPLY.                                                 * 
*                                                                     * 
*              MODE 4A             200 UT, 214, 731, 734, CYBER 18    * 
*              MODE 4B             711-10                             * 
*              MODE 4C             714-10/20, 714-30                  * 
*                                                                     * 
*              THE TIP SUPPORTS MULTIPLE TERMINALS ON A LINE. IN      * 
*              ADDITION, TERMINALS USING A DIFFERENT VARIANT OF THE   * 
*              PROTOCOL, OR A DIFFERENT CODE SET CAN SHARE THE SAME   * 
*              LINE. THE TIP TREATS EACH LINE AS A MULTIDROP LINE,    * 
*              EACH DROP BEING REFERRED TO AS A CLUSTER, AND EACH     * 
*              CLUSTER BEING CAPABLE OF SUPPORTING MULTIPLE DEVICES.  * 
*                                                                     * 
*              THE TIP IS STRUCTURED AS A MULTI-LEVEL DRIVER, AND IS  * 
*              ACTIVATED BY EXTERNAL EVENTS (WORKLISTS).              * 
*              THE DISCRETE LEVELS ARE SHOWN BELOW :                  * 
*                                                                     * 
*              LEVEL 5             LINE CONTROL                       * 
*              LEVEL 4             CLUSTER CONTROL                    * 
*              LEVEL 3             DEVICE CONTROL                     * 
*              LEVEL 2             PROTOCOL CONTROL                   * 
*              LEVEL 1             PHYSICAL INPUT / OUTPUT CONTROL    * 
*                                                                     * 
*              UNDER NORMAL RUNNING CONDITIONS, CONTROL IS PASSED     * 
*              SEQUENTIALLY THROUGH THE LEVELS IN BOTH DIRECTIONS,    * 
*              ALTHOUGH THE SEQUENCE MAY BE PRE-EMPTED IN CERTAIN     * 
*              CIRCUMSTANCES TO IMPROVE OVERALL RESPONSE TIME         * 
*              PERFORMANCE.                                           * 
*                                                                     * 
** INPUT -     WORKLISTS ENTRIES FROM -                               * 
*                SERVICE MODULE                                       * 
*                BLOCK INTERFACE PROGRAM                              * 
*                TIMING SERVICES                                      * 
*                MULTIPLEX SUBSYSTEM                                  * 
*                MODE 4 INPUT STATES                                  * 
*                MODE 4 PREVIEW OUTPUT DATA AND COMMANDS              * 
*                MODE 4 MUX-LEVEL TIP                                 * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PBMON               OPS LEVEL MONITOR                  * 
*              PT4SCAN             PREVIEW OUTPUT DATA AND COMMANDS   * 
*                                                                     * 
** OUTPUT -    COMMUNICATIONS WITH MODE 4 TERMINALS                   * 
*                                                                     * 
** EXTERNAL SUBROUTINES -   MAIN PROCEDURE ONLY                       * 
*              PBGET1BF            GET A BUFFER                       * 
*              PBCLR               CLEAR AN AREA OF MEMORY            * 
*              PBREL1BF            RELEASE A BUFFER                   * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*                           LOGICALLY PART OF THE TIP                 * 
*              PT4TPREL            RELEASE TEXT PROCESSING INFORMATION* 
*              PT4TEXTPROCESS      MODE 4 OUTPUT TEXT PROCESSOR       * 
*              PT4SCAN             PREVIEW OUTPUT DATA AND COMMANDS   * 
*              PT4MUXLEVEL         MODE 4 MUX LEVEL TIP               * 
*                                                                     * 
** INTERNAL SUBROUTINES -   IN ORDER OF DECLARATION                   * 
*              PT4IO               PERFORM INPUT / OUTPUT SEQUENCE    * 
*              PT4TERMIO           TERMINATE INPUT AND OUTPUT         * 
*              PT4RETURN           RETURN TO A GIVEN ADDRESS          * 
*              PT4CONTROL          GIVE CONTROL TO NEXT CCB ON LINE   * 
*              PT4DELINK           DELINK A CCB OR TCB                * 
*              PT4TELLSVM          SEND WORKLIST TO SERVICE MODULE    * 
*              PT4RESTARTIMER      RESTART A CCB / TCB TIMER          * 
*              PT4TMREXPIRED       CHECK IF CCB / TCB TIMER EXPIRED   * 
*              PT4ATTEMPTREC       CHECK IF RECOVERY ATTEMPT IS DUE   * 
*              PT4INQUEUE          QUEUE PARTIAL INPUT DATA           * 
*              PT4INRELEASE        RELEASE ALL INPUT BUFFERS          * 
*              PT4UPDEVICE         BRING A DEVICE UP                  * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*              PT4UPCLUSTER        BRING A CLUSTER UP                 * 
*              PT4RELAUTOREC       RELEASE AUTO-REC STRUCTURES        * 
*              PT4DNLINE           BRING A LINE DOWN                  * 
*              PT4AUTORECRESULT    REPORT AUTO-RECOGNITION RESULTS    * 
*              PT4BUILDWRITE       BUILD A CANNED WRITE MESSAGE       * 
*              PT4BINTERRUPT       SEND BATCH INTERRUPTS              * 
*              PT4PROCESSCMD       PROCESS CMD / ICMD BLOCKS          * 
*              PT4PREOUTPUT        PRE-OUTPUT PROCESSING              * 
*              PT4DPINPUT          CONSOLE POST INPUT PROCESSING      * 
*              PT4CPINPUT          CARD READER POST INPUT PROCESSING  * 
*              PT4VERIFY           VERIFY TERMINAL RESPONSE           * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*              PT4LINEDRIVER       SERVICE ALL CLUSTERS ON A LINE     * 
*              PT4TCBINIT          INITIALIZE NEW TCB                 * 
*                                                                     * 
** NAMING CONVENTIONS -                                               * 
*              PT4...              MODE 4 PROCEDURE OR FUNCTION       * 
*              V4....              MODE 4 CONSTANT                    * 
*              V5....              MODE 4 TYPE                        * 
*              V6....              MODE 4 VARIABLE                    * 
*              BZ4...              MODE 4 LINE CONTROL BLOCK FIELD    * 
*              BV....              MODE 4 CLUSTER CONTROL BLOCK FIELD * 
*              BS4...              MODE 4 TERMINAL CONTROL BLOCK FIELD* 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              DEPENDING ON THE TERMINALS BEING USED, THE NEEDS OF    * 
*              THE USER, AND THE COMMUNICATIONS MEDIA, IT MAY BE      * 
*              ADVANTAGEOUS TO TUNE CERTAIN PARAMETERS USED BY THE    * 
*              TIP. THESE PARAMETERS ARE LOCATED AT THE START OF THE  * 
*              CONSTANT DEFINITIONS, AND THEIR RELEVANCE IS           * 
*              OUTLINED BELOW.                                        * 
*                                                                     * 
*                NAME           DEFAULT          MEANING              * 
*                ----           -------          -------              * 
*                                                                     * 
*              V4TINPUT        1.0 -  1.5   THE TIME IN WHICH A       * 
*                                           TERMINAL MUST RESPOND.    * 
*                                                                     * 
*              V4TUCFAST          0.5       THE TIME BETWEEN POLLS /  * 
*                                           STATUS REQUESTS FOR A     * 
*                                           CLUSTER IN FAST MODE.     * 
*                                                                     * 
*              V4TUCSLOW          1.0       THE TIME BETWEEN POLLS /  * 
*                                           STATUS REQUESTS FOR A     * 
*                                           CLUSTER IN SLOW MODE.     * 
*                                                                     * 
*              V4TSLOWDOWN       30.0       THE TIME AFTER WHICH A    * 
*                                           CLUSTER WILL GO FROM      * 
*                                           FAST TO SLOW MODE IF      * 
*                                           THERE IS NO DATA TRAFFIC. * 
*                                                                     * 
*              V4TDCSINGLE       10.0       THE TIME BETWEEN CLUSTER  * 
*                                           RECOVERY ATTEMPTS ON A    * 
*                                           POINT TO POINT LINE.      * 
*                                                                     * 
*              V4TDCMULTI        50.0       THE TIME BETWEEN CLUSTER  * 
*                                           RECOVERY ATTEMPTS ON A    * 
*                                           MULTI-DROP LINE.          * 
*                                                                     * 
*              V4TDNDEVICE       50.0       THE TIME BETWEEN DEVICE   * 
*                                           RECOVERY ATTEMPTS.        * 
*                                                                     * 
*              V4MAXRETRY         10        THE NUMBER OF CONSECUTIVE * 
*                                           PROTOCOL ERRORS ACCEPTED  * 
*                                           BEFORE THE CLUSTER /      * 
*                                           DEVICE IS DECLARED DOWN.  * 
*                                                                     * 
*              THE TIME PERIODS BETWEEN LONG TERM ERROR RECOVERY      * 
*              ATTEMPTS SHOWN ABOVE ARE NOT PRECISE AS THE TIP ONLY   * 
*              PERMITS ONE SUCH ATTEMPT EACH CYCLE OF THE LINE.       * 
*                                                                     * 
** COMPILER OPTIONS -                                                 * 
*              ?_$R-,G-,I-         NON RECURSIVE AND INTERRUPTABLE    * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
?_$J+?
PROCEDURE PTMODE4TIP; 
  
              _ L A B E L   D E C L A R A T I O N S ? 
LABEL 
      999;                                  _EXIT FROM MODE 4 TIP      ?
  
              _ C O N S T A N T   D E F I N I T I O N S ? 
CONST 
_ 
* * * *   100 MILLI-SECOND TIMER (CTIMER.CT100MS) CONSTANTS 
? 
      V4TUCFAST      = 5;                   _CLUSTER UP IN FAST MODE   ?
      V4TUCSLOW      = 10;                  _CLUSTER UP IN SLOW MODE   ?
      V4TSLOWDOWN    = 300;                 _TIME BEFORE FAST -> SLOW  ?
      V4TDCSINGLE    = 100;                 _CLUSTER DOWN ONLY CLUSTER ?
      V4TDCMULTI     = 500;                 _CLUSTER DOWN MULTI ON LINE?
      V4TDNDEVICE    = 500;                 _DEVICE DOWN IN RECOVERY   ?
      V4TLPQUEUE     = 50;                  _SWITCH FROM LP TO CONSOLE ?
_ 
* * * *   HALF SECOND TIMER CONSTANTS 
? 
      V4TIDLE        = 1;                   _IDLE LINE DELAY TIMEOUT   ?
      V4TOUTPUT      = 21;                  _TIMEOUT DURING OUTPUT     ?
      V4TINPUT       = 3;                   _TIMEOUT FOR INPUT RESPONSE?
_ 
* * * *   RETRY LIMIT FOR PROTOCOL ERRORS 
? 
      V4MAXRETRY     = 10;                  _RETRY COUNT BEFORE DOWN   ?
      V4REJRETRY     = 64;                  _RETRY COUNT BATCH REJECTS ?
_ 
* * * *   DEVICES STATES
? 
      V4DSTART       = 0;                   _INITIAL STATE             ?
      V4DIOWAIT      = 1;                   _NORMAL RUNNING STATE      ?
      V4DOUTWAIT     = 2;                   _CONSOLE COMPLETE OUTPUT   ?
      V4DREJECT      = 2;                   _MODE 4A BATCH REJECT STATE?
      V4DBATCHWAIT   = 3;                   _MODE 4A CONSOLE BATCH WAIT?
     _V4DRECOVER     = 4;?                  _LONG TERM ERROR RECOVERY  ?
      V4DDEAD        = 5;                   _NON EXISTENT DEVICE STATE ?
_ 
* * * *   CLUSTER STATES
? 
      V4CNORMAL      = 0;                   _NORMAL RUNNING STATE      ?
      V4CRECOVER     = 1;                   _LONG TERM ERROR RECOVERY  ?
_ 
* * * *   LINE STATES 
? 
      V4LDISABLED    = 1;                   _DISABLED                  ?
      V4LINOPERATIVE = 2;                   _INOPERATIVE               ?
      V4LWAITCB      = 3;                   _WAITING FOR TCBS          ?
      V4LTERMIO      = 4;                   _TERMINATING INPUT / OUTPUT?
      V4LACTIVE      = 5;                   _ACTIVE WITH INPUT / OUTPUT?
      V4LDELAYED     = 6;                   _ACTIVE BUT DELAYED        ?
_ 
* * * *   MODE 4C PRINTER FLAGS 
? 
      V4LPNOTRDYBUSY = 0;                   _NOT READY AND BUSY        ?
      V4LPRDYNOTBUSY = 3;                   _READY AND NOT BUSY        ?
_ 
* * * *   MODE 4A BATCH FLAGS 
? 
      V4BACTIVE      = 2;                   _BATCH DEVICE ON + NO WAIT ?
_ 
* * * *   BOOLEAN FOR PT4RESTARTIMER, PT4TMREXPIRED, PT4ATTEMPTREC, AND 
* * * *               PT4VERIFY 
? 
      V4TCB          = FALSE;               _TIMER/COUNT/RECOVER IN TCB?
      V4CCB          = TRUE;                _TIMER/COUNT/RECOVER IN CCB?
_ 
* * * *   REASONS FOR DOWNING A CLUSTER OR DEVICE 
? 
      V4EDELETE      = 0;                   _DEVICE BEING DELETED      ?
      V4ENORSP       = CEM4NORSP;           _NO RESPONSE               ?
      V4EBADRSP      = CEM4BDRSP;           _BAD RESPONSE              ?
      V4EERRRSP      = CEM4ERRSP;           _ERROR RESPONSE            ?
_ 
* * * *   MESSAGE TYPE INDICATORS 
? 
      V4MPOLL        = $05;                 _POLL                      ?
      V4MWRITE       = $11;                 _WRITE                     ?
      V4MCLRWRITE    = $12;                 _CLEAR WRITE               ?
      V4MRSTWRITE    = $0C;                 _RESET WRITE               ?
      V4MBSTSREQ     = $17;                 _MODE 4B STATUS REQUEST    ?
      V4MCSTSREQ     = $1C;                 _MODE 4C STATUS REQUEST    ?
      V4MCONFIG      = $19;                 _CONFIGURATION REQUEST     ?
_ 
* * * *   I  /  0   T Y P E S 
? 
_ 
* * * *   WRITE TYPES 
? 
      V4WCLRWRT      = 0;                   _CLEAR WRITE               ?
      V4WE3          = 1;                   _WRITE E3 FOR CARD READING ?
      V4WLPREC       = 2;                   _WRITE FOR M4C LP RECOVERY ?
      V4WAUNLOCK     = 3;                   _WRITE UNLOCK KEYBOARD M4A ?
      V4WCUNLOCK     = 4;                   _WRITE UNLOCK KEYBOARD M4BC?
      V4WLOCK        = 5;                   _WRITE LOCK KEYBOARD M4C   ?
      V4WENDCLR      = 6;                   _CLEAR WRITE BATCH/XPT END ?
      V4WNORMAL      = 7;                   _NORMAL WRITE              ?
_ 
* * * *   POLL / CONFIGURATION REQUEST TYPES
? 
      V4PCONSOLE     = 8;                   _POLL FOR CONSOLE DATA     ?
      V4PCARD        = 9;                   _POLL FOR CARD READER DATA ?
      V4PPRINT       = 10;                  _POLL FOR PRINTER STATUS   ?
      V4PTOGGLE      = 11;                  _POLL FOR TOGGLE BIT       ?
      V4PARADDR      = 12;                  _AUTO-REC POLL FOR ADDRESS ?
      V4PARCODE      = 13;                  _AUTO-REC POLL FOR CODE SET?
      V4PCNFG        = 14;                  _CONFIGURATION REQUEST     ?
_ 
* * * *   STATUS REQUEST TYPE 
? 
      V4STATUS       = 15;                  _NORMAL STATUS REQUEST     ?
      V4STOGGLE      = 16;                  _STATUS REQUEST FOR TOGGLE ?
_ 
* * * *   CONFIGURATION REQUEST CONSTANTS 
? 
      V4FIDX         = $B;                  _INDEX FIRST DATA BYTE - 1 ?
      V4FCONSOLE     = $30;                 _CODE FOR CONSOLE DEVICE   ?
      V4FIPRINT      = $29;                 _CODE FOR IMPACT PRINTER   ?
      V4FNIPRINT     = $2A;                 _CODE FOR NON-IMPACT PRINTR?
      V4FNODEVICE    = $40;                 _CODE FOR NO DEVICE        ?
_ 
* * * *   TERMINAL ADDRESS FOR ALL DEVICES
? 
      V4ALLTA        = $60; 
_ 
* * * *   INPUT ADDRESS CONSTANTS 
? 
      V4XIDX         = 6;                   _INDEX TO CA/TA IN BUFFER  ?
      V4X4AMASK      = $7F60;               _MODE 4A / TOGGLE POLL MASK?
      V4X4CMASK      = $7F6F;               _MODE 4BC NORMAL MASK      ?
_ 
* * * *   WORKCODES FROM INPUT STATES 
? 
      V4WKE1         = A0WK1;               _READ E1 RECEIVED          ?
      V4WKE2         = A0WK2;               _READ E2 RECEIVED          ?
      V4WKE3         = A0WK3;               _READ E3 RECEIVED          ?
      V4WKSLC        = A0WK4;               _SLIPPED CARD RECEIVED     ?
      V4WKBUFT       = A0WK5;               _BUFFER THRESHOLD REACHED  ?
      V4WKACK        = A0WK6;               _ACKNOWLEDGE RECEIVED      ?
      V4WKREJ        = A0WK7;               _REJECT RECEIVED           ?
      V4WKERR        = A0WK8;               _ERROR RECEIVED            ?
      V4WKASC        = A0WK9;               _ASCII RESPONSE RECEIVED   ?
      V4WKBCD        = A0WK10;              _BCD RESPONSE RECEIVED     ?
      V4WKSOFT       = A0WK11;              _SOFT ERROR DETECTED       ?
  
      V4WKPART       = A0WK14;              _PARTIAL INPUT DATA        ?
_ 
* * * *   TIP INTERNAL WORKCODES
? 
      V4WKBAD        = A0WK12;              _BAD ADDRESS IN RESPONSE   ?
      V4WKTIMO       = A0WK13;              _TIMEOUT RECEIVED          ?
  
     _V4WKDLCMD      = A0WK15;?             _DOWNLINE PRINTER COMMAND  ?
      V4WKINPTERM    = A0WK16;              _INPUT TERMINATED WORKLIST ?
_ 
* * * *   AUTO RECOGNITION CONSTANTS
? 
      V4AUTOREC      = N1CP;                _AUTO-REC DEVICE TYPE      ?
      V4ARCA         = $7C;                 _FIRST CA ATTEMPTED        ?
      V4ARTA         = $60;                 _TA USED IN AUTO REC       ?
      V4ARRETRY      = 36;                  _MAX NUMBER OF POLLS SENT  ?
  
      V4ARADDRESS    = 0;                   _DEVICE STATE GET ADDRESS  ?
      V4ARCODESET    = 1;                   _DEVICE STATE GET CODE SET ?
      V4ARCNFIG      = 2;                   _DEVICE STATE GET CONFIGURN?
  
      V4A4ABCD       = $0101;               _MODE 4A BCD RECOGNIZED    ?
      V4A4AASCII     = $0201;               _MODE 4A ASCII RECOGNIZED  ?
      V4A4CASCII     = $0202;               _MODE 4C ASCII RECOGNIZED  ?
  
              _ T Y P E   D E F I N I T I O N S ? 
TYPE
      V5CATA   = PACKED RECORD              _CLUSTER AND TERMINAL ADDR ?
                 CASE V5X : INTEGER OF
                 1: (V5INT    : INTEGER);   _INTEGER OVERLAY           ?
                 2: (V5SET    : SETWORD);   _SET OVERLAY               ?
                 3: (V5DUM1   : B011BITS;   _FORCE CORRECT BIT         ?
                     V5TOGBIT : BOOLEAN;    _TOGGLE BIT                ?
                     V5DUM2   : B04BITS);   _FORCE CORRECT BIT         ?
                 END; 
  
      V5ADDR   = PACKED RECORD              _CLUSTER OR TERMINAL ADDR  ?
                 CASE V5X : INTEGER OF
                 1: (V5TINT   : INTEGER);   _INTEGER OVERLAY           ?
                 2: (V5DUM3   : B012BITS; 
                     V5TIDX   : B04BITS);   _LOWER 4 BITS (UNIQUE) ADDR?
                 END; 
  
      V5RSPS   = (V4RE1,  V4RE2,  V4RE3,  V4RSLC, 
                  V4RBUFT,V4RACK, V4RREJ, V4RERR, 
                  V4RASC, V4RBCD, V4RSOFT,V4RBAD, 
                  V4RTIMO,V4RSP1, V4RSP2, V4RSP3);
  
      V5RSPTYP = SET OF V5RSPS;             _B00 : V4RE1 - B15 : V4RSP3?
  
      V5RESP   = PACKED RECORD              _INPUT RESPONSE TYPE       ?
                 CASE V5X : INTEGER OF
                 1: (V5SETWD  : V5RSPTYP);  _RESPONSE BITS             ?
                 2: (V5BITS   : SETWORD);   _SETWORD OVERLAY           ?
                 END; 
  
              _ V A R I A B L E   D E C L A R A T I O N S ? 
VAR 
      V6HEADER       : PACKED ARRAY [0..7]  _ M O D E 4 T I P          ?
                         OF CHAR; 
      V6DBGI         : INTEGER;             _INDEX NEXT WORKLIST ENTRY ?
      V6DBGA         : ARRAY [0..24]        _SAVED WORKLIST ENTRY ARRAY?
                         OF BWTIPWLE; 
      V6LCBP         : BZLCBP;              _CURRENT LCB POINTER       ?
      V6CCBP         : B0BUFPTR;            _CURRENT CCB POINTER       ?
      V6BUFP         : B0BUFPTR;            _CURRENT BUFFER POINTER    ?
      V6WKCODE       : INTEGER;             _CURRENT WORK CODE         ?
      V6LSTATE       : INTEGER;             _CURRENT LINE STATE        ?
      V6LINO         : B0LINO;              _CURRENT LINE NUMBER       ?
      V6CMDP         : NKINCOM;             _COMMAND PACKET            ?
      V6RESPONSE     : V5RESP;              _INPUT RESPONSE SET        ?
      V6TERMIO       : BOOLEAN;             _TERMINATE I/O REQUIRED    ?
      V6TA           : V5ADDR;              _TERMINAL ADDRESS          ?
      V6RXCATA       : V5CATA;              _RECEIVED CA AND TA        ?
      V6ADDRMASK     : V5CATA;              _ADDRESS MASK FOR RCVD CATA?
      V6RXMASK       : ARRAY [BOOLEAN]      _MODE 4A / 4C ADDRESS MASKS?
                         OF INTEGER;
      V6FLGWD        : KTULTSFLAG;          _BIP UPLINE FLAG WORD      ?
      V6EOIFND       : BOOLEAN;             _EOI FOUND IN CARD DATA    ?
      V6RADLINE      : INTEGER;             _RETURN ADDR TO LINE DRIVER?
      V6RADCLUSTER   : INTEGER;             _RETURN ADDR TO CLUSTER DVR?
      V6NIL          : B0BUFPTR;            _NIL BUFFER POINTER        ?
  
              _ V A L U E   A S S I G N M E N T S ? 
VALUE 
      V6HEADER       = (#MODE4TIP#);
      V6CMDP         = (8*0); 
      V6RXMASK       = (V4X4CMASK, V4X4AMASK);
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 I O                                           * 
*                                                                     * 
*       PERFORM INPUT / OUTPUT SEQUENCE                               * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ISSUES THE INPUT AFTER OUTPUT COMMAND     * 
*              TO THE LINE, AND SETS UP THE CONDITIONS SO THAT        * 
*              CONTROL WILL BE RETURNED TO THE CALLER WHEN THE INPUT  * 
*              IS COMPLETED OR THE INPUT TIMER HAS EXPIRED.           * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              POSSIBLE TCB POINTER               * 
*              BUFFER ADDRESS TO OUTPUT - NIL INDICATES IDLE THE LINE * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4LINEDRIVER       SERVICE ALL CLUSTERS ON A LINE     * 
*                                                                     * 
** OUTPUT -    LCB FIELDS UPDATED, COMMAND SENT TO MUX SUBSYSTEM      * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBCOIN              COMMAND DRIVER                     * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THE CALLERS RETURN ADDRESS IN SAVED IN THE LCB         * 
*              AND CONTROL WILL RETURN TO THAT ADDRESS WHEN A         * 
*              WORKLIST INDICATING COMPLETION OF THE I/O IS RECEIVED. * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4IO (V6OBUF : B0BUFPTR);
  
CONST 
      V4SYNC  = 4;                          _STATE INDEX LOOK FOR SYNC ?
  
VAR 
      V6ASCII : BOOLEAN;                    _ASCII CODE SET FLAG       ?
  
BEGIN 
_ 
* * * *   SET UP LCB AND TIMER TABLE ENTRY FIELDS 
? 
WITH V6LCBP',                               _SET INDEX TO LCB          ?
     BLTIMTBL'[V6LINO.BDPORT] DO            _SET INDEX TO TIMER TABLE  ?
  BEGIN 
  RETADR (BZRET1ADDR);                      _SAVE RETURN ADDRESS IN LCB?
  BZWTCOUNT := BZWTCOUNT + 1;               _BUMP CONTENTION COUNTER   ?
  BZLBTOMUX := V6OBUF;                      _SAVE LAST BUFFER TO MUX   ?
  IF V6OBUF = NIL                           _ENTERED WITH NO BUFFER    ?
  THEN
    BEGIN 
    BLTIME := V4TIDLE;                      _SET IDLE LINE TIME PERIOD ?
    GOTO EXIT 999;                          _RETURN TO OPS MONITOR     ?
    END;
  BZ4DELAYLINE := FALSE;                    _I/O ACTIVE NO REASON DELAY?
  BLTIME       := V4TOUTPUT;                _SET OUTPUT TIMER          ?
  BLTRESET     := V4TINPUT;                 _SET INPUT TIMER           ?
  END; _WITH V6LCBP', BLTIMTBL' .... DO?
_ 
* * * *   SET UP VARIANT PORTION OF COMMAND PACKET
? 
WITH V6CMDP DO                              _COMMAND PACKET            ?
  BEGIN 
  NKUOPS := 0;                              _CLEAR USER OPTION FLAGS   ?
  NKMVB  := TRUE;                           _SET MOVE USER FLAGS       ?
  NKUOP5 := TRUE;                           _DEFAULT TO NOT FULL ASCII ?
  IF V6CCBP'.BVCCB.BVIOTYPE \ V4PARADDR 
  THEN                                      _A-R, STATUS, CONFG REQUEST?
    NKUOP1 := TRUE                          _SET AUTO-REC FLAG         ?
  ELSE
    WITH V6TCBP'.BSTCB DO                   _SET INDEX TO TCB          ?
      BEGIN 
      V6ASCII := BSCODE = N0ASCII;          _SAVE ASCII CODE SET FLAG  ?
      IF BSBATCH
      THEN                                  _BATCH DEVICE              ?
        BEGIN 
        NKCXLTA := V6IBCXLTA [V6ASCII];     _SET TRANSLATE TABLE ADDR  ?
        NKUOP7  := V6CCBP'.BVCCB.BVJOBCARD; _SET IF JOB CARD EXPECTED  ?
        END 
      ELSE
        BEGIN                               _INTERACTIVE DEVICE        ?
        NKCXLTA := V6IICXLTA [V6ASCII];     _SET TRANSLATE TABLE ADDR  ?
        NKUOP2  := TRUE;                    _SET INTERACTIVE DEVICE FLG?
        IF BSXPT
        THEN                                _TRANSPARENT INTERACTIVE   ?
          BEGIN 
          NKUOP3 := TRUE;                   _SET TRANSPARENT FLAG      ?
          NKUOP4 := V6ASCII;                _SET IF ASCII CODE SET     ?
          END _IF BSXPT THEN? 
        ELSE
          BEGIN                             _NON-TRANSPARENT INTERACTIV?
          NKUOP5 := NOT BSFLASCII;          _SET IF NOT FULL ASCII     ?
          NKUOP6 := BSELCHAR = BSEBCHAR;    _SET IF EOL = EOB          ?
          NKCNT1 := BSPGWIDTH;              _SET COLUMN COUNT          ?
          END; _IF BSXPT ELSE?
        END; _IF BSBATCH ELSE?
      END; _WITH V6TCBP'.BSTCB DO?
_ 
* * * *   SET UP REST OF COMMAND PACKET, AND ISSUE THE COMMAND
? 
  NKISTAI := V4SYNC;                        _SET INPUT STATE INDEX     ?
  NKOBP   := V6OBUF;                        _SET OUTPUT BUFFER ADDRESS ?
  NKCMD   := NKINOUT;                       _SET INPUT AFTER OUTPUT CMD?
  END; _WITH V6CMDP DO? 
  
PBCOIN (V6CMDP);                            _ISSUE THE COMMAND         ?
  
GOTO EXIT 999;                              _RETURN TO OPS MONITOR     ?
END; _PROCEDURE PT4IO?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 T E R M I O                                   * 
*                                                                     * 
*       TERMINATE INPUT AND OUTPUT                                    * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ISSUES THE TERMINATE OUTPUT / INPUT       * 
*              COMMANDS , AND SETS UP THE CONDITIONS SO THAT          * 
*              CONTROL WILL RETURN TO THE CALLER WHEN THE I/O         * 
*              HAS BEEN SUCCESSFULLY TERMINATED.                      * 
*                                                                     * 
** INPUT -     V6LCBP              LCB POINTER                        * 
*              NEW STATE OF THE LINE                                  * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DNLINE           BRING A LINE DOWN                  * 
*              PT4AUTORECRESULT    REPORT AUTO-RECOGNITION RESULTS    * 
*              PT4LINEDRIVER       SERVICE ALL CLUSTERS ON A LINE     * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    COMMANDS SENT TO MUX SUBSYSTEM                         * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBCOIN              COMMAND DRIVER                     * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THE CALLERS RETURN ADDRESS IS SAVED IN THE LCB         * 
*              AND CONTROL WILL BE RETURNED TO THAT ADDRESS WHEN      * 
*              THE INPUT TERMINATED WORKLIST IS RECEIVED.             * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4TERMIO (V6NEXTSTATE : INTEGER);
  
VAR 
      V6WTCOUNT : INTEGER;                  _LOCAL COPY OF WAIT COUNT  ?
  
BEGIN 
_ 
* * * *   UPDATE LCB FIELDS, AND ISSUE TERMINATE OUTPUT COMMAND 
? 
RETADR (V6LCBP'.BZRET2ADDR);                _SAVE RETURN ADDRESS IN LCB?
V6LCBP'.BZSTATE   := V6NEXTSTATE;           _SET NEW STATE IN LCB      ?
V6WTCOUNT         := V6LCBP'.BZWTCOUNT + 1; _BUMP CONTENTION COUNTER   ?
V6LCBP'.BZWTCOUNT := V6WTCOUNT;             _STORE IT BACK IN THE LCB  ?
V6CMDP.NKRELBFS   := FALSE;                 _DO NOT RELEASE BUFFERS    ?
V6CMDP.NKWKFLG    := FALSE;                 _NO WL ON TERMINATE OUTPUT ?
V6CMDP.NKCMD      := NKENDOT; 
PBCOIN (V6CMDP);                            _ISSUE TERMINATE OUTPUT CMD?
_ 
* * * *   NOW ISSUE TERMINATE INPUT COMMAND 
? 
V6CMDP.NKRELBFS   := TRUE;                  _RELEASE ANY INPUT BUFFERS ?
V6CMDP.NKWKFLG    := TRUE;                  _SEND WL ON TERMINATE INPUT?
V6CMDP.NKWKCOD    := V4WKINPTERM;           _WORKCODE INPUT TERMINATED ?
V6CMDP.NKWLINDX   := B0M4WL;                _HOPEFULLY BACK TO THIS TIP?
V6CMDP.NKUSRBY    := V6WTCOUNT;             _STORE CONTENTION COUNTER  ?
V6CMDP.NKCMD      := NKENDIN; 
PBCOIN (V6CMDP);                            _ISSUE TERMINATE INPUT CMD ?
  
GOTO EXIT 999;                              _RETURN TO OPS MONITOR     ?
END; _PROCEDURE PT4TERMIO?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 R E T U R N                                   * 
*                                                                     * 
*       RETURN TO A GIVEN ADDRESS                                     * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE RETURNS CONTROL TO THE ADDRESS SPECIFIED. * 
*              IT IS THE CALLERS RESPONSIBILITY TO SET UP THE INDEX   * 
*              REGISTERS (WITH STATEMENTS) SO THAT PROGRAM            * 
*              RE-ENTRANCY IS POSSIBLE.                               * 
*                                                                     * 
** INPUT -     SAVED RETURN ADDRESS                                   * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4CONTROL          GIVE CONTROL TO NEXT CCB ON LINE   * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    NONE                                                   * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              NONE                                                   * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THIS ROUTINE WILL NEVER RETURN TO ITS CALLER.          * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4RETURN (V6RETURNADDR : INTEGER); 
  
BEGIN 
RETURN (V6RETURNADDR);                      _ALTER PROCEDURES RETURN   ?
END; _PROCEDURE PT4RETURN?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 C O N T R O L                                 * 
*                                                                     * 
*       GIVE CONTROL TO THE NEXT CLUSTER ON LINE                      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE SETS THE CONDITIONS SO THAT THE CURRENT   * 
*              CLUSTER IS RESERVED BY THIS DEVICE AND CONTROL IS      * 
*              GIVEN TO SERVICE THE NEXT CLUSTER ON THE LINE.         * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              V6CCBP              CURRENT CCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    CLUSTER RESERVED AND RETURN ADDRESS SAVED              * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4RETURN           RETURN TO A GIVEN ADDRESS          * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              IF THIS IS THE ONLY CLUSTER ON THE LINE THEN CONTROL   * 
*              WILL BE IMMEDIATELY RETURNED TO THE CALLER , ELSE      * 
*              THE CALLERS RETURN ADDRESS IS SAVED IN THE CCB, AND    * 
*              CONTROL WILL RETURN TO THAT ADDRESS WHEN THIS CLUSTER  * 
*              IS SERVICED AGAIN.                                     * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4CONTROL; 
  
BEGIN 
IF V6LCBP'.BZ4MLTCLS                        _MULTIPLE CLUSTERS ON LINE ?
THEN
  BEGIN 
  V6CCBP'.BVCCB.BVRESERVED := TRUE;         _FLAG THE CLUSTER RESERVED ?
  RETADR (V6CCBP'.BVCCB.BVRETRESERVED);     _SAVE THE RETURN ADDRESS   ?
  PT4RETURN (V6RADLINE);                    _RETURN TO THE LINE DRIVER ?
  END;
END; _PROCEDURE PT4CONTROL? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 D E L I N K                                   * 
*                                                                     * 
*       DELINK A CLUSTER OR TERMINAL CONTROL BLOCK                    * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE DELINKS A STRUCTURE (CCB / TCB)           * 
*              FROM A GIVEN CHAIN (LCB-TCB / LCB-CCB / CCB-TCB)       * 
*                                                                     * 
** INPUT -     POINTER TO ENTRY TO BE DELINKED                        * 
*              POINTER TO FIRST ENTRY IN CHAIN                        * 
*              WORD INDEX OF CHAIN WORD IN STRUCTURE                  * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    ENTRY DELINKED FROM CHAIN                              * 
*              POINTER TO FIRST ENTRY UPDATED IF NECESSARY            * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              NONE                                                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4DELINK (V6ENTRY : B0BUFPTR; VAR V6FIRST : B0BUFPTR;
                     V6INDEX : INTEGER);
  
VAR 
      V6PREVP : B0BUFPTR;                   _PREVIOUS CTRL BLK POINTER ?
  
BEGIN 
IF V6FIRST = V6ENTRY                        _FIRST ENTRY TO BE DELINKED?
THEN
  V6FIRST := V6ENTRY'.BCCHAINS [V6INDEX]    _YES MAKE SECOND FIRST     ?
ELSE
  BEGIN                                     _NO  SEARCH THRU CHAIN     ?
  V6PREVP := V6FIRST;                       _START AT BEGINNING        ?
  WHILE V6PREVP'.BCCHAINS [V6INDEX] "       _SEARCH FOR PREVIOUS ENTRY ?
        V6ENTRY DO
    V6PREVP := V6PREVP'.BCCHAINS [V6INDEX]; 
  V6PREVP'.BCCHAINS [V6INDEX] :=
    V6ENTRY'.BCCHAINS [V6INDEX];            _DELINK THE ENTRY          ?
  
  END; _IF V6FIRST = V6ENTRY ELSE?
END; _PROCEDURE PT4DELINK?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 T E L L S V M                                 * 
*                                                                     * 
*       SEND WORKLIST TO SERVICE MODULE                               * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE SENDS A USER SPECIFIED WORKLIST TO THE    * 
*              TO THE SERVICE MODULE.                                 * 
*                                                                     * 
** INPUT -     V6LINO              CURRENT LINE NUMBER                * 
*              V6TCBP              CURRENT TCB POINTER / A-R PARAMS   * 
*              WORKCODE   OF WORKLIST ENTRY                           * 
*              DATA FIELD OF WORKLIST ENTRY                           * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4UPDEVICE         BRING A DEVICE UP                  * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*              PT4DNLINE           BRING A LINE DOWN                  * 
*              PT4AUTORECRESULT    REPORT AUTO-RECOGNITION RESULTS    * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    WORKLIST ENTRY QUEUED TO SERVICE MODULE                * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBLSPUT             MAKE A WORKLIST ENTRY              * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4TELLSVM (V6SVMWKCODE : INTEGER ; V6SVMDATA : INTEGER); 
  
BEGIN 
WITH BWWLENTRY [OPS].CMSMLEY DO             _OPS LVL INTERMEDIATE ARRAY?
  BEGIN 
  CMWKCODE      := V6SVMWKCODE;             _STORE WORK CODE           ?
  CMDATA        := V6SVMDATA;               _STORE DATA PORTION        ?
  CMLINO.BDLINO := V6LINO.BDLINO;           _STORE LINE NUMBER         ?
  CMPTR         := V6TCBP;                  _STORE POSS. TCB ADDRESS   ?
  END; _WITH BWWLENTRY [OPS].CMSMLEY DO?
  
PBLSPUT (BWWLENTRY [OPS], BYWLCB [B0SMWL]); _SEND WORKLIST TO SVM     ? 
  
END; _PROCEDURE PT4TELLSVM? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 R E S T A R T I M E R                         * 
*                                                                     * 
*       RESTART A CCB / TCB TIMER                                     * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE STARTS A TIMER IN EITHER THE CCB OR TCB.  * 
*              THE TIME PERIOD FOR A CCB IS DEPENDENT ON THE STATUS   * 
*              OF THE CLUSTER AND POSSIBLY THE LINE.                  * 
*                                                                     * 
** INPUT -     WHETHER TIMER IS IN CCB   (POINTED TO BY V6CCBP)       * 
*                               OR TCB   (POINTED TO BY V6TCBP)       * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4TMREXPIRED       CHECK IF CCB / TCB TIMER EXPIRED   * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*                                                                     * 
** OUTPUT -    NEW TIMER SET IN CCB OR TCB                            * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              NONE                                                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4RESTARTIMER (V6TINCCB : BOOLEAN);
  
VAR 
      V6TIME : INTEGER;                     _TIME INCREMENT FOR CLUSTER?
      V6DCLS : ARRAY [BOOLEAN] OF INTEGER;  _CLUSTER DOWN RECOVERY DLYS?
  
VALUE 
      V6DCLS = (V4TDCSINGLE, V4TDCMULTI); 
  
BEGIN 
IF V6TINCCB                                 _TIMER IS IN CCB           ?
THEN
  BEGIN 
  IF V6CCBP'.BVCCB.BVSTATE = V4CNORMAL      _CLUSTER UP AND RUNNING    ?
  THEN                                      _BASE TIMER ON FAST / SLOW ?
    BEGIN                                   _POLLING RATE              ?
    IF V6CCBP'.BVCCB.BVSLOWTIMER -
       CTIMER.CT100MS \ 1 
    THEN                                    _SLOW DOWN TIMER RUNNING   ?
      V6TIME := V4TUCFAST                   _CLUSTER IN FAST MODE      ?
    ELSE
      BEGIN                                 _SLOW DOWN TIMER EXPIRED   ?
      V6TIME := V4TUCSLOW;                  _CLUSTER IN SLOW MODE      ?
      V6CCBP'.BVCCB.BVSLOWTIMER 
                   := CTIMER.CT100MS; 
      END;
    END _IF CLUSTER UP THEN?
  ELSE                                      _CLUSTER CURRENTLY DOWN    ?
    V6TIME := V6DCLS [V6LCBP'.BZ4MLTCLS];   _BASE TIMER ON WHETHER     ?
                                            _LINE HAS MULTIPLE CLUSTERS?
  V6CCBP'.BVCCB.BVTIMER := V6TIME 
                           + CTIMER.CT100MS;
  END _IF V6TINCCB THEN?
ELSE                                        _DEVICE IS CURRENTLY DOWN  ?
  V6TCBP'.BSTCB.BS4TIMER := V4TDNDEVICE +   _SET RECOVERY TIMER        ?
                            CTIMER.CT100MS; 
END; _PROCEDURE PT4RESTARTIMER? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 T M R E X P I R E D                           * 
*                                                                     * 
*       CHECK IF CCB / TCB TIMER EXPIRED                              * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE CHECKS IF A TIMER IN THE CCB OR TCB       * 
*              HAS EXPIRED, AND RESTARTS IT IF IT HAS EXPIRED.        * 
*                                                                     * 
** INPUT -     WHETHER TIMER IS IN CCB   (POINTED TO BY V6CCBP)       * 
*                               OR TCB   (POINTED TO BY V6TCBP)       * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4ATTEMPTREC       CHECK IF RECOVERY ATTEMPT IS DUE   * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*                                                                     * 
** OUTPUT -    TRUE RETURNED IF TIMER HAS EXPIRED                     * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4RESTARTIMER      RESTART A CCB / TCB TIMER          * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
FUNCTION PT4TMREXPIRED (V6TINCCB : BOOLEAN) : BOOLEAN;
  
VAR 
      V6TIMER : INTEGER;                    _LOCAL COPY OF TIMER       ?
  
BEGIN 
PT4TMREXPIRED := FALSE;                     _RETURN FALSE BY DEFAULT   ?
IF V6TINCCB 
THEN
  V6TIMER := V6CCBP'.BVCCB.BVTIMER          _GET TIMER FROM CCB        ?
ELSE
  V6TIMER := V6TCBP'.BSTCB.BS4TIMER;        _            OR TCB        ?
IF V6TIMER - CTIMER.CT100MS < 1 
THEN
  BEGIN                                     _TIMER HAS EXPIRED         ?
  PT4TMREXPIRED := TRUE;                    _RETURN TRUE RESULT        ?
  PT4RESTARTIMER (V6TINCCB);                _RESTART THE EXPIRED TIMER ?
  END;
END; _FUNCTION PT4TMREXPIRED? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 A T T E M P T R E C                           * 
*                                                                     * 
*       CHECK IF LONG TERM ERROR RECOVERY ATTEMPT DUE                 * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE CHECKS IF A LONG TERM ERROR RECOVERY      * 
*              ATTEMPT FOR A CCB / TCB IS DUE AND ALLOWABLE.          * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              WHETHER RECOVERY IS FOR CCB   (POINTED TO BY V6CCBP)   * 
*                               OR FOR TCB   (POINTED TO BY V6TCBP)   * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*                                                                     * 
** OUTPUT -    TRUE RETURNED IF RECOVERY ATTEMPT IS DUE AND ALLOWABLE * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TMREXPIRED       CHECK IF CCB / TCB TIMER EXPIRED   * 
*              PB1BFAVAIL          CHECK SINGLE BUFFER AVAILABLE      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
FUNCTION PT4ATTEMPTREC (V6AINCCB : BOOLEAN) : BOOLEAN;
  
BEGIN 
PT4ATTEMPTREC := FALSE;                     _RETURN FALSE BY DEFAULT   ?
IF V6LCBP'.BZ4RECATTEMPT                    _HAVE NOT ALREADY ATTEMPTED?
THEN                                        _ONE RECOVERY THIS CYCLE   ?
  IF PB1BFAVAIL (B0TH2LV) 
  THEN                                      _NOT LOW ON BUFFERS        ?
    IF PT4TMREXPIRED (V6AINCCB) 
    THEN                                    _AND RECOVERY TIMER EXPIRED?
      BEGIN 
      PT4ATTEMPTREC         := TRUE;        _RETURN TRUE TO CALLER     ?
      V6LCBP'.BZ4RECATTEMPT := FALSE;       _DELAY NEXT ATTEMPT        ?
      END;
  
END; _FUNCTION PT4ATTEMPTREC? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 I N Q U E U E                                 * 
*                                                                     * 
*       QUEUE PARTIAL INPUT DATA                                      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE QUEUES INPUT DATA TO THE TCB AS IT IS     * 
*              RECEIVED FROM THE INPUT STATE PROGRAMS.                * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*              V6BUFP              CURRENT BUFFER POINTER             * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4MODE4TIP         MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    TCB INPUT QUEUE UPDATED                                * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              NONE                                                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4INQUEUE; 
  
VAR 
      V6LBUF : B0BUFPTR;                    _LOCAL BUFFER POINTER      ?
  
BEGIN 
IF V6TCBP'.BSTCB.BS4INBUF = NIL             _INPUT QUEUE EMPTY         ?
THEN
  V6TCBP'.BSTCB.BS4INBUF := V6BUFP          _BUFFER IS FIRST IN QUEUE  ?
ELSE
  BEGIN 
  V6LBUF := V6TCBP'.BSTCB.BS4INBUF;         _GET PTR TO START OF QUEUE ?
  WHILE V6LBUF'.BCCHAINS [QCHN] " NIL DO    _FIND END OF INPUT QUEUE   ?
    V6LBUF := V6LBUF'.BCCHAINS [QCHN];
  V6LBUF'.BCCHAINS [QCHN] := V6BUFP;        _ADD INPUT TO END OF QUEUE ?
  END;
V6BUFP'.BCCHAINS [QCHN] := NIL;             _CLEAR CHAIN WORD OF BUFFER?
V6BUFP                  := NIL;             _CLEAR CURRENT BUFFER PTR  ?
END; _PROCEDURE PT4INQUEUE? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 I N R E L E A S E                             * 
*                                                                     * 
*       RELEASE ALL INPUT BUFFERS                                     * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE RELEASES ALL POSSIBLE INPUT BUFFERS       * 
*              OF AN INPUT TRANSMISSION.                              * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*              V6BUFP              CURRENT BUFFER POINTER             * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    BUFFERS RELEASED, TCB INPUT QUEUE UPDATED              * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4INRELEASE; 
  
VAR 
      V6LBUF : B0BUFPTR;                    _LOCAL BUFFER POINTER      ?
  
BEGIN 
PBRELZRO (V6BUFP, BEDBSIZE);                _RELEASE POSS. CURRENT BFRS?
  
WHILE V6TCBP'.BSTCB.BS4INBUF " NIL DO       _WHILE MORE INPUT IN QUEUE ?
  BEGIN 
  V6LBUF := V6TCBP'.BSTCB.BS4INBUF;         _GET PTR TO INPUT BUFFERS  ?
  V6TCBP'.BSTCB.BS4INBUF := V6LBUF'.        _DELINK FROM INPUT QUEUE   ?
                            BCCHAINS [QCHN];
  PBRELCHN (V6LBUF, BEDBSIZE);              _RELEASE THE INPUT BUFFERS ?
  END;
  
END; _PROCEDURE PT4INRELEASE? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 U P D E V I C E                               * 
*                                                                     * 
*       BRING A DEVICE UP                                             * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE BRINGS UP A DEVICE THAT WAS PREVIOUSLY    * 
*              DOWN, AND INFORMS THE SERVICE MODULE OF THE EVENT.     * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4UPCLUSTER        BRING A CLUSTER UP                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    TCB FIELDS UPDATED                                     * 
*              WORKLIST TO SERVICE MODULE                             * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TELLSVM          SEND WORKLIST TO SERVICE MODULE    * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4UPDEVICE;
  
BEGIN 
V6TCBP'.BSTCB.BS4STATE    := V4DIOWAIT;     _SET TO RUNNING STATE      ?
V6TCBP'.BSTCB.BS4LCOUNT   := 0;             _RESET LINES REMAINING     ?
V6TCBP'.BSTCB.BS4REJCOUNT := 0;             _RESET BATCH REJECT COUNTER?
V6TCBP'.BSTCB.BS4INFLGS   := 0;             _RESET INPUT REQUIRED FLAGS?
V6TCBP'.BSTCB.BS4READREQ  := FALSE;         _RESET ANY READ REQUEST    ?
PT4TELLSVM (D0TCB, D5UP);                   _TELL SVM DEVICE IS UP     ?
END; _PROCEDURE PT4UPDEVICE?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 D N D E V I C E                               * 
*                                                                     * 
*       BRING A DEVICE DOWN                                           * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE BRINGS DOWN A DEVICE THAT WAS PREVIOUSLY  * 
*              UP. ANY ASSOCIATED BUFFERS WILL BE RELEASED, A CE      * 
*              ERROR FILE ENTRY WILL BE MADE, AND THE SERVICE MODULE  * 
*              WILL BE NOTIFIED OF THE EVENT. IF ALL DEVICES ON THE   * 
*              CLUSTER ARE DOWN OR DEAD, THE CLUSTER WILL BE DOWNED.  * 
*                                                                     * 
** INPUT -     V6LINO              CURRENT LINE NUMBER                * 
*              V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*              REASON FOR DOWNING THE DEVICE                          * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4VERIFY           VERIFY TERMINAL RESPONSE           * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    CCB / TCB FIELDS UPDATED, CE ERROR FILE MESSAGE,       * 
*              WORKLIST TO SERVICE MODULE                             * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TELLSVM          SEND A WORKLIST TO SERVICE MODULE  * 
*              PT4RESTARTIMER      RESTART A CCB / TCB TIMER          * 
*              PT4INRELEASE        RELEASE ALL INPUT BUFFERS          * 
*              PT4TPREL            RELEASE TEXT PROCESSING INFORMATION* 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*              PNCEFILE            MAKE A CE ERROR FILE ENTRY         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4DNDEVICE (V6DREASON : INTEGER);
  
VAR 
      V6LTCB : B0BUFPTR;                    _LOCAL TCB POINTER         ?
  
BEGIN 
WITH V6TCBP'.BSTCB DO                       _SET INDEX TO DOWNED TCB   ?
  BEGIN 
_ 
* * * *   RELEASE ANY BUFFERS, SET NEW STATE, AND START RECOVERY TIMER
? 
  PT4INRELEASE;                             _RELEASE ANY INPUT BUFFERS ?
  PBRELZRO (BS4OUTBUF,  BEDBSIZE);          _RELEASE ANY OUTPUT BUFFERS?
  IF BS4STATE < V4DRECOVER                  _NOT ALREADY DOWN OR DEAD  ?
  THEN
    BEGIN 
    BS4STATE := V4DRECOVER;                 _DECLARE DEVICE DOWN       ?
    IF BSDEVTYPE " V4AUTOREC                _NOT A AUTO-RECOGNITION TCB?
    THEN
      BEGIN 
      PT4RESTARTIMER (V4TCB);               _START RECOVERY TIMER      ?
      PBRELZRO (BS4PSOURCE, BEDBSIZE);      _RELEASE ANY PARTIAL SOURCE?
      PT4TPREL;                             _RELEASE POSSIBLE TP BFRS  ?
_ 
* * * *   CLEAR ANY CLUSTER RESERVATION 
? 
      IF V6CCBP'.BVCCB.BVCURTCB = V6TCBP    _DOWNING THE CURRENT TCB   ?
      THEN
        V6CCBP'.BVCCB.BVRESERVED := FALSE;  _CLEAR CLUSTER RESERVATION ?
_ 
* * * *   SEND CE ERROR FILE MESSAGE, AND TELL SVM THE DEVICE IS DOWN 
? 
      IF V6DREASON " V4EDELETE              _NOT BEING DELETED         ?
      THEN
        BEGIN 
        BS4DNCODE := V6WKCODE;              _SAVE WORKCODE RESPONSIBLE ?
        WITH CNCEOVLY [OPS] DO              _CE ERROR FILE OVERLAY     ?
          BEGIN 
          CNCECODE := V6DREASON;            _ERROR CODE                ?
          VM4LINO  := V6LINO.BDLINO;        _LINE NUMBER               ?
          VM4CA    := BSCA;                 _CLUSTER ADDRESS           ?
          VM4TA    := BSTA;                 _TERMINAL ADDRESS          ?
          VM4DT    := BSDEVTYPE;            _DEVICE TYPE               ?
          VM4TC    := BSTCLASS;             _TERMINAL CLASS            ?
          END; _WITH CNCEOVLY [OPS] DO? 
        PNCEFILE (7);                       _SEND CE ERROR FILE MESSAGE?
        PT4TELLSVM (D0TCB, D5DOWN);         _TELL SVM DEVICE IS DOWN   ?
        END; _IF V6DREASON " V4EDELETE THEN?
      END; _IF BSDEVTYPE " V4AUTOREC THEN?
    END; _IF BS4STATE < V4DRECOVER THEN?
_ 
* * * *   DECLARE CLUSTER DOWN, IF ALL DEVICES ARE DOWN OR DEAD 
? 
  V6LTCB := V6CCBP'.BVCCB.BVTCBPTR;         _START WITH 1ST TCB ON CCB ?
  REPEAT
    IF V6LTCB'.BSTCB.BS4STATE < V4DRECOVER  _FOUND A TCB NOT DOWN/DEAD ?
    THEN                                    _CLUSTER NOT DOWN YET      ?
      GOTO 10;
    V6LTCB := V6LTCB'.BSTCB.BS4TCBPTR;      _CHAIN TO NEXT TCB ON CCB  ?
  UNTIL V6LTCB = NIL;                       _UNTIL ALL TCBS CHECKED    ?
  
  V6CCBP'.BVCCB.BVTOGKNOWN := FALSE;        _RESET TOGGLE KNOWN FLAG   ?
  V6CCBP'.BVCCB.BVSTATE    := V4CRECOVER;   _DECLARE THE CLUSTER DOWN  ?
  PT4RESTARTIMER (V4CCB);                   _START RECOVERY TIMER      ?
10: 
  END; _WITH V6TCBP'.BSTCB DO?
END; _PROCEDURE PT4DNDEVICE?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 U P C L U S T E R                             * 
*                                                                     * 
*       BRING A CLUSTER UP                                            * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE BRINGS UP A CLUSTER THAT WAS PREVIOUSLY   * 
*              DOWN. FOR MODE 4A THIS IMPLIES THAT ALL THE DEVICES    * 
*              ARE TO BE BROUGHT UP.                                  * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*                                                                     * 
** OUTPUT -    CCB / TCB FIELDS UPDATED                               * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4UPDEVICE         BRING A DEVICE UP                  * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4UPCLUSTER; 
  
BEGIN 
V6CCBP'.BVCCB.BVSTATE     := V4CNORMAL;     _SET NORMAL RUNNING STATE  ?
V6CCBP'.BVCCB.BVBTCHFLGS  := 0;             _RESET MODE 4A BATCH FLAGS ?
V6CCBP'.BVCCB.BVBIREQD    := FALSE;         _RESET BATCH INTERRUPT REQ ?
V6CCBP'.BVCCB.BVTIMER     := CTIMER.CT100MS;_RESTART POLL/STATUS TIMER ?
_ 
* * * *   IF MODE 4A BRING UP ALL DEVICES, ELSE RESET RECOVERY TIMERS 
* * * *   V 6 T C B P   I S   D E S T R O Y E D 
? 
V6TCBP := V6CCBP'.BVCCB.BVTCBPTR;           _START WITH THE FIRST TCB  ?
REPEAT                                      _LOOP THRU ALL TCBS ON CCB ?
  IF V6CCBP'.BVCCB.BVM4A
  THEN                                      _MODE 4A                   ?
    PT4UPDEVICE                             _BRING THE DEVICE UP       ?
  ELSE                                      _MODE 4B/C                 ?
    V6TCBP'.BSTCB.BS4TIMER := CTIMER.CT100MS; 
  V6TCBP := V6TCBP'.BSTCB.BS4TCBPTR;
UNTIL V6TCBP = NIL; 
  
END; _PROCEDURE PT4UPCLUSTER? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 R E L A U T O R E C                           * 
*                                                                     * 
*       RELEASE AUTO RECOGNITION STRUCTURES                           * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE RELEASES THE AUTO RECOGNITION CCB AND TCB * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DNLINE           BRING A LINE DOWN                  * 
*              PT4AUTORECRESULT    REPORT AUTO RECOGNITION RESULTS    * 
*                                                                     * 
** OUTPUT -    A-R CCB AND TCB RELEASED, AND LCB FIELDS UPDATED       * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBREL1BF            RELEASE A BUFFER                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4RELAUTOREC;
  
VAR 
      V6LCCB : B0BUFPTR;                    _LOCAL CCB POINTER         ?
  
BEGIN 
V6LCCB              := V6LCBP'.BZ4CCBPTR;   _GET POINTER TO A-R CCB    ?
V6LCBP'.BZ4CCBPTR   := NIL;                 _DELINK IT FROM LCB CHAIN  ?
V6LCBP'.BZ4ARINPROG := FALSE;               _RESET AUTO REC ACTIVE FLAG?
PBREL1BF (V6LCCB'.BVCCB.BVTCBPTR, B0S64);   _RELEASE THE A-R TCB       ?
PBREL1BF (V6LCCB, B0S16);                   _RELEASE THE A-R CCB       ?
  
END; _PROCEDURE PT4RELAUTOREC?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 D N L I N E                                   * 
*                                                                     * 
*       BRING A LINE DOWN                                             * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE BRINGS DOWN A MODE 4 LINE, AND INFORMS    * 
*              THE SERVICE MODULE OF THE EVENT.                       * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              NEW STATE OF THE LINE                                  * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PT4MODE4TIP         MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    LCB FIELDS UPDATED, WORKLIST TO SERVICE MODULE         * 
*              COMMAND SENT TO MUX SUBSYSTEM                          * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TERMIO           TERMINATE INPUT / OUTPUT           * 
*              PT4TELLSVM          SEND A WORKLIST TO SERVICE MODULE  * 
*              PT4RELAUTOREC       RELEASE AUTO-REC STRUCTURES        * 
*              PBCOIN              COMMAND DRIVER                     * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THIS ROUTINE WILL NEVER RETURN TO ITS CALLER.          * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4DNLINE (V6NEWLSTATE : INTEGER);
  
BEGIN 
PT4TERMIO (V6NEWLSTATE);                    _TERMINATE I/O, SET STATE  ?
IF V6LCBP'.BZ4ARINPROG                      _AUTO RECOGNITION ACTIVE   ?
THEN
  PT4RELAUTOREC;                            _RELEASE AUTOREC STRUCTURES?
IF V6LCBP'.BZSTATE = V4LDISABLED            _SVM REQUESTED DISABLE LINE?
THEN
  BEGIN 
  V6CMDP.NKCMD := NKDISL;                   _SET UP COMMAND PACKET     ?
  PBCOIN (V6CMDP);                          _ISSUE DISABLE LINE COMMAND?
  PT4TELLSVM (D0LINE, D5DISA);              _TELL SVM LINE IS DISABLED ?
  END 
ELSE
  PT4TELLSVM (D0LINE, D5INOP);              _TELL SVM LINE INOPERATIVE ?
  
GOTO EXIT 999;                              _RETURN TO OPS MONITOR     ?
END; _PROCEDURE PT4DNLINE?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 A U T O R E C R E S U L T                     * 
*                                                                     * 
*       REPORT AUTO RECOGNITION RESULTS                               * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE REPORTS LINE OPERATIONAL TO THE           * 
*              SERVICE MODULE AFTER AUTO RECOGNITION IS COMPLETE.     * 
*              THE WORKLIST SENT CONTAINS A POINTER TO THE AUTO-      * 
*              REC PARAMETERS BUFFER WHICH CONTAINS INFORMATION       * 
*              ON THE RECOGNIZED CLUSTER.                             * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              V6CCBP              CURRENT CCB POINTER                * 
*              V6BUFP              POSSIBLE CONFIGURATION BUFFER      * 
*              CODE SET AND SUB-TIP TYPE RECOGNIZED                   * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    WORKLIST TO SVM WITH AUTO-REC PARAMETERS BUFFER        * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TERMIO           TERMINATE INPUT AND OUTPUT         * 
*              PT4TELLSVM          SEND A WORKLIST TO SERVICE MODULE  * 
*              PT4RELAUTOREC       RELEASE AUTO-REC STRUCTURES        * 
*              PBGET1BF            GET A BUFFER                       * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*                                                                     * 
** INTERNAL SUBROUTINE -                                              * 
*              PT4STTADT           STORE TERMINAL ADDR + DEVICE TYPE  * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THIS ROUTINE WILL NEVER RETURN TO ITS CALLER.          * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4AUTORECRESULT (V6ARCDSTIP : INTEGER);
  
CONST 
      V4ARDFTA   = $60;                     _DEFAULT TERMINAL ADDRESS  ?
      V4ARFCD    = 7;                       _FCD OF AUTO-REC PARAMS BFR?
      V4ARLS     = 4;                       _INDEX TO LINE SPEED       ?
      V4ARCDSTIP = 5;                       _INDEX TO CODE SET + SUBTIP?
      V4ARCANT   = 6;                       _INDEX TO CA + NBR OF TMLS ?
      V4ARTADT   = 7;                       _INDEX TO FIRST TA + DEV TP?
  
VAR 
      V6ARBUF    : B0BUFPTR;                _PTR TO AUTO-REC PARAMS BFR?
      V6ARSIDX   : INTEGER;                 _SOURCE BUFFER INDEX       ?
      V6ARCODE   : INTEGER;                 _CONFIGURATION CODE        ?
      V6ARIDX    : INTEGER;                 _AUTO-REC PARAMS BFR INDEX ?
      V6ARTA     : INTEGER;                 _TERMINAL ADDRESS          ?
      V6ARNT     : INTEGER;                 _NUMBER OF TERMINALS       ?
_ 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** PROCEDURE NAME -    P T 4 S T T A D T                              * 
*                                                                     * 
** OVERVIEW -  THIS LEVEL 3 ROUTINE STORES A TERMINAL ADDRESS         * 
*              AND DEVICE TYPE INTO THE AUTO-REC PARAMS BUFFER,       * 
*              UPDATES THE NUMBER OF TERMINALS, AND UPDATES           * 
*              THE INDEX INTO THE AUTO-REC PARAMS BUFFER.             * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4STTADT (V6ARDT : INTEGER); 
  
BEGIN 
V6ARBUF'.BIINT [V6ARIDX] := V6ARTA * $100 + _STORE TA AND DT INTO BUFR ?
                            V6ARDT; 
V6ARNT  := V6ARNT + 1;                      _BUMP NUMBER OF TERMINALS  ?
V6ARIDX := V6ARIDX + 1;                     _BUMP INDEX INTO BUFFER    ?
END; _PROCEDURE PT4STTADT?
_$J+? 
_ 
* * * *   S T A R T   O F   P T 4 A U T O R E C R E S U L T 
? 
BEGIN 
V6ARTA  := V4ARDFTA;                        _DEFAULT TERMINAL ADDRESS  ?
V6ARNT  := 0;                               _RESET NUMBER OF TERMINALS ?
V6ARIDX := V4ARTADT;                        _INITIALIZE BUFFER INDEX   ?
V6ARBUF := PBGET1BF (BEDBSIZE);             _GET BUFFER FOR A-R PARAMS ?
WITH V6ARBUF' DO                            _SET INDEX TO BUFFER       ?
  BEGIN 
  IF V6ARCDSTIP = V4A4CASCII
  THEN
_ 
* * * *   MODE 4C ASCII RECOGNIZED
? 
    BEGIN 
    V6ARSIDX := V4FIDX;                     _INITIALIZE SOURCE INDEX   ?
    REPEAT                                  _LOOP THRU ALL CONF CODES  ?
      V6ARTA   := V6ARTA + 1;               _INCREMENT TERMINAL ADDRESS?
      V6ARSIDX := V6ARSIDX + 1;             _BUMP SOURCE BUFFER INDEX  ?
      V6ARCODE := ORD (V6BUFP'.             _GET CONFIGURATION CODE    ?
                       BFDATAC [V6ARSIDX]); 
      IF V6ARCODE = V4FCONSOLE              _CONSOLE DEVICE            ?
      THEN
        PT4STTADT (N1CON)                   _STORE CONSOLE TA + DT     ?
      ELSE
        IF V6ARCODE = V4FIPRINT             _IMPACT PRINTER            ?
        THEN
          PT4STTADT (N1LP)                  _STORE LINE PRINTER TA + DT?
        ELSE
          IF V6ARCODE = V4FNIPRINT          _NON-IMPACT PRINTER        ?
          THEN
            PT4STTADT (N1LP);               _STORE LINE PRINTER TA + DT?
    UNTIL V6ARSIDX = V6BUFP'.BFLCD; 
    END 
  ELSE
_ 
* * * *   MODE 4A (BCD / ASCII) RECOGNIZED
? 
    BEGIN 
    PT4STTADT (N1CON);                      _STORE CONSOLE TA + DT     ?
    PT4STTADT (N1CR);                       _STORE CARD READER TA + DT ?
    PT4STTADT (N1LP);                       _STORE LINE PRINTER TA + DT?
    END; _IF V6ARCDSTIP = V4A4CASCII ELSE?
_ 
* * * *   COMPLETE AUTO-REC PARAMETERS BUFFER 
? 
  BIINT [1]          := (V6ARIDX * 2 - 3)   _STORE LCD AND FCD         ?
                        * $100 + V4ARFCD; 
  BIINT [V4ARLS]     := 0;                  _STORE LINE SPEED          ?
  BIINT [V4ARCDSTIP] := V6ARCDSTIP;         _STORE CODE SET AND SUB-TIP?
  BIINT [V4ARCANT]   := V6CCBP'.BVCCB.      _STORE CLUSTER ADDRESS AND ?
                        BVCANNED.BVCA       _NUMBER OF TERMINALS       ?
                        * $100 + V6ARNT;
  END; _WITH V6ARBUF' DO? 
_ 
* * * *   CLEAN UP, INFORM SERVICE MODULE, AND EXIT FROM TIP
? 
PT4RELAUTOREC;                              _RELEASE AUTO-REC TCB + CCB?
PBRELZRO (V6BUFP, BEDBSIZE);                _RELEASE POSS. INPUT BUFFER?
V6TCBP := V6ARBUF;                          _PUT BUFFER PTR IN WORKLIST?
PT4TELLSVM (D0LINE, D5OPER);                _TELL SVM LINE OPERATIONAL ?
PT4TERMIO (V4LWAITCB);                      _CLEAN UP LINE, SET STATE  ?
  
GOTO EXIT 999;                              _RETURN TO OPS MONITOR     ?
END; _PROCEDURE PT4AUTORECRESULT? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 B U I L D W R I T E                           * 
*                                                                     * 
*       BUILD A CANNED WRITE MESSAGE                                  * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE BUILDS A CANNED WRITE MESSAGE INTO A      * 
*              BUFFER AND PLACES IT IN THE TCB OUTPUT TRANSMISSION    * 
*              QUEUE.                                                 * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*              TYPE OF WRITE MESSAGE TO BE BUILT                      * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DPINPUT          CONSOLE POST INPUT PROCESSING      * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    TCB OUTPUT TRANSMISSION QUEUE UPDATED                  * 
*              TYPE OF WRITE SAVED IN TCB                             * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TEXTPROCESS      MODE 4 OUTPUT TEXT PROCESSOR       * 
*              PBFCOPY             COPY CHARACTERS INTO A BUFFER      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4BUILDWRITE (V6BTYPE : INTEGER);
  
CONST 
      V4BLTBL   = 51;                       _LENGTH OF CANNED MSG TABLE?
      V4BIND    = 16;                       _WORD INDEX TO SYNC + ESC  ?
      V4BBCDESC = $163E;                    _SYNC + BCD ESCAPE CHAR    ?
  
VAR 
      V6BSBFR   : B0BUFPTR;                 _LOCAL BUFFER POINTER      ?
      V6BCANTBL : ARRAY [1..V4BLTBL]        _CANNED MESSAGE TABLE      ?
                    OF INTEGER; 
      V6BLCDFCD : ARRAY [V4WCLRWRT..V4WENDCLR] _LCD, FCD FOR PBFCOPY   ?
                    OF INTEGER; 
  
VALUE 
      V6BCANTBL = ($0000,                   _LCD AND FCD FOR PBFCOPY   ?
                   $1616,$1616,$1601,$0000,$1216,$1616,$1616,$1616, 
                         $1616,$1616,$1616,$161B,$4203, 
                   $1616,$1616,$1601,$0000,$1216,$1616,$1616,$1616, 
                         $1616,$1616,$1616,$161B,$2103, 
                   $1616,$1616,$1601,$0000,$111B,$4203, 
                   $0000,$0000,$0816, 
                   $1616,$1616,$1601,$0000,$111B,$411B,$501B,$2203, 
                   $1616,$1616,$1601,$0000,$111B,$281B,$4203);
  
      V6BLCDFCD = ($1B02,                   _CLEAR WRITE               ?
                   $351C,                   _WRITE E3                  ?
                   $4136,                   _M4C PRINTER RECOVERY WRITE?
                   $4742,                   _M4A UNLOCK KEYBOARD WRITE ?
                   $5748,                   _M4C UNLOCK KEYBOARD WRITE ?
                   $6558,                   _M4C LOCK KEYBOARD WRITE   ?
                   $1B02);                  _CLEAR WRITE BATCH/XPT END ?
  
BEGIN 
V6BCANTBL [1] := V6BLCDFCD [V6BTYPE];       _SET LCD, FCD FOR PBFCOPY  ?
ADDR (V6BCANTBL, V6BSBFR);                  _SET CANNED TABLE AS SOURCE?
V6BUFP := NIL;                              _HAVE PBFCOPY GET THE BFR  ?
PBFCOPY (V6BSBFR, V6BUFP);                  _COPY CANNED MESSAGE       ?
IF V6BTYPE = V4WAUNLOCK                     _M4A UNLOCK KEYBOARD       ?
THEN                                        _NEEDS TEXT PROCESSING     ?
  BEGIN 
  V6BLKTYPE := V4B4AUNL;                    _SET M4A UNLOCK BLOCK TYPE ?
  PT4TEXTPROCESS (V6BUFP)                   _BUILD UNLOCK KEYBOARD WRT ?
  END 
ELSE
  BEGIN 
  IF V6TCBP'.BSTCB.BSCODE = N0BCD           _FOR A BCD TERMINAL        ?
  THEN                                      _MUST BE CLEAR WRITE OR E3 ?
    V6BUFP'.BIINT [V4BIND] := V4BBCDESC;    _STORE SYNC + BCD ESCAPE   ?
  END;
V6TCBP'.BSTCB.BS4WRTYPE := V6BTYPE;         _SAVE WRITE TYPE IN TCB    ?
V6TCBP'.BSTCB.BS4OUTBUF := V6BUFP;          _PUT WRITE MSG IN TCB QUEUE?
END; _PROCEDURE PT4BUILDWRITE?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 B I N T E R R U P T                           * 
*                                                                     * 
*       SEND BATCH INTERRUPTS                                         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE SENDS THE INPUT / OUTPUT STOPPED COMMANDS * 
*              (BATCH INTERRUPT) ON THE CARD READER AND LINE PRINTER  * 
*              CONNECTIONS.                                           * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    CCB FIELDS UPDATED, COMMANDS SENT UPLINE               * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PTCOMMAND           SEND AN UPLINE COMMAND             * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4BINTERRUPT;
  
VAR 
      V6LTCB : B0BUFPTR;                    _LOCAL TCB POINTER         ?
  
BEGIN 
IF V6CCBP'.BVCCB.BVBIREQD                   _BATCH INTERRUPTS REQUIRED ?
THEN
  BEGIN 
  V6CCBP'.BVCCB.BVBIREQD := FALSE;          _RESET BATCH INTERRUPTS REQ?
  V6CCBP'.BVCCB.BVCRWAIT := TRUE;           _SET WAIT ON CARD READER   ?
  V6LTCB := V6CCBP'.BVCCB.BVTCBPTR;         _START WITH 1ST TCB ON CCB ?
  REPEAT                                    _PROCESS ALL TCBS ON CCB   ?
    IF V6LTCB'.BSTCB.BSDEVTYPE = N1CR       _CARD READER DEVICE        ?
    THEN
      PTCOMMAND (V6LTCB, D8IS, D9BI)        _SEND INPUT STOPPED        ?
    ELSE
      IF V6LTCB'.BSTCB.BSDEVTYPE = N1LP     _LINE PRINTER DEVICE       ?
      THEN
        PTCOMMAND (V6LTCB, D8OS, D9BI);     _SEND OUTPUT STOPPED       ?
    V6LTCB := V6LTCB'.BSTCB.BS4TCBPTR;      _CHAIN TO NEXT TCB         ?
  UNTIL V6LTCB = NIL; 
  
  END; _IF V6CCBP'.BVCCB.BVBIREQD THEN? 
END; _PROCEDURE PT4BINTERRUPT?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 P R O C E S S C M D                           * 
*                                                                     * 
*       PROCESS CMD / ICMD BLOCKS                                     * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE PROCESSES ALL CMD AND ICMD BLOCKS         * 
*              RECEIVED, AND TAKES THE APPROPRIATE ACTION.            * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*              V6BUFP              POINTER TO CMD / ICMD BUFFER       * 
*              V6BLKTYPE           BLOCK TYPE                         * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4PREOUTPUT        PRE-OUTPUT PROCESSING              * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    RELEVANT FIELDS UPDATED IN TCB / CCB                   * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TPREL            RELEASE TEXT PROCESSING INFORMATION* 
*              PTDLCMD             PROCESS DOWNLINE COMMANDS          * 
*              PBPEOI              SEND ACCOUNTING DATA               * 
*              PBULTS              UPLINE TIP SERVICES                * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4PROCESSCMD;
  
VAR                                         _PARAMETER OF ICMD BLOCK OR?
      V6PFC : INTEGER;                      _PRIMARY FUNCTION CODE     ?
      V6SFC : INTEGER;                      _SECONDARY FUNCTION CODE   ?
  
BEGIN 
_ 
* * * *   PICK UP THE PFC AND SFC OF THE CMD BLOCK, OR PARAMETER
* * * *   OF THE ICMD BLOCK.
? 
WITH V6BUFP' DO                             _SET INDEX TO DOWNLINE BFR ?
  BEGIN 
  V6PFC := ORD (BFDATAC [P1]);              _GET PFC / PARAMETER       ?
  V6SFC := ORD (BFDATAC [P2]);              _GET POSSIBLE SFC          ?
  END; _WITH V6BUFP' DO?
  
WITH V6TCBP'.BSTCB.BS4CCBPTR'.BVCCB DO      _SET INDEX TO AFFECTED CCB ?
  BEGIN 
  IF V6BLKTYPE = HTICMD                     _ICMD BLOCK                ?
  THEN
    BEGIN 
    IF V6PFC = D7TERMINATE
    THEN
_ 
* * * *   T E R M I N A T E   B A T C H   O U T P U T   I C M D 
? 
      BEGIN 
      PBRELZRO (V6TCBP'.BSTCB.BS4OUTBUF,    _RELEASE POSS. OUTPUT BFRS ?
                BEDBSIZE);
      PT4TPREL;                             _RELEASE POSSIBLE TP BFRS  ?
      BVBIREQD := BVM4A;                    _MODE4A BATCH INTERRUPT REQ?
      END; _IF V6PFC = D7TERMINATE THEN?
    END _IF V6BLKTYPE = HTICMD THEN?
  ELSE
    BEGIN 
    CASE V6PFC OF 
_ 
* * * *   T E R M I N A T E   B A T C H   O U T P U T   M A R K E R 
? 
      D8TO: 
        BEGIN 
        V6TCBP'.BSTCB.BS4LCOUNT := 0;       _RESET LINE COUNT          ?
        PBPEOI (V6TCBP, D9IOT);             _SEND ACCOUNTING DATA      ?
        END; _D8TO? 
_ 
* * * *   T E R M I N A L / F I L E   C H A R A C T E R I S T I C S 
? 
      D8BD, 
      D8BF, 
      D8CTRL: 
        BEGIN 
        PTDLCMD (V6TCBP, V6BUFP);           _PROCESS DOWNLINE COMMAND  ?
        V6BUFP := NIL;                      _PTDLCMD RELEASES BUFFER   ?
        END; _D8BD, D8BF, D8CTRL? 
_ 
* * * *   S T A R T / R E S U M E   B A T C H   I N P U T 
? 
      D8SI: 
        BEGIN 
        BVCRWAIT := FALSE;                  _RESET WAIT ON CARD READER ?
        IF V6SFC " D9RSM                    _NOT RESUME                ?
        THEN
          BEGIN 
          BVCRON    := TRUE;                _SET CARD READER ON        ?
          BVJOBCARD := TRUE;                _AND EXPECTING JOB CARD    ?
          END; _IF V6SFC " D9RSM? 
        END; _D8SI? 
_ 
* * * *   A B O R T   B A T C H   I N P U T 
? 
      D8AI: 
        BEGIN                               _TURN CARD READER OFF      ?
        BVCRFLGS         := 0;              _NOT WAITING FOR RESUME    ?
        V6FLGWD.KTWORD   := 0;              _CLEAR BIP FLAG WORD       ?
        V6FLGWD.KTINTERM := TRUE;           _TELL BIP INPUT IS ABORTED ?
        PBULTS (V6TCBP, NIL, V6FLGWD);
        END; _D8AI? 
  
  
      END; _CASE V6PFC OF?
    END; _IF V6BLKTYPE = HTICMD ELSE? 
  END; _WITH V6TCBP'.BSTCB.BS4CCBPTR'.BVCCB DO? 
  
PBRELZRO (V6BUFP, BEDBSIZE);                _RELEASE POSSIBLE BUFFER   ?
END; _PROCEDURE PT4PROCESSCMD?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 P R E O U T P U T                             * 
*                                                                     * 
*       PRE-OUTPUT PROCESSING                                         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE CHECKS A TCB OUTPUT QUEUE FOR DATA OR A   * 
*              CMD OR ICMD BLOCK. COMMAND BLOCKS WILL BE IMMEDIATELY  * 
*              PROCESSED AND DATA BLOCKS WILL BE TEXT PROCESSED, IF   * 
*              NOT ALREADY DONE, AND PLACED IN THE TCB OUTPUT         * 
*              TRANSMISSION QUEUE.                                    * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*              TCB DEVICE TYPE                                        * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    TRUE RETURNED IF DATA READY TO TRANSMIT.               * 
*              TCB OUTPUT TRANSMISSION QUEUE UPDATED TO REFLECT       * 
*              ANY READY TO TRANSMIT DATA.                            * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4PROCESSCMD       PROCESS CMD / ICMD BLOCKS          * 
*              PT4TEXTPROCESS      MODE 4 OUTPUT TEXT PROCESSOR       * 
*              PB1BFAVAIL          CHECK SINGLE BUFFER AVAILABLE      * 
*              PBQUEMAINT          MAINTAIN QUEUES                    * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*              PBPEOI              SEND ACCOUNTING DATA               * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              ALL BLOCKS FOR A PRINTER DEVICE ARE INITIALLY          * 
*              PROCESSED BY PT4SCAN.                                  * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
FUNCTION PT4PREOUTPUT (V6DEVICE : INTEGER) : BOOLEAN; 
  
BEGIN 
IF V6TCBP'.BSTCB.BS4OUTBUF = NIL            _NO DATA ALREADY QUEUED    ?
THEN
  BEGIN 
  V6BUFP := V6TCBP'.BSTCB.BS4PSOURCE;       _PICK UP ANY PARTIAL SOURCE?
  IF V6BUFP " NIL                           _FOUND SOME                ?
  THEN
    IF PB1BFAVAIL (B0THMUX)                 _BUFFERS NOT CRITICALLY LOW?
    THEN
      GOTO 20                               _GO TEXT PROCESS THE DATA  ?
    ELSE
      GOTO 90;                              _WAIT UNTIL MORE BUFFERS   ?
_ 
* * * *   CHECK IF BLOCK CAN BE TAKEN FROM QUEUE
? 
10:                                         _ENTRY FOR RECHECKING QUEUE?
  V6BUFP := V6TCBP'.BSTCB.BSQPTR.BABUFPTR;  _PICK UP ANY QUEUED BLOCK  ?
  IF V6BUFP " NIL                           _DOWNLINE BLOCK EXISTS     ?
  THEN
    BEGIN 
    V6BLKTYPE := V6BUFP'.BIINT [BTWD];      _PICK UP THE BLOCK TYPE    ?
    V6BUFP    := NIL;                       _CLEAR IN CASE NO DEQUEUE  ?
    IF V6DEVICE = N1LP
    THEN                                    _LINE PRINTER DEVICE       ?
      PBQUEMAINT (V6TCBP, V6BUFP, K4GETNB)  _DEQUEUE BUT DONT BACK     ?
    ELSE
      IF (V6BLKTYPE \ HTCMD) !              _COMMAND OR ICMD BLOCK     ?
         PB1BFAVAIL (B0THMUX)               _OR ENOUGH BUFFERS EXIST   ?
      THEN                                  _DEQUEUE AND BACK THE BLOCK?
        PBQUEMAINT (V6TCBP, V6BUFP, K4GET); 
    IF V6BUFP " NIL                         _BLOCK TAKEN FROM QUEUE    ?
    THEN
_ 
* * * *   BLOCK TAKEN FROM QUEUE, PROCESS DATA AND COMMANDS 
? 
      BEGIN 
      IF V6BUFP'.BF4LPTP = FALSE            _NOT ALREADY TEXT-PROCESSED?
      THEN                                  _PRINTER DATA              ?
        BEGIN 
        IF V6BLKTYPE \ HTCMD                _COMMAND OR ICMD BLOCK     ?
        THEN
_ 
* * * *   COMMAND BLOCK OR ICMD BLOCK FOUND 
? 
          BEGIN 
          PT4PROCESSCMD;                    _PROCESS THE COMMAND BLOCK ?
          GOTO 10;                          _RECHECK THE OUTPUT QUEUE  ?
          END; _IF V6BLKTYPE \ HTCMD THEN?
_ 
* * * *   DOWNLINE DATA FOUND, TEXT PROCESS IF FOR A CONSOLE DEVICE 
? 
        IF V6DEVICE " N1CON                 _UN-TEXT PROCESSED DATA FOR?
        THEN                                _A CARD READER OR PRINTER  ?
          BEGIN 
          PBRELCHN (V6BUFP, BEDBSIZE);      _RELEASE THE DATA BUFFERS  ?
          IF V6DEVICE = N1LP                _BLOCK WAS FOR A PRINTER   ?
          THEN                              _MUST BE EOI MARKER BLOCK  ?
            PBPEOI (V6TCBP, D9EOI);         _SEND ACCOUNTING DATA      ?
          GOTO 10;                          _RECHECK THE OUTPUT QUEUE  ?
          END; _IF V6DEVICE " N1CON THEN? 
  
20:                                         _ENTRY FOR PARTIAL SOURCE  ?
        PT4TEXTPROCESS (V6BUFP);            _TEXT PROCESS THE DATA     ?
        IF V6BUFP = NIL                     _EMPTY XMIT BLOCK GENERATED?
        THEN
          GOTO 10;                          _RECHECK THE OUTPUT QUEUE  ?
        END; _IF V6BUFP'.BF4LPTP = FALSE THEN?
  
      V6TCBP'.BSTCB.BS4WRTYPE := V4WNORMAL; _NORMAL DATA WRITE TYPE    ?
      V6TCBP'.BSTCB.BS4OUTBUF := V6BUFP;    _PLACE OUTPUT IN TCB QUEUE ?
      END; _IF V6BUFP " NIL THEN? 
    END; _IF V6TCBP'.BSTCB.BSQPTR.BABUFPTR " NIL THEN?
  END; _IF V6TCBP'.BSTCB.BS4OUTBUF = NIL THEN?
90:                                         _ENTRY BFRS LOW ON PARTIAL ?
  
PT4PREOUTPUT := V6TCBP'.BSTCB.BS4OUTBUF "   _RETURN TRUE IF DATA READY ?
                NIL;                        _TO TRANSMIT               ?
END; _FUNCTION PT4PREOUTPUT?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 D P I N P U T                                 * 
*                                                                     * 
*       CONSOLE POST INPUT PROCESSING                                 * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ROUTES CONSOLE INPUT DATA UPLINE TO BIP,  * 
*              AND BUILDS THE RESPONSE MESSAGE, IF ANY REQUIRED.      * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    TCB FIELDS UPDATED, DATA SENT UPLINE TO BIP.           * 
*              ANY RESPONSE QUEUED IN TCB OUTPUT TRANSMISSION QUEUE.  * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4BUILDWRITE       BUILD A CANNED WRITE MESSAGE       * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*              PBULTS              UPLINE TIP SERVICES                * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4DPINPUT; 
  
CONST 
      V4DCC      = 4;                       _INDEX TO COLUMN COUNT     ?
  
VAR 
      V6DBUF     : B0BUFPTR;                _PTR TO CURRENT INPUT BLOCK?
      V6DLCD     : INTEGER;                 _LCD OF FULL ASCII INPUT   ?
      V6DI       : INTEGER;                 _LOOP VARIABLE             ?
      V6DCOLUMN  : INTEGER;                 _REMAINING COLUMN COUNT    ?
      V6DSAVEPG  : INTEGER;                 _SAVED PAGE WIDTH          ?
      V6DCHAR    : CHAR;                    _WORK CHARACTER            ?
      V6DFLASCII : BOOLEAN;                 _FULL ASCII FLAG           ?
      V6DXPT     : BOOLEAN;                 _TRANSPARENT DEVICE FLAG   ?
      V6DFIRST   : BOOLEAN;                 _FIRST INPUT BLOCK FLAG    ?
  
BEGIN 
WITH V6TCBP'.BSTCB DO                       _SET INDEX TO TCB          ?
  BEGIN 
  V6DFLASCII := BSFLASCII;                  _SAVE FULL ASCII FLAG      ?
  V6DXPT     := BSXPT;                      _SAVE TRANSPARENT DEVICE FG?
_ 
* * * *   PROCESS ALL INPUT BLOCKS RECEIVED 
? 
  V6DFIRST   := TRUE;                       _SET FIRST INPUT BLOCK FLAG?
  WHILE BS4INBUF " NIL DO                   _MORE INPUT TO PROCESS     ?
    BEGIN 
    V6DBUF := BS4INBUF;                     _GET POINTER TO INPUT BLOCK?
    WITH V6DBUF' DO                         _SET INDEX TO CURRENT INPUT?
      BEGIN 
      BS4INBUF := BCCHAINS [QCHN];          _DELINK FROM TCB INPUT QUE ?
      IF V6DXPT                             _TRANSPARENT DEVICE        ?
      THEN
_ 
* * * *   PROCESS INPUT FROM TRANSPARENT DEVICE (ONLY ONE BLOCK)
? 
        BEGIN 
        IF BFXPT                            _TRANSPARENT DATA RECEIVED ?
        THEN
          BEGIN 
          BSXPT := BSMXPT;                  _STILL XPT IF MULTI MSG XPT?
          IF BSTCLASS = N071430             _714-30 TERMINAL           ?
          THEN
            PT4BUILDWRITE (V4WLOCK);        _BUILD LOCK KEYBOARD WRITE ?
          END 
        ELSE
          BEGIN                             _NO TRANSPARENT DATA RECVD ?
          BSXPT := FALSE;                   _NO LONGER IN XPT MODE     ?
          PBRELCHN (V6DBUF, BEDBSIZE);      _RELEASE INPUT BUFFERS     ?
          PT4BUILDWRITE (V4WENDCLR);        _BUILD CLEAR SCREEN WRITE  ?
          END;
        END _IF V6DXPT THEN?
      ELSE
_ 
* * * *   PROCESS INPUT FROM NON-TRANSPARENT DEVICE 
? 
        BEGIN 
        V6DCOLUMN := BIINT [V4DCC];         _SAVE POSSIBLE COLUMN COUNT?
        IF V6DFLASCII                       _FULL ASCII MODE           ?
        THEN
_ 
* * * *   FULL ASCII MODE, CHECK FOR IVT COMMAND AND ADJUST BUFFER
? 
          BEGIN 
          V6DLCD  := BFLCD - 1;             _ALLOW FOR NEW LINE OR ESC ?
          V6DCHAR := BFDATAC [DATA + 1];    _PICK UP FIRST CHARACTER   ?
          IF V6DFIRST                       _FIRST INPUT BLOCK         ?
          THEN
            BEGIN 
            V6DCHAR := BFDATAC [DATA + 2];  _ALLOW FOR SOH CHARACTER   ?
            IF V6DCHAR = CHR (BSSECHAR)     _SECURITY CHARACTER FOUND  ?
            THEN
              IF BS4INBUF = NIL             _IN ONLY BLOCK OF INPUT    ?
              THEN
                IF V6DLCD = DATA + 4        _AND ONLY CHARACTER INPUT  ?
                THEN                        _MOVE DOWN TO FIRST CHAR   ?
                  V6DCHAR := CHR (BSCNTRLCHAR); 
            IF V6DCHAR = CHR (BSCNTRLCHAR)  _CONTROL CHARACTER FOUND   ?
            THEN
              BEGIN                         _MOVE THE BUFFER DOWN 1 CHR?
              V6DI := DATA;                 _INITIALIZE CHAR. INDEX    ?
              REPEAT
                V6DI := V6DI + 1;           _BUMP CHARACTER INDEX      ?
                BFDATAC [V6DI] :=           _MOVE CHARACTER BACK BY ONE?
                  BFDATAC [V6DI + 1]; 
              UNTIL V6DI = V6DLCD;          _UNTIL ALL CHARACTERS MOVED?
              V6DLCD := V6DLCD - 1;         _ALLOW FOR REMOVED SOH     ?
              END; _IF CONTROL CHARACTER THEN?
            END; _IF V6DFIRST THEN? 
          IF V6DCHAR = CHR (BSCNTRLCHAR)    _CONTROL CHARACTER FOUND   ?
          THEN
            BEGIN 
            IF BS4INBUF = NIL               _IN THE LAST INPUT BLOCK   ?
            THEN
              V6DLCD := V6DLCD - 2;         _ALLOW FOR E1 AND ETX CHAR ?
            BFLCD := V6DLCD;                _INSERT NEW LCD OF BUFFER  ?
            END; _IF CONTROL CHARACTER THEN?
          END _IF V6DFASCII THEN? 
        ELSE
_ 
* * * *   NOT FULL ASCII MODE, CHECK FOR POSSIBLE EMPTY BLOCK 
? 
          BEGIN 
          IF V6DFIRST = FALSE               _NOT FIRST BLOCK RECEIVED  ?
          THEN
            IF BS4INBUF = NIL               _BUT IT IS THE LAST BLOCK  ?
            THEN
              IF BFLCD = DATA               _AND IT IS EMPTY           ?
              THEN
                PBRELCHN (V6DBUF, BEDBSIZE);_RELEASE THE EMPTY BLOCK   ?
          END; _IF V6DFLASCII ELSE? 
        END; _IF V6DXPT ELSE? 
_ 
* * * *   PASS VALID DATA UPLINE TO BIP 
? 
      IF V6DBUF " NIL                       _BLOCK NOT RELEASED        ?
      THEN
        BEGIN 
        BFFCD             := DATA;          _SET FCD OF INPUT BLOCK    ?
        V6FLGWD.KTWORD    := 0;             _CLEAR BIP FLAG WORD       ?
        V6FLGWD.KTCKSPEC  := NOT V6DXPT;    _CHECK SPECIAL CHRS NON-XPT?
        V6FLGWD.KTSEND    := TRUE;          _SEND DATA UPLINE          ?
        V6FLGWD.KTCKPGTRN := BS4PGTURN;     _CHECK PAGE TURN IF REQUIRD?
        BS4PGTURN         := FALSE;         _CLEAR PAGE TURN REQUIRED  ?
  
        PBULTS (V6TCBP, V6DBUF, V6FLGWD);   _PASS DATA UPLINE TO BIP   ?
  
        IF V6FLGWD.KTUBS " 0                _USER BREAK 1 OR 2 FOUND   ?
        THEN
          PBRELZRO (BS4PSOURCE, BEDBSIZE);  _RELEASE ANY PARTIAL SOURCE?
  
        END; _IF V6DBUF " NIL THEN? 
      END; _WITH V6DBUF' DO?
    V6DFIRST := FALSE;                      _RESET FIRST BLOCK FLAG    ?
    END; _WHILE BS4INBUF " NIL DO?
_ 
* * * *   FOR NON-TRANSPARENT DEVICE, UNLOCK THE KEYBOARD 
? 
  IF V6DXPT = FALSE                         _NON-TRANSPARENT DEVICE    ?
  THEN
    BEGIN 
    IF V6CCBP'.BVCCB.BVM4A                  _MODE 4A DEVICE            ?
    THEN
      BEGIN 
      V6DSAVEPG := BSPGWIDTH;               _SAVE THE PAGE WIDTH       ?
      IF V6DCOLUMN " 0                      _NOT AT END OF LINE        ?
      THEN
        BSPGWIDTH := V6DCOLUMN - 1;         _SET UP BLANKFILL COUNT    ?
      PT4BUILDWRITE (V4WAUNLOCK);           _BUILD UNLOCK KEYBOARD WRT ?
      BSPGWIDTH := V6DSAVEPG;               _RESTORE TRUE PAGE WIDTH   ?
      END 
    ELSE
      PT4BUILDWRITE (V4WCUNLOCK);           _BUILD UNLOCK KEYBOARD M4BC?
    END; _IF V6DXPT = FALSE THEN? 
_ 
* * * *   CLEAR LINE COUNT, AND UPDATE INPUT REQUIRED FLAGS 
? 
  BS4LCOUNT  := 0;                          _RESET LINES REMAINING     ?
  BS4XPTURN  := FALSE;                      _RESET XPT INPUT REQUIRED  ?
  
  END; _WITH V6TCBP'.BSTCB DO?
END; _PROCEDURE PT4DPINPUT? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 C P I N P U T                                 * 
*                                                                     * 
*       CARD READER POST INPUT PROCESSING                             * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ROUTES CARD READER DATA UPLINE TO BIP     * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    CCB / TCB FIELDS UPDATED, DATA SENT UPLINE TO BIP.     * 
*              FLAG V6EOIFND INDICATES IF LAST VALID DATA CONTAINED   * 
*              END OF INFORMATION.                                    * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBREL1BF            RELEASE A BUFFER                   * 
*              PBULTS              UPLINE TIP SERVICES                * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4CPINPUT; 
  
VAR 
      V6CBUF : B0BUFPTR;                    _PTR TO CURRENT INPUT BLOCK?
  
BEGIN 
V6FLGWD.KTWORD := 0;                        _RESET BIP FLAG WORD       ?
V6EOIFND       := FALSE;                    _RESET EOI FOUND FLAG      ?
WHILE V6TCBP'.BSTCB.BS4INBUF " NIL DO       _MORE INPUT TO PROCESS     ?
  BEGIN 
  V6CBUF := V6TCBP'.BSTCB.BS4INBUF;         _GET POINTER TO INPUT BLOCK?
  V6TCBP'.BSTCB.BS4INBUF :=                 _DELINK FROM TCB INPUT QUE ?
    V6CBUF'.BCCHAINS [QCHN];
_ 
* * * *   DO NOT PROCESS AN EMPTY BLOCK, UNLESS IT INDICATES EOI
? 
  IF V6CBUF'.BFLCD = DATA                   _NO DATA IN FIRST BUFFER   ?
  THEN
    IF V6CBUF'.BFEOI = FALSE                _AND NOT AN EOI BLOCK      ?
    THEN
      IF V6CBUF'.BCCHAINS [DBUFLENGTH] = NIL_AND ONLY BUFFER OF BLOCK  ?
      THEN
        BEGIN 
        PBREL1BF (V6CBUF, BEDBSIZE);        _RELEASE THE EMPTY BUFFER  ?
        GOTO 10;                            _NOTHING TO PASS ON TO BIP ?
        END;
_ 
* * * *   VALID INPUT FOUND, SEND IT TO BIP 
? 
  V6CBUF'.BFFCD := DATA;                    _SET FCD OF INPUT BLOCK    ?
  V6EOIFND := V6CBUF'.BFEOI;                _UPDATE EOI FOUND FLAG     ?
  V6CCBP'.BVCCB.BVJOBCARD := V6EOIFND;      _UPDATE JOB CARD EXPECTED  ?
  PBULTS (V6TCBP, V6CBUF, V6FLGWD);         _PASS DATA UPLINE TO BIP   ?
10: 
  END; _WHILE V6TCBP'.BSTCB.BS4INBUF " NIL DO?
  
END; _PROCEDURE PT4CPINPUT? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 V E R I F Y                                   * 
*                                                                     * 
*       VERIFY TERMINAL RESPONSE                                      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE VERIFIES A TERMINAL RESPONSE TO AN        * 
*              OUTPUT TRANSMISSION, AND MAINTAINS THE RELEVANT        * 
*              ERROR COUNTER. IF THE ERROR COUNTER OVERFLOWS, THE     * 
*              CLUSTER OR DEVICE WILL BE DECLARED DOWN.               * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              IF APPLICABLE, CURRENT TCB POINTER * 
*              SET OF ALLOWABLE RESPONSES                             * 
*              WHETHER TO COUNT ERRORS FOR CLUSTER OR DEVICE          * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*                                                                     * 
** OUTPUT -    TRUE RETURNED IF AN ALLOWABLE RESPONSE RECEIVED, OR    * 
*              A RETRY OF THE I/O IS PERMISSIBLE.                     * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*              PNSGATH             GATHER STATISTICS                  * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
FUNCTION PT4VERIFY (V6VALLOW : V5RSPTYP; V6VINCCB : BOOLEAN) : BOOLEAN; 
  
VAR 
      V6VECOUNT : INTEGER;                  _LOCAL ERROR COUNTER       ?
      V6VCODE   : INTEGER;                  _REASON CODE FOR DOWNING   ?
      V6VDOWN   : BOOLEAN;                  _SET IF CCB OR TCB IS DOWN ?
      V6VREASON : ARRAY [V4WKE1..V4WKTIMO]  _REASONS TO DOWN CCB / TCB ?
                    OF INTEGER; 
  
VALUE 
      V6VREASON = (V4EBADRSP,V4EBADRSP,V4EBADRSP,V4EBADRSP, 
                   V4EBADRSP,V4EBADRSP,V4EBADRSP,V4EERRRSP, 
                   V4EBADRSP,V4EBADRSP,V4EBADRSP,V4EBADRSP, 
                   V4ENORSP); 
  
BEGIN 
PT4VERIFY := TRUE;                          _RETURN TRUE BY DEFAULT    ?
V6VECOUNT := 0;                             _AND RESET ANY ERROR COUNT ?
IF V6RESPONSE.V5SETWD & V6VALLOW = [ ]      _RESPONSE NOT ALLOWABLE    ?
THEN
_ 
* * * *   RESPONSE RECEIVED IS NOT ALLOWABLE
? 
  BEGIN 
  IF V6VINCCB 
  THEN
    BEGIN 
    V6VECOUNT := V6CCBP'.BVCCB.BVERRCOUNT;  _ERROR COUNTER FROM CCB    ?
    V6VDOWN   := V6CCBP'.BVCCB.BVSTATE =    _DOWN STATUS FROM CCB      ?
                 V4CRECOVER;
    END 
  ELSE
    BEGIN 
    V6VECOUNT := V6TCBP'.BSTCB.BS4ERRCOUNT; _ERROR COUNTER FROM TCB    ?
    V6VDOWN   := V6TCBP'.BSTCB.BS4STATE =   _DOWN STATUS FROM TCB      ?
                 V4DRECOVER;
    END;
_ 
* * * *   MAINTAIN ERROR COUNTER IF CCB / TCB NOT ALREADY DOWN
? 
  IF V6VDOWN                                _CLUSTER OR DEVICE IS DOWN ?
  THEN
    PT4VERIFY := FALSE                      _ALWAYS RETURN FALSE       ?
  ELSE
    BEGIN 
    IF V6LCBP'.BZ4ARINPROG = FALSE          _NOT DOING AUTO-RECOGNITION?
    THEN
      PNSGATH (V6LCBP, NIL, J0BADBLK);      _INCREMENT BAD BLOCKS      ?
    V6VECOUNT := V6VECOUNT + 1;             _INCREMENT ERROR COUNTER   ?
    IF V6VECOUNT \ V4MAXRETRY               _ERROR COUNTER OVERFLOWED  ?
    THEN
_ 
* * * *   TOO MANY CONSECUTIVE ERRORS, BRING DOWN THE CLUSTER OR DEVICE 
? 
      BEGIN 
      PT4VERIFY := FALSE;                   _RETURN FALSE RESULT       ?
      V6VCODE   := V6VREASON [V6WKCODE];    _GET REASON CODE           ?
      IF V6VINCCB 
      THEN                                  _WHOLE CLUSTER FAILURE     ?
        BEGIN                               _BRING DOWN ALL THE DEVICES?
        V6TCBP := V6CCBP'.BVCCB.BVTCBPTR;   _GET POINTER TO FIRST TCB  ?
        REPEAT                              _LOOP THRU ALL TCBS ON CCB ?
          PT4DNDEVICE (V6VCODE);            _BRING DOWN THE DEVICE     ?
          V6TCBP := V6TCBP'.BSTCB.BS4TCBPTR;
        UNTIL V6TCBP = NIL;                 _UNTIL ALL TCBS DOWNED     ?
        END _IF V6VINCCB THEN?
      ELSE
        PT4DNDEVICE (V6VCODE);              _NO  JUST DOWN THE DEVICE  ?
      END; _IF V6VECOUNT \ V4MAXRETRY THEN? 
    END; _IF V6VDOWN ELSE?
  END; _IF NOT AN ALLOWED RESPONSE THEN?
_ 
* * * *   STORE UPDATED (OR RESET) ERROR COUNTER IN CCB / TCB 
? 
IF V6VINCCB 
THEN
  V6CCBP'.BVCCB.BVERRCOUNT := V6VECOUNT     _STORE NEW COUNTER IN CCB  ?
ELSE
  V6TCBP'.BSTCB.BS4ERRCOUNT := V6VECOUNT;   _STORE NEW COUNTER IN TCB  ?
END; _FUNCTION PT4VERIFY? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 P O L L                                       * 
*                                                                     * 
*       PERFORM POLL SEQUENCE                                         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ISSUES A POLL OR CONFIGURATION REQUEST    * 
*              AND RETURNS TO ITS CALLER WHEN A CORRECT RESPONSE      * 
*              THAT THE CALLER WISHES TO PROCESS IS RECEIVED. IF THE  * 
*              RESPONSE IS INCORRECT OR IT IS NOT A RETURNABLE ONE,   * 
*              THEN THE SEQUENCE MAY BE RETRIED LATER BY RETURNING    * 
*              TO THE CLUSTER DRIVER, OR MAY BE RETRIED ON THE        * 
*              CALLERS BEHALF BY THIS ROUTINE.                        * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*              TYPE OF POLL / CONFIGURATION REQUEST REQUESTED         * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    POLL / CONFIGURATION MESSAGE TO DEVICE (OR CLUSTER)    * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4IO               PERFORM INPUT / OUTPUT SEQUENCE    * 
*              PT4RETURN           RETURN TO A GIVEN ADDRESS          * 
*              PT4CONTROL          GIVE CONTROL TO NEXT CCB ON LINE   * 
*              PT4INRELEASE        RELEASE ALL INPUT BUFFERS          * 
*              PT4VERIFY           VERIFY TERMINAL RESPONSE           * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THE CALLERS RETURN ADDRESS IS SAVED IN THE CCB, AND    * 
*              CONTROL WILL RETURN TO THAT ADDRESS WHEN AN ALLOWABLE  * 
*              AND RETURNABLE RESPONSE IS RECEIVED.                   * 
*                                                                     * 
** RESPONSE BIT DEFINITIONS-                                          * 
*                                                                     * 
*15  14  13  12    11  10  09  08    07  06  05  04    03  02  01  00 * 
*                                                                     * 
*--  --  --  TIM   BAD SFT BCD ASC   ERR REJ ACK BUF   SLC E3  E2  E1 * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4POLL (V6PTYPE : INTEGER);
  
TYPE
      V5PSETS = ARRAY [V4PCONSOLE..V4PCNFG] OF V5RSPTYP;
  
VAR 
      V6PALLOW  : V5PSETS;                  _ALLOWABLE REPONSE SETS    ?
      V6PRETURN : V5PSETS;                  _RETURNABLE RESPONSE SETS  ?
      V6PAGAIN  : V5PSETS;                  _RETRYABLE RESPONSE SETS   ?
      V6PINCCB  : BOOLEAN;                  _COUNT ERRORS IN TCB OR CCB?
  
VALUE 
      V6PALLOW  = ($0057,$005F,$0057,$00FF,$0350,$0350,$0110);
      V6PRETURN = ($0001,$000F,$0007,$00EF,$0340,$0340,$0100);
      V6PAGAIN  = ($0000,$FFF0,$FFF8,$FF10,$0000,$0000,$FEEF);
  
BEGIN 
WITH V6CCBP'.BVCCB DO                       _SET INDEX 1 TO CCB        ?
  BEGIN 
  RETADR (BVRETCALLIO);                     _SAVE RETURN ADDRESS IN CCB?
_ 
* * * *   PREPARE AND ISSUE THE POLL / CONFIGURATION REQUEST
? 
  BVIOTYPE := V6PTYPE;                      _SAVE I/O TYPE IN CCB      ?
  IF V6PTYPE = V4PCNFG                      _CONFIGURATION REQUEST     ?
  THEN
    BEGIN 
    BVCANNED.BVTA  := V4ALLTA;              _SET TA TO ALL DEVICES     ?
    BVCANNED.BVMTI := V4MCONFIG;            _SET MTI FOR CONFIGURATION ?
    END 
  ELSE
    BEGIN 
    BVCANNED.BVTA  := V6TCBP'.BSTCB.BSTA;   _SET TERMINAL ADDRESS      ?
    BVCANNED.BVMTI := V4MPOLL;              _SET MTI FOR POLL          ?
    END;
  BVCANNED.BVTOG := BVTOGLASTWRT;           _UPDATE TOGGLE BIT         ?
10:                                         _ENTRY FOR RETRY           ?
  PT4IO (V6CCBP);                           _ISSUE THE POLL / CONF. REQ?
_ 
* * * *   VERIFY AND PROCESS THE RESPONSE, IF ANY 
? 
  V6PINCCB := BVM4A;                        _M4A ERRORS COUNTED IN CCB ?
  V6PTYPE  := BVIOTYPE;                     _PICK UP THE SAVED I/O TYPE?
  IF V6PTYPE = V4PCNFG                      _CONFIGURATION REQUEST     ?
  THEN                                      _ERRORS COUNTED IN CCB     ?
    V6PINCCB := TRUE; 
  IF PT4VERIFY (V6PALLOW [V6PTYPE],         _NO ERROR COUNTER OVERFLOW ?
                V6PINCCB) 
  THEN
    BEGIN 
    IF V6RESPONSE.V5SETWD &                 _RETURNABLE RESPONSE       ?
       V6PRETURN [V6PTYPE] " [ ]
    THEN
      PT4RETURN (BVRETCALLIO);              _RETURN TO CALLER          ?
  
    PT4INRELEASE;                           _RELEASE ALL POSSIBLE INPUT?
    IF V6RESPONSE.V5SETWD &                 _RESPONSE NEEDS A RETRY    ?
       V6PAGAIN [V6PTYPE] " [ ] 
    THEN
      BEGIN 
      PT4CONTROL;                           _SERVICE OTHER CCBS ON LINE?
      GOTO 10;                              _RETRY THE POLL / CONF REQ ?
      END;
    END; _IF PT4VERIFY .... THEN? 
_ 
* * * *   ERROR OVERFLOW IN TCB OR CCB, OR NON-RETURNABLE RESPONSE
? 
  IF BVSTATE = V4CRECOVER                   _IF THE CLUSTER IS DOWN    ?
  THEN
    PT4RETURN (V6RADLINE);                  _RETURN TO THE LINE DRIVER ?
                                            _ELSE                      ?
  PT4RETURN (V6RADCLUSTER);                 _RETURN TO CLUSTER DRIVER  ?
 END; _WITH V6CCBP'.BVCCB DO? 
END; _PROCEDURE PT4POLL?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 S T A T U S                                   * 
*                                                                     * 
*       PERFORM STATUS REQUEST SEQUENCE                               * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ISSUES A STATUS REQUEST TO A MODE 4B      * 
*              OR MODE 4C CLUSTER AND PROCESSES THE RESPONSE.         * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*              TYPE OF STATUS REQUEST                                 * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*                                                                     * 
** OUTPUT -    STATUS REQUEST ISSUED                                  * 
*              STATUS INFORMATION SAVED IN EACH TCB                   * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4IO               PERFORM INPUT / OUTPUT SEQUENCE    * 
*              PT4RETURN           RETURN TO A GIVEN ADDRESS          * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*              PT4VERIFY           VERIFY TERMINAL RESPONSE           * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THE CALLERS RETURN ADDRESS IS SAVED IN THE CCB, AND    * 
*              CONTROL WILL RETURN TO THAT ADDRESS AFTER A CORRECT    * 
*              RESPONSE IS RECEIVED AND PROCESSED.                    * 
*                                                                     * 
** RESPONSE BIT DEFINITIONS-                                          * 
*                                                                     * 
*15  14  13  12    11  10  09  08    07  06  05  04    03  02  01  00 * 
*                                                                     * 
*--  --  --  TIM   BAD SFT BCD ASC   ERR REJ ACK BUF   SLC E3  E2  E1 * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4STATUS (V6STYPE : INTEGER);
  
CONST 
      V4SIDX = $C;                          _BFR INDEX TO STATUS BYTES ?
  
VAR 
      V6SBUF : B0BUFPTR;                    _PTR TO STATUS REQ RESPONSE?
      V6SMTI : ARRAY [BOOLEAN] OF INTEGER;  _STATUS MTI MODE4B / MODE4C?
      V6SRSP : ARRAY [V4STATUS..V4STOGGLE]  _ACCEPTABLE RESPONSES      ?
                 OF V5RSPTYP; 
  
VALUE 
      V6SMTI = (V4MBSTSREQ,V4MCSTSREQ); 
      V6SRSP = ($0110,$01F0); 
  
BEGIN 
WITH V6CCBP'.BVCCB DO                       _SET INDEX 1 TO CCB        ?
  BEGIN 
  RETADR (BVRETCALLIO);                     _SAVE RETURN ADDRESS IN CCB?
_ 
* * * *   PREPARE AND ISSUE THE STATUS REQUEST
? 
  BVIOTYPE       := V6STYPE;                _SAVE I/O TYPE             ?
  BVCANNED.BVTA  := V4ALLTA;                _SET TA FOR ALL DEVICES    ?
  BVCANNED.BVMTI := V6SMTI [BVM4C];         _SET MTI FOR M4B OR M4C    ?
  BVCANNED.BVTOG := BVTOGLASTWRT;           _UPDATE TOGGLE BIT         ?
  
10:                                         _ENTRY FOR RETRY OF STATUS ?
  PT4IO (V6CCBP);                           _ISSUE THE STATUS REQUEST  ?
  
  V6STYPE := BVIOTYPE;                      _PICK UP SAVED I/O TYPE    ?
  IF PT4VERIFY (V6SRSP[V6STYPE], V4CCB)     _NO ERROR COUNTER OVERFLOW ?
  THEN                                      _IN CLUSTER CONTROL BLOCK  ?
    IF V6WKCODE = V4WKASC                   _STATUS RESPONSE RECEIVED  ?
    THEN
_ 
* * * *   GOOD RESPONSE, PROCESS STATUS INFORMATION RECEIVED
? 
      BEGIN 
      BVTYPEKNOWN := TRUE;                  _DECLARE CLUSTER TYPE KNOWN?
      V6SBUF      := V6BUFP;                _GET POINTER TO RESPONSE   ?
      V6BUFP      := NIL;                   _CLEAR INPUT BUFFER POINTER?
      V6TCBP      := BVTCBPTR;              _START WITH FIRST TCB      ?
      REPEAT                                _PROCESS FOR ALL TCBS      ?
        WITH V6TCBP'.BSTCB DO 
          BEGIN 
          V6TA.V5TINT := BSTA;              _PICK UP TERMINAL ADDRESS  ?
          BS4STSFLGS  :=                    _PUT RELEVANT FLAGS IN TCB ?
            ORD (V6SBUF'.BFDATAC
                 [V4SIDX + V6TA.V5TIDX]); 
          IF BS4EXISTENT                    _EXISTENT DEVICE           ?
          THEN
            BEGIN 
            IF BS4STATE = V4DDEAD           _DEVICE CURRENTLY DEAD     ?
            THEN
              BEGIN 
              BS4STATE := V4DRECOVER;       _ATTEMPT CLR WRITE RECOVERY?
              BS4TIMER := CTIMER.CT100MS;   _ON NEXT DEVICE CYCLE      ?
              END;
            END _IF BS4EXISTENT THEN? 
          ELSE
            BEGIN                           _NON EXISTENT DEVICE       ?
            IF BS4STATE " V4DDEAD           _HAVE NOT DIAGNOSED DEATH  ?
            THEN
              BEGIN 
              PT4DNDEVICE (V4ENORSP);       _BRING THE DEVICE DOWN     ?
              BS4STATE := V4DDEAD;          _PRONOUNCE DEATH           ?
              END;                          _THIS IS AN EX-DEVICE      ?
            END; _IF BS4EXISTENT ELSE?
          V6TCBP := BS4TCBPTR;              _ADVANCE TO NEXT TCB ON CCB?
          END; _WITH V6TCBP'.BSTCB DO?
      UNTIL V6TCBP = NIL; 
      PBRELCHN (V6SBUF, BEDBSIZE);          _RELEASE THE STATUS BUFFER ?
20:                                         _ENTRY FOR OTHER RETURNS   ?
      V6TCBP := BVCURTCB;                   _SET CURRENT TCB POINTER   ?
      WITH V6TCBP'.BSTCB DO                 _SET INDEX 2 TO TCB        ?
        BEGIN 
        IF BS4STATE = V4DDEAD               _IF THE DEVICE IS DEAD     ?
        THEN                                _AND                       ?
          BEGIN 
          IF V6STYPE = V4STOGGLE            _REQUEST IS FOR TOGGLE     ?
          THEN
            PT4RETURN (V6RADCLUSTER);       _RETURN TO CLUSTER DRIVER  ?
          END;  _IF BS4STATE = V4DDEAD? 
        PT4RETURN (BVRETCALLIO);            _RETURN TO CALLER          ?
        END;  _WITH B6TCBP'.BSTCB ? 
      END; _IF V6WKCODE = V4WKASC THEN? 
_ 
* * * *   ERROR OVERFLOW IN CCB, OR INCORRECT RESPONSE
? 
  PBRELZRO (V6BUFP, BEDBSIZE);              _RELEASE POSSIBLE INPUT    ?
  IF V6WKCODE " V4WKBUFT                    _NOT BUFFER THRESHOLD      ?
  THEN
    IF BVTYPEKNOWN = FALSE                  _CLUSTER TYPE UNKNOWN      ?
    THEN
      BVM4C := NOT BVM4C;                   _NEXT TIME TRY OTHER STATUS?
  
  IF V6STYPE = V4STOGGLE                    _RECOVERING TOGGLE BIT     ?
  THEN
    IF BVSTATE = V4CNORMAL                  _AND CLUSTER STILL UP      ?
    THEN
      BEGIN 
      IF [V4RERR, V4RREJ, V4RACK] &         _OTHER ACCEPTABLE RESPONSES?
         V6RESPONSE.V5SETWD " [ ]           _TO CHECK TOGGLE BIT       ?
      THEN
        GOTO 20;                            _SET TCB POINTER AND RETURN?
  
      PT4CONTROL;                           _SERVICE OTHER CCBS ON LINE?
      GOTO 10;                              _RETRY STATUS REQUEST      ?
      END; _IF BVSTATE = V4CNORMAL THEN?
  
  PT4RETURN (V6RADLINE);                    _RETURN TO THE LINE DRIVER ?
  
  END; _WITH V6CCBP'.BVCCB DO?
END; _PROCEDURE PT4STATUS?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 W R I T E                                     * 
*                                                                     * 
*       PERFORM WRITE SEQUENCE                                        * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE ISSUES A WRITE TO A DEVICE AND RETURNS    * 
*              TO ITS CALLER WHEN THE ACKNOWLEDGEMENT TO THE WRITE    * 
*              IS RECEIVED. IF THE WRITE RESPONSE IS REJECT OR        * 
*              ERROR THEN THE WRITE IS RETRIED LATER BY RETURNING     * 
*              TO THE CLUSTER DRIVER. OTHER RESPONSES RESULT IN       * 
*              THE POLL / STATUS REQUEST SEQUENCE TO DETERMINE IF     * 
*              THE WRITE WAS CORRECTLY RECEIVED. THIS IS ATTEMPTED    * 
*              A NUMBER OF TIMES UNTIL THE STATUS OF THE WRITE IS     * 
*              FOUND OR THE CLUSTER IS DECLARED DOWN.                 * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*              TYPE OF WRITE REQUESTED                                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*                                                                     * 
** OUTPUT -    WRITE MESSAGE TO DEVICE                                * 
*              INTERNAL WRITE MESSAGES BUILT AND RELEASED             * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4IO               PERFORM INPUT / OUTPUT SEQUENCE    * 
*              PT4RETURN           RETURN TO A GIVEN ADDRESS          * 
*              PT4CONTROL          GIVE CONTROL TO NEXT CCB ON LINE   * 
*              PT4INRELEASE        RELEASE ALL INPUT BUFFERS          * 
*              PT4BUILDWRITE       BUILD A CANNED WRITE MESSAGE       * 
*              PT4VERIFY           VERIFY TERMINAL RESPONSE           * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THE CALLERS RETURN ADDRESS IS SAVED IN THE CCB, AND    * 
*              CONTROL WILL RETURN TO THAT ADDRESS WHEN THE           * 
*              ACKNOWLEDGEMENT TO THE WRITE IS RECEIVED.              * 
*                                                                     * 
** RESPONSE BIT DEFINITIONS-                                          * 
*                                                                     * 
*15  14  13  12    11  10  09  08    07  06  05  04    03  02  01  00 * 
*                                                                     * 
*--  --  --  TIM   BAD SFT BCD ASC   ERR REJ ACK BUF   SLC E3  E2  E1 * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4WRITE (V6WTYPE : INTEGER); 
  
CONST 
      V4WIDX    = 8;                        _INDEX TO CA,TA IN BUFFER  ?
  
BEGIN 
WITH V6CCBP'.BVCCB,                         _SET INDEX 1 TO CCB        ?
     V6TCBP'.BSTCB DO                       _SET INDEX 2 TO TCB        ?
  BEGIN 
  RETADR (BVRETCALLIO);                     _SAVE RETURN ADDRESS IN CCB?
_ 
* * * *    PREPARE AND ISSUE THE WRITE
? 
10:                                         _ENTRY FOR RETRY OF WRITE  ?
  BVIOTYPE := V6WTYPE;                      _SAVE I/O TYPE IN CCB      ?
  IF V6WTYPE < V4WAUNLOCK                   _NEED TO BUILD WRITE       ?
  THEN
    PT4BUILDWRITE (V6WTYPE);                _BUILD THE DESIRED WRITE   ?
  BVCANNED.BVTA  := BSTA;                   _PICK UP TERMINAL ADDRESS  ?
  BVCANNED.BVTOG := NOT BVTOGLASTWRT;       _ADJUST TOGGLE BIT OF WRT  ?
  BS4OUTBUF'.BIINT [V4WIDX] :=              _STORE CA + TA INTO BUFFER ?
    BVCANNED.BVCATA + ORD (BVM4A);          _ADDING 1 TO TA FOR MODE 4A?
  
  PT4IO (BS4OUTBUF);                        _ISSUE THE WRITE MESSAGE   ?
  
_ 
* * * *   PROCESS THE RESPONSE RECEIVED, IF ANY 
? 
  PT4INRELEASE;                             _RELEASE ALL INPUT BUFFERS ?
  IF PT4VERIFY ([V4RACK, V4RREJ, V4RBUFT],  _NO ERROR COUNTER OVERFLOW ?
                BVM4A)                      _M4A IN CCB, M4B/C IN TCB  ?
  THEN
    BEGIN 
    IF V6WKCODE = V4WKACK                   _ACKNOWLEDGE RECEIVED      ?
    THEN
      BEGIN 
20:                                         _ENTRY FOR WRITE RECOVERED ?
      BVTOGLASTWRT := V6RXCATA.V5TOGBIT;    _SAVE TOGGLE OF GOOD WRITE ?
      IF BVIOTYPE < V4WAUNLOCK              _NEED TO RELEASE BUFFER    ?
      THEN
        PBRELZRO (BS4OUTBUF, BEDBSIZE);     _RELEASE BUFFER FOR CALLER ?
      BS4REJCOUNT := 0;                     _RESET REJECT COUNTER      ?
      PT4RETURN (BVRETCALLIO);              _RETURN TO THE WRITE CALLER?
      END; _IF V6WKCODE = V4WKACK THEN?     _SORRY ABOUT THE PUN       ?
  
    IF [V4RREJ, V4RERR] &                   _NOT REJECT RECEIVED OR    ?
       V6RESPONSE.V5SETWD = [ ]             _    ERROR RECEIVED        ?
    THEN
_ 
* * * *   WRITE RESPONSE LOST OR BAD, ENTER WRITE RECOVERY LOGIC
? 
      BEGIN 
      BVRETWRITERR := BVRETCALLIO;          _SAVE CALLERS ADDRESS      ?
      BVIOWRITERR  := BVIOTYPE;             _SAVE CALLERS I/O TYPE     ?
      PT4CONTROL;                           _SERVICE OTHER CCBS ON LINE?
      IF BVM4A                              _MODE 4A CLUSTER           ?
      THEN                                  _POLL TO RECOVER TOGGLE BIT?
        PT4POLL (V4PTOGGLE) 
      ELSE                                  _MODE 4B / 4C CLUSTER      ?
        PT4STATUS (V4STOGGLE);              _STATUS TO RECOVER TOGGLE  ?
  
      PT4INRELEASE;                         _RELEASE ANY POSSIBLE INPUT?
      BVRETCALLIO := BVRETWRITERR;          _RESTORE CALLERS ADDRESS   ?
      BVIOTYPE    := BVIOWRITERR;           _RESTORE CALLERS I/O TYPE  ?
      IF V6RXCATA.V5TOGBIT " BVTOGLASTWRT   _TOGGLE BIT SETTING MATCHES?
      THEN                                  _THAT OF CURRENT WRITE     ?
        GOTO 20;                            _SIMULATE ACK RESPONSE     ?
  
      END; _IF NOT REJECT OR ERROR THEN?
    END; _IF NO OVERFLOW ON WRITE THEN? 
_ 
* * * *   ERROR OVERFLOW IN TCB OR CCB, OR WRITE TO BE RETRIED LATER
? 
  IF BVIOTYPE < V4WAUNLOCK                  _DID WE BUILD THE WRITE    ?
  THEN
    PBRELZRO (BS4OUTBUF, BEDBSIZE);         _RELEASE POSSIBLE WRITE BFR?
  IF BVSTATE = V4CRECOVER                   _IF CLUSTER STATE IS DOWN  ?
  THEN
    PT4RETURN (V6RADLINE);                  _RETURN TO THE LINE DRIVER ?
  
  IF BVM4A                                  _WRITE TO A MODE 4A DEVICE ?
  THEN
    BEGIN 
    IF BSDEVTYPE = N1CON                    _FOR THE CONSOLE DEVICE    ?
    THEN                                    _MAKE SURE WRITE COMPLETES ?
      BEGIN                                 _BEFORE SERVICING BATCH DEV?
      PT4CONTROL;                           _SERVICE OTHER CCBS ON LINE?
      V6WTYPE := BVIOTYPE;                  _PICK UP THE SAVED I/O TYPE?
      GOTO 10;                              _GO RETRY THE WRITE        ?
      END;
                                            _WRITE WAS TO A MODE 4A    ?
    IF V6WKCODE = V4WKREJ                   _BATCH DEVICE              ?
    THEN                                    _AND WE RECEIVED A REJECT  ?
      BEGIN 
      BS4REJCOUNT := BS4REJCOUNT + 1;       _INCREMENT REJECT COUNTER  ?
      IF BS4REJCOUNT = V4REJRETRY           _TOO MANY REJECTS RECEIVED ?
      THEN
        BEGIN 
        BS4REJCOUNT := 0;                   _RESET REJECT COUNTER      ?
        BS4STATE    := V4DREJECT;           _SET TO REJECT STATE       ?
        END;
      END; _IF V6WKCODE = V4WKREJ THEN? 
    END; _IF BVM4A THEN?
  
  PT4RETURN (V6RADCLUSTER);                 _RETURN TO CLUSTER DRIVER  ?
  END; _WITH V6CCBP'.BVCCB, V6TCBP'.BSTCB DO? 
END; _PROCEDURE PT4WRITE? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 D E V I C E D R I V E R                       * 
*                                                                     * 
*       SERVICE A SPECIFIC DEVICE                                     * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE SERVICES A SPECIFIC MODE 4 DEVICE.        * 
*              IT DECIDES IF AND WHEN AN I/O EVENT CAN BE INITIATED   * 
*              AND PROCESSES THE CORRECT COMPLETION OF THE I/O.       * 
*              THE I/O ROUTINES ARE DESIGNED SUCH THAT CONTROL IS     * 
*              RETURNED TO THE CALLER WHEN A CORRECT RESPONSE THAT    * 
*              THE CALLER NEEDS TO ACTION IS RECEIVED.                * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              V6CCBP              CURRENT CCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*                                                                     * 
** OUTPUT -    WRITES, POLLS, AND CONFIGURATION REQUESTS              * 
*              CCB AND TCB FIELDS UPDATED                             * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4RETURN           RETURN TO A GIVEN ADDRESS          * 
*              PT4CONTROL          GIVE CONTROL TO NEXT CCB ON LINE   * 
*              PT4TMREXPIRED       CHECK IF CCB/TCB TIMER EXPIRED     * 
*              PT4ATTEMPTREC       CHECK IF RECOVERY ATTEMPT IS DUE   * 
*              PT4INRELEASE        RELEASE ALL INPUT BUFFERS          * 
*              PT4UPDEVICE         BRING A DEVICE UP                  * 
*              PT4UPCLUSTER        BRING A CLUSTER UP                 * 
*              PT4DNLINE           BRING A LINE DOWN                  * 
*              PT4AUTORECRESULT    REPORT AUTO RECOGNITION RESULTS    * 
*              PT4BUILDWRITE       BUILD A CANNED WRITE MESSAGE       * 
*              PT4BINTERRUPT       SEND BATCH INTERRUPTS              * 
*              PT4PREOUTPUT        PRE-OUTPUT PROCESSING              * 
*              PT4DPINPUT          CONSOLE POST INPUT PROCESSING      * 
*              PT4CPINPUT          CARD READER POST INPUT PROCESSING  * 
*              PT4POLL             PERFORM POLL SEQUENCE              * 
*              PT4WRITE            PERFORM WRITE SEQUENCE             * 
*              PB1BFAVAIL          CHECK SINGLE BUFFER AVAILABLE      * 
*              PTREGL              CHECK REGULATIONS LEVELS           * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*              PTCOMMAND           SEND UPLINE COMMAND                * 
*              PBQUEMAINT          MAINTAIN QUEUES                    * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THIS ROUTINE MUST ONLY BE CALLED FROM ONE PLACE        * 
*              IN PT4CLUSTERDRIVER.                                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4DEVICEDRIVER;
  
VAR 
      V6ISSFC    : INTEGER;                 _INPUT STOPPED SFC         ?
  
BEGIN 
RETADR (V6RADCLUSTER);                      _SAVE RETURN ADDRESS       ?
                                            _BACK TO PT4CLUSTERDRIVER  ?
WITH V6CCBP'.BVCCB,                         _SET INDEX 1 TO CCB        ?
     V6TCBP'.BSTCB DO                       _SET INDEX 2 TO TCB        ?
  BEGIN 
  CASE BSDEVTYPE OF 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*       C O N S O L E   D E V I C E                                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
  N1CON:  
  
  BEGIN 
  CASE BS4STATE OF
_ 
* * * *   S T A R T   S T A T E 
? 
  V4DSTART: 
    BEGIN 
    IF PB1BFAVAIL (B0TH2LV)                 _NOT LOW ON BUFFERS        ?
    THEN
      BEGIN 
      PT4WRITE (V4WCLRWRT);                 _ISSUE A CLEAR WRITE       ?
      BVTOGKNOWN := TRUE;                   _DECLARE TOGGLE BIT KNOWN  ?
      BS4STATE   := V4DIOWAIT;              _SET TO NORMAL STATE       ?
      BS4READREQ := FALSE;                  _KILL ANY READ REQUEST     ?
      END;
    END; _V4DSTART? 
_ 
* * * *   N O R M A L   R U N N I N G   S T A T E 
? 
  V4DIOWAIT:  
    BEGIN 
    IF BVBATCH                              _MODE 4A IN BATCH MODE     ?
    THEN
      BS4STATE := V4DBATCHWAIT              _WAIT FOR BATCH COMPLETION ?
    ELSE
      BEGIN 
_ 
* * * *   CHECK IF OUTPUT IS POSSIBLE 
? 
      IF BS4READREQ = FALSE                 _4B/4C READ REQUEST NOT UP ?
      THEN
        BEGIN 
        IF BVM4A
        THEN                                _MODE 4A READ REQUEST      ?
          BS4READREQ :=                     _DEPENDS ON TIMER IN CCB   ?
            PT4TMREXPIRED (V4CCB);
10: 
        IF BS4INFLGS = 0                    _NOT PAGE-WAIT, AUTO-INPUT ?
        THEN
          IF PT4PREOUTPUT (N1CON)           _AND OUTPUT AVAILABLE      ?
          THEN
            BEGIN                           _DATA READY TO TRANSMIT    ?
            PT4BINTERRUPT;                  _POSSIBLE BATCH INTERRUPTS ?
            BS4STATE := V4DOUTWAIT;         _SET STATE TO ASSURE OUTPUT?
            GOTO 40;                        _TRANSMIT THE OUTPUT       ?
            END 
          ELSE
            BVSLOWTIMER := CTIMER.CT100MS + V4TSLOWDOWN;
        END; _IF BS4READREQ = FALSE THEN? 
_ 
* * * *   CHECK IF INPUT IS POSSIBLE
? 
      IF BS4READREQ                         _READ REQUEST ACTIVE       ?
      THEN
        BEGIN 
20: 
        BS4READREQ := FALSE;                _KILL THE READ REQUEST     ?
        IF PTREGL (V6TCBP) \ RGBUF2         _BUFFERS LOW / UBL EXCEEDED?
        THEN
          BEGIN 
          BS4INFLGS := 0;                   _CLR PAGE-WAIT, AUTO-INPUT ?
          GOTO 10;                          _CHECK IF OUTPUT POSSIBLE  ?
          END;
                                            _INPUT PERMITTED, DO IT NOW?
        PT4POLL (V4PCONSOLE);               _ISSUE THE POLL MESSAGE    ?
        PT4BINTERRUPT;                      _POSSIBLE BATCH INTERRUPTS ?
        PT4DPINPUT;                         _DO POST INPUT PROCESSING  ?
        BS4STATE := V4DOUTWAIT;             _SET STATE TO OUTPUT UNLOCK?
        GOTO 30;                            _LOCK, XPT END CLEAR WRITE ?
                                            _OR WAIT FOR OUTPUT, DO IT ?
        END; _IF BS4READREQ THEN? 
      END; _IF BVBATCH ELSE?
    END; _V4DIOWAIT?
_ 
* * * *   W A I T   O U T P U T   C O M P L E T I O N   S T A T E 
? 
  V4DOUTWAIT: 
    BEGIN 
30: 
    IF PT4PREOUTPUT (N1CON)                 _OUTPUT READY TO TRANSMIT  ?
    THEN
      BEGIN 
40: 
      PT4WRITE (BS4WRTYPE);                 _ISSUE THE WRITE MESSAGE   ?
      PBRELCHN (BS4OUTBUF, BEDBSIZE);       _RELEASE THE OUTPUT BUFFERS?
      BS4READREQ  := FALSE;                 _KILL ANY READ REQUEST     ?
      BVSLOWTIMER := CTIMER.CT100MS +       _EXTEND FAST POLL TIMER    ?
                     V4TSLOWDOWN;           _FOR CLUSTER               ?
      IF BS4WRTYPE " V4WLOCK                _NOT A LOCK KEYBOARD WRITE ?
      THEN                                  _TO A TRANSPARENT DEVICE   ?
        BS4STATE := V4DIOWAIT;              _EXIT OUTPUT WAIT STATE    ?
      END; _IF PT4PREOUTPUT (N1CON) THEN? 
    END; _V4DOUTWAIT? 
_ 
* * * *   W A I T   F O R   B A T C H   C O M P L E T I O N   S T A T E 
? 
  V4DBATCHWAIT: 
    BEGIN 
    IF BSQPTR.BABUFPTR " NIL                _OUTPUT FOR CONSOLE        ?
    THEN
      BEGIN 
      PT4BINTERRUPT;                        _SEND BATCH INTERRUPTS     ?
50: 
      PT4BUILDWRITE (V4WENDCLR);            _BUILD A CLEAR SCREEN WRITE?
      BVBATCH   := FALSE;                   _CLUSTER INTERACTIVE MODE  ?
      BS4LCOUNT := 0;                       _RESET LINES REMAINING     ?
      BS4STATE  := V4DOUTWAIT;              _SET STATE TO ASSURE OUTPUT?
      GOTO 40;                              _GO CLEAR THE DISPLAY      ?
      END; _IF BSQPTR.BABUFPTR " NIL THEN?
  
    IF BVLPFLGS " V4BACTIVE                 _LINE PRINTER NOT ACTIVE   ?
    THEN
      IF BVCRFLGS " V4BACTIVE               _AND CARD READER NOT ACTIVE?
      THEN
        BEGIN 
        IF BVBIREQD                         _BATCH INTERRUPT REQUIRED  ?
        THEN                                _IMPLIES NO CONSOLE INPUT  ?
          GOTO 50;                          _CLEAR THE DISPLAY SCREEN  ?
  
        BVBATCH  := FALSE;                  _CLUSTER INTERACTIVE MODE  ?
        BS4STATE := V4DIOWAIT;              _SET TO NORMAL STATE       ?
        GOTO 20;                            _GO POLL THE DISPLAY       ?
        END; _IF BVCRFLGS " V4BACTIVE THEN? 
  
    END; _V4DBATCHWAIT? 
_ 
* * * *   L O N G   T E R M   E R R O R   R E C O V E R Y   S T A T E 
? 
  V4DRECOVER: 
    BEGIN 
    IF PT4ATTEMPTREC (BVM4A)                _RECOVERY ATTEMPT DUE NOW  ?
    THEN
      BEGIN 
      PT4WRITE (V4WCLRWRT);                 _ISSUE A CLEAR WRITE       ?
      BVTOGKNOWN := TRUE;                   _DECLARE TOGGLE BIT KNOWN  ?
      IF BVM4A                              _BRING UP THE CCB OR TCB   ?
      THEN
        BEGIN 
        PT4UPCLUSTER;                       _MODE 4A, THE CLUSTER IS UP?
        PT4RETURN (V6RADLINE);              _RETURN TO THE LINE DRIVER ?
        END;
     _ELSE? 
        PT4UPDEVICE;                        _MODE 4B/C THE DEVICE IS UP?
      END; _IF PT4ATTEMPTREC (BVM4A) THEN?
    END; _V4DRECOVER? 
  
  END; _CASE BS4STATE OF? 
  END; _N1CON?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*       M O D E   4 A   C A R D   R E A D E R   D E V I C E           * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
  N1CR: 
  
  BEGIN 
  CASE BS4STATE OF
_ 
* * * *   S T A R T   S T A T E 
? 
  V4DSTART: 
    BEGIN 
    IF BVTOGKNOWN                           _WAIT TILL CONSOLE IS UP   ?
    THEN                                    _AND RUNNING               ?
      BS4STATE := V4DIOWAIT;
    END; _V4DSTART? 
_ 
* * * *   N O R M A L   R U N N I N G   S T A T E 
? 
  V4DIOWAIT:  
    BEGIN 
    IF BSQPTR.BABUFPTR " NIL                _OUTPUT QUEUE NOT EMPTY    ?
    THEN
      IF PT4PREOUTPUT (N1CR)                _PROCESS ANY COMMANDS      ?
      THEN; 
    IF BVCRFLGS = V4BACTIVE                 _CARD READER ON, AND       ?
    THEN                                    _NOT WAITING FOR RESUME    ?
      BEGIN 
      BVBATCH  := TRUE;                     _CLUSTER IN BATCH MODE     ?
      BVBIREQD := TRUE;                     _BATCH INTERRUPT REQUIRED  ?
      IF PTREGL (V6TCBP) < RGBUF2           _NOT LOW ON BUFFERS        ?
      THEN                                  _OR UBL EXCEEDED           ?
        BEGIN                               _INITIATE CARD READING     ?
        PT4WRITE (V4WE3);                   _ISSUE A WRITE E3          ?
                                            _ACK RECEIVED, RESERVE CCB ?
        PT4CONTROL;                         _SERVICE OTHER CCBS ON LINE?
        PT4POLL (V4PCARD);                  _ISSUE POLL FOR CARD DATA  ?
        V6ISSFC := 0;                       _CLEAR POSS INPUT STOPPED  ?
        CASE V6WKCODE OF
  
        V4WKE1:                             _E1 RECEIVED               ?
          BEGIN 
          PT4INRELEASE;                     _RELEASE ALL POSSIBLE INPUT?
          PT4BINTERRUPT;                    _SEND BATCH INTERRUPTS     ?
          END; _V4WKE1? 
  
        V4WKSLC:                            _SLIPPED CARD DETECTED     ?
          BEGIN 
          PT4INRELEASE;                     _RELEASE INPUT BUFFERS     ?
          V6ISSFC := D9SC;                  _SET SFC TO SLIPPED CARD   ?
          END; _V4WKSLC?
  
        V4WKE2:                             _E2 RECEIVED               ?
          BEGIN 
          PT4CPINPUT;                       _DO POST INPUT PROCESSING  ?
          IF V6EOIFND                       _END OF INFORMATION FOUND  ?
          THEN
            BEGIN 
            BVCRON  := FALSE;               _TURN CARD READER OFF      ?
            V6ISSFC := D9ES;                _SET SFC TO END OF STREAM  ?
            END 
          ELSE
            BEGIN 
110:  
            V6ISSFC := D9NR;                _SET SFC TO NOT READY      ?
            END;
          END; _V4WKE2? 
  
        V4WKE3:                             _E3 RECEIVED               ?
          BEGIN 
          PT4CPINPUT;                       _DO POST INPUT PROCESSING  ?
          END; _V4WKE3? 
  
        END; _CASE V6WKCODE OF? 
  
        IF V6ISSFC " 0                      _INPUT STOPPED DETECTED    ?
        THEN
          BEGIN 
          PTCOMMAND (V6TCBP, D8IS, V6ISSFC);_SEND COMMAND UPLINE       ?
          BVCRWAIT := V6ISSFC " D9ES;       _WAIT RESUME IF NOT EOS    ?
          END;
  
        END; _IF PTREGL (V6TCBP) < RGBUF2 THEN? 
      END; _IF BVCRFLGS = V4BACTIVE THEN? 
    END; _V4DIOWAIT?
_ 
* * * *   R E J E C T   O V E R F L O W   S T A T E 
? 
  V4DREJECT:  
    BEGIN 
    BS4STATE := V4DIOWAIT;                  _SET TO RUNNING STATE      ?
    IF BVBATCH                              _CLUSTER IN BATCH MODE     ?
    THEN
      GOTO 110;                             _TREAT AS DEVICE NOT READY ?
    END; _V4DREJECT?
  
  END; _CASE BS4STATE OF? 
  END; _N1CR? 
  
  
  N1LP: 
  BEGIN 
  IF BVM4A
  THEN
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*       M O D E   4 A   L I N E   P R I N T E R   D E V I C E         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
  BEGIN 
  CASE BS4STATE OF
_ 
* * * *   S T A R T   S T A T E 
? 
  V4DSTART: 
    BEGIN 
    IF BVTOGKNOWN                           _WAIT TILL CONSOLE IS UP   ?
    THEN                                    _AND RUNNING               ?
      BS4STATE := V4DIOWAIT;
    END; _V4DSTART? 
_ 
* * * *   N O R M A L   R U N N I N G   S T A T E 
? 
  V4DIOWAIT:  
    BEGIN 
    BVLPWAIT := BSSTSTOP;                   _WAIT IF STREAM IS STOPPED ?
    IF PT4PREOUTPUT (N1LP)                  _FOUND ANY OUTPUT DATA     ?
    THEN
      BEGIN 
      BS4TIMER := 0;                        _STOP NO DATA TIMER        ?
      BVLPON   := TRUE;                     _TURN LINE PRINTER ON      ?
      IF BVLPFLGS = V4BACTIVE               _PRINTER ON + NOT WAITING  ?
      THEN
        BEGIN 
        BVBATCH  := TRUE;                   _CLUSTER IN BATCH MODE     ?
        BVBIREQD := TRUE;                   _BATCH INTERRUPT REQUIRED  ?
        PT4WRITE (V4WNORMAL);               _OUTPUT THE PRINTER DATA   ?
                                            _ACK RECEIVED, RESERVE CCB ?
        PT4CONTROL;                         _SERVICE OTHER CCBS ON LINE?
        PT4POLL (V4PPRINT);                 _ISSUE POLL FOR PRINT STAT ?
        PT4INRELEASE;                       _RELEASE INPUT BUFFER      ?
        IF V6WKCODE = V4WKE2
        THEN                                _E2 RECEIVED               ?
          BEGIN 
210:                                        _OUTPUT NOT RELEASED YET   ?
          IF BS4OUTBUF " NIL                _BY TERMINATE OUTPUT ICMD  ?
          THEN                              _OR CONNECTION BROKEN      ?
            PTCOMMAND (V6TCBP, D8OS, D9NR); _OUTPUT STOPPED, NOT READY ?
          END _IF V6WKCODE = V4WKE2 THEN? 
        ELSE
          BEGIN                             _E1, E3 RECEIVED           ?
          PBRELZRO (BS4OUTBUF, BEDBSIZE);   _RELEASE OUTPUT BUFFERS    ?
          PBQUEMAINT (V6TCBP, V6NIL,        _FORCE UPLINE BACK CHECK   ?
                      K4PUTBC); 
          IF V6WKCODE = V4WKE1              _E1 RECEIVED               ?
          THEN
            PT4BINTERRUPT;                  _SEND BATCH INTERRUPTS     ?
          END; _IF V6WKCODE = V4WKE2 ELSE?
  
        END; _IF BVLPFLGS = V4BACTIVE THEN? 
      END _IF PT4PREOUTPUT (N1LP) THEN? 
    ELSE
      BEGIN                                 _NO PRINT DATA RETURNED    ?
      IF BVLPON                             _PRINTER PREVIOUSLY ON     ?
      THEN
        IF BS4TIMER " 0                     _NO DATA TIMER ACTIVE      ?
        THEN                                _PRINTER OFF IF EXPIRED    ?
          BVLPON := NOT PT4TMREXPIRED (V4TCB) 
        ELSE
          BS4TIMER := V4TLPQUEUE +          _START TIMER FOR SWITCH TO ?
                      CTIMER.CT100MS;       _INTERACTIVE MODE          ?
      END; _IF PT4PREOUTPUT (N1LP) ELSE?
    END; _V4DIOWAIT?
_ 
* * * *   R E J E C T   O V E R F L O W   S T A T E 
? 
  V4DREJECT:  
    BEGIN 
    BS4STATE := V4DIOWAIT;                  _SET TO RUNNING STATE      ?
    IF BVBATCH                              _CLUSTER IN BATCH MODE     ?
    THEN
      GOTO 210;                             _TREAT AS DEVICE NOT READY ?
    END; _V4DREJECT?
  
  END; _CASE BS4STATE OF? 
  END _IF BVM4A THEN? 
  ELSE
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*       M O D E   4 C   P R I N T E R   D E V I C E                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
  BEGIN 
  CASE BS4STATE OF
_ 
* * * *   S T A R T   S T A T E 
? 
  V4DSTART: 
    BEGIN 
    IF BVTOGKNOWN                           _CLUSTER TOGGLE BIT KNOWN  ?
    THEN
      IF PB1BFAVAIL (B0TH2LV)               _NOT LOW ON BUFFERS        ?
      THEN
        BEGIN 
        PT4POLL (V4PCNFG);                  _ISSUE CONFIGURATION REQUST?
        V6TA.V5TINT := BSTA;                _PICK UP TERMINAL ADDRESS  ?
        BS4LPIP := V6BUFP'.BFDATAC          _STORE TYPE OF PRINTER AS  ?
                   [V4FIDX + V6TA.V5TIDX]   _FOUND IN RESPONSE         ?
                   = CHR (V4FIPRINT); 
        PBRELCHN (V6BUFP, BEDBSIZE);        _RELEASE INPUT BUFFER      ?
        BS4STATE := V4DIOWAIT;              _WAIT FOR SOMETHING TO DO  ?
        END;
    END; _V4DSTART? 
_ 
* * * *   N O R M A L   R U N N I N G   S T A T E 
? 
  V4DIOWAIT:  
    BEGIN 
    IF BS4LPFLGS = V4LPRDYNOTBUSY           _PRINTER READY AND NOT BUSY?
    THEN
      IF PT4PREOUTPUT (N1LP)                _FOUND ANY OUTPUT DATA     ?
      THEN
        BEGIN 
        PT4WRITE (V4WNORMAL);               _OUTPUT THE PRINTER DATA   ?
        PBRELZRO (BS4OUTBUF, BEDBSIZE);     _ACK RECVD, RELEASE BUFFERS?
        PBQUEMAINT (V6TCBP, V6NIL, K4PUTBC);_FORCE UPLINE BACK CHECK   ?
        BS4LPFLGS := V4LPNOTRDYBUSY;        _SET PRINTER NOT READY,BUSY?
        END; _IF PT4PREOUTPUT (N1LP) THEN?
    END; _V4DIOWAIT?
_ 
* * * *   L O N G   T E R M   E R R O R   R E C O V E R Y   S T A T E 
? 
  V4DRECOVER: 
    BEGIN 
    IF PT4ATTEMPTREC (V4TCB)                _RECOVERY ATTEMPT DUE NOW  ?
    THEN
      BEGIN 
      PT4WRITE (V4WLPREC);                  _ISSUE AN EMPTY WRITE      ?
      PT4UPDEVICE;                          _ACK RCVD, PRINTER IS UP   ?
      BS4STATE := V4DSTART;                 _GO DETERMINE PRINTER TYPE ?
      END;
    END; _V4DRECOVER? 
  
  END; _CASE BS4STATE OF? 
  END; _IF BVM4A ELSE?
  END; _N1LP? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*       A U T O - R E C O G N I T I O N   D E V I C E                 * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
  V4AUTOREC:  
  
  BEGIN 
  IF PB1BFAVAIL (B0TH2LV)                   _NOT LOW ON BUFFERS        ?
  THEN
    CASE BS4STATE OF
_ 
* * * *   R E C O G N I Z E   C L U S T E R   A D D R E S S 
? 
    V4ARADDRESS:  
      BEGIN 
      BVERRCOUNT := V4MAXRETRY - 1;         _ONLY ALLOW ONE ATTEMPT    ?
      BVSTATE    := V4CNORMAL;              _SET TO NORMAL STATE       ?
      PT4POLL (V4PARADDR);                  _ISSUE THE POLL            ?
      PT4INRELEASE;                         _RELEASE ANY INPUT         ?
      BS4STATE := V4ARCODESET;              _DETERMINE CODE SET        ?
      END; _V4ARADDRESS?
_ 
* * * *   R E C O G N I Z E   C O D E   S E T 
? 
    V4ARCODESET:  
      BEGIN 
      PT4POLL (V4PARCODE);                  _ISSUE THE POLL            ?
      PT4INRELEASE;                         _RELEASE ANY INPUT         ?
      IF V6WKCODE = V4WKBCD                 _BCD RECOGNIZED            ?
      THEN
        PT4AUTORECRESULT (V4A4ABCD);        _REPORT MODE 4A BCD        ?
      IF V6WKCODE = V4WKASC                 _ASCII RECOGNIZED          ?
      THEN
        BEGIN 
        BVERRCOUNT := V4MAXRETRY - 2;       _ALLOW ONLY TWO ATTEMPTS TO?
        BS4STATE   := V4ARCNFIG;            _DETERMINE CONFIGURATION   ?
        END 
      ELSE
        V6LCBP'.BZ4DELAYLINE := TRUE;       _REJECT RECEIVED, SET DELAY?
      END; _V4ARCODESET?
_ 
* * * *   R E C O G N I Z E   C O N F I G U R A T I O N 
? 
    V4ARCNFIG:  
      BEGIN 
      PT4POLL (V4PCNFG);                    _ISSUE CONFIGURATION REQUST?
      PT4AUTORECRESULT (V4A4CASCII);        _GOOD RESP, MODE 4C ASCII  ?
      END; _V4ARCNFIG?
_ 
* * * *   E R R O R   O V E R F L O W 
? 
    V4DRECOVER: 
      BEGIN 
      IF BVIOTYPE = V4PARADDR               _DURING ADDRESS RECOGNITION?
      THEN
        BEGIN 
        BS4ERRCOUNT := BS4ERRCOUNT + 1;     _BUMP ATTEMPT COUNTER      ?
        IF BS4ERRCOUNT = V4ARRETRY          _TRIED EVERYONE TWICE      ?
        THEN
          PT4DNLINE (V4LINOPERATIVE);       _BRING THE LINE DOWN       ?
  
        BVCANNED.BVARCA :=                  _SET NEXT CLUSTER ADDRESS  ?
          BVCANNED.BVARCA + 1;
        BS4STATE := V4ARADDRESS;            _TRY NEXT CLUSTER ADDRESS  ?
        END _IF BVIOTYPE = V4PARADDR THEN?
      ELSE
        BEGIN 
        IF BVIOTYPE = V4PARCODE             _DURING CODE SET RECOGNTION?
        THEN                                _BRING THE LINE DOWN       ?
          PT4DNLINE (V4LINOPERATIVE); 
                                            _DURING CONFIGURATION RECOG?
        PT4AUTORECRESULT (V4A4AASCII);      _REPORT MODE 4A ASCII      ?
        END; _IF BVIOTYPE = V4PARADDR ELSE? 
      END; _V4DRECOVER? 
  
    END; _CASE BS4STATE OF? 
  END; _V4AUTOREC?
  
  END; _CASE BSDEVTYPE OF?
  END; _WITH V6CCBP'.BVCCB, V6TCBP'.BSTCB DO? 
  
PT4RETURN (V6RADCLUSTER);                   _RETURN TO CLUSTER DRIVER  ?
  
END; _PROCEDURE PT4DEVICEDRIVER?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 C L U S T E R D R I V E R                     * 
*                                                                     * 
*       SERVICE ALL DEVICES ON A CLUSTER                              * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE SERVICES A GIVEN CLUSTER AND MAINTAINS    * 
*              CONTROL OVER THE SERVICING OF ALL DEVICES ON THE       * 
*              CLUSTER.                                               * 
*                                                                     * 
** INPUT -     V6CCBP              CURRENT CCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4LINEDRIVER       SERVICE ALL CLUSTERS ON A LINE     * 
*                                                                     * 
** OUTPUT -    STATUS REQUEST ISSUED FOR MODE 4B OR 4C CLUSTER        * 
*              CONTROL GIVEN TO SERVICE EACH DEVICE                   * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4RETURN           RETURN CONTROL TO GIVEN ADDRESS    * 
*              PT4TMREXPIRED       CHECK IF CCB / TCB TIMER EXPIRED   * 
*              PT4ATTEMPTREC       CHECK IF RECOVERY ATTEMPT IS DUE   * 
*              PT4UPCLUSTER        BRING A CLUSTER UP                 * 
*              PT4STATUS           PERFORM STATUS REQUEST SEQUENCE    * 
*              PT4DEVICEDRIVER     SERVICE A SPECIFIC DEVICE          * 
*              PB1BFAVAIL          CHECK SINGLE BUFFER AVAILABLE      * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THIS ROUTINE MUST ONLY BE CALLED FROM ONE PLACE        * 
*              IN PT4LINEDRIVER.                                      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4CLUSTERDRIVER; 
  
BEGIN 
RETADR (V6RADLINE);                         _SAVE RETURN ADDRESS       ?
                                            _BACK TO PT4LINEDRIVER     ?
WITH V6CCBP'.BVCCB DO                       _SET INDEX 1 TO CCB        ?
  BEGIN 
_ 
* * * *   PROCESS ANY CLUSTER RESERVATION 
? 
  IF BVRESERVED                             _CLUSTER RESERVED          ?
  THEN
    BEGIN 
    BVRESERVED := FALSE;                    _CLEAR RESERVATION FLAG    ?
    V6TCBP     := BVCURTCB;                 _SET CURRENT TCB POINTER   ?
    WITH V6TCBP'.BSTCB DO                   _SET INDEX 2 TO TCB        ?
      PT4RETURN (BVRETRESERVED);            _RETURN BACK TO CALLER THAT?
    END; _IF BVRESERVED THEN?               _RESERVED THE CLUSTER      ?
_ 
* * * *   IF TIME FOR MODE 4B / 4C STATUS REQUEST, THEN DO SO 
? 
  IF BVM4A = FALSE                          _MODE 4B OR 4C CLUSTER     ?
  THEN
    BEGIN 
    IF BVSTATE = V4CNORMAL                  _CLUSTER UP AND RUNNING    ?
    THEN
      BEGIN 
      IF PT4TMREXPIRED (V4CCB)              _TIME FOR STATUS REQUEST   ?
      THEN
        IF PB1BFAVAIL (B0TH2LV)             _AND A BUFFER AVAILABLE    ?
        THEN
          PT4STATUS (V4STATUS);             _ISSUE REQ. AND PROCESS RSP?
      END _IF BVSTATE = V4CNORMAL THEN? 
    ELSE
      BEGIN                                 _CLUSTER IN RECOVERY STATE ?
      IF PT4ATTEMPTREC (V4CCB)              _RECOVERY ATTEMPT DUE NOW  ?
      THEN
        BEGIN 
        PT4STATUS (V4STATUS);               _ATTEMPT RECOVERY STATUS   ?
        PT4UPCLUSTER;                       _GOOD RESP. CLUSTER IS UP  ?
        END;
      PT4RETURN (V6RADLINE);                _RETURN TO THE LINE DRIVER ?
      END; _IF BVSTATE = V4CNORMAL ELSE?
    END; _IF BVM4A = FALSE THEN?
_ 
* * * *   SERVICE ALL DEVICES ON THE CLUSTER
? 
  V6TCBP := BVTCBPTR;                       _PICK UP PTR TO FIRST TCB  ?
  
  REPEAT
    BVCURTCB := V6TCBP;                     _SET CURRENT TCB POINTER   ?
  
    PT4DEVICEDRIVER;                        _SERVICE THE DEVICE        ?
  
    V6TCBP := V6TCBP'.BSTCB.BS4TCBPTR;      _GET PTR TO NEXT TCB ON CCB?
  UNTIL V6TCBP = NIL;                       _UNTIL ALL TCBS SERVICED   ?
  
  END; _WITH V6CCBP'.BVCCB DO?
END; _PROCEDURE PT4CLUSTERDRIVER? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 L I N E D R I V E R                           * 
*                                                                     * 
*       SERVICE ALL CLUSTERS ON A LINE                                * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE PROVIDES THE HIGHEST LEVEL CONTROL OF A   * 
*              MODE 4 LINE BY SERVICING EACH CLUSTER ON THE LINE      * 
*              IN A CIRCULAR FASHION.                                 * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    CONTROL GIVEN TO SERVICE EACH CLUSTER                  * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4IO               PERFORM INPUT / OUTPUT SEQUENCE    * 
*              PT4TERMIO           TERMINATE INPUT AND OUTPUT         * 
*              PT4CLUSTERDRIVER    SERVICE ALL DEVICES ON A CLUSTER   * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THIS ROUTINE WILL NEVER RETURN TO ITS CALLER.          * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4LINEDRIVER;
  
BEGIN 
PT4TERMIO (V4LTERMIO);                      _CLEAN UP ANY POSSIBLE I/O ?
  
REPEAT
_ 
* * * *   SERVICE ALL CLUSTERS ON THE LINE
? 
  V6LCBP'.BZ4RECATTEMPT := TRUE;            _ALLOW ONE RECOVERY ATTEMPT?
  V6LCBP'.BZ4DELAYLINE  := TRUE;            _LINE CANDIDATE FOR DELAY  ?
  V6CCBP := V6LCBP'.BZ4CCBPTR;              _PICK UP PTR TO FIRST CCB  ?
  
  REPEAT
    V6LCBP'.BZ4CURCCB := V6CCBP;            _SET CURRENT CCB POINTER   ?
  
    PT4CLUSTERDRIVER;                       _SERVICE THE CLUSTER       ?
  
    V6CCBP := V6CCBP'.BVCCB.BVCCBPTR;       _GET PTR NEXT CCB ON LINE  ?
  UNTIL V6CCBP = NIL;                       _UNTIL ALL CCBS SERVICED   ?
_ 
* * * *   ALL CLUSTERS SERVICED, DELAY LINE IF REQUIRED 
? 
  IF V6LCBP'.BZ4DELAYLINE                   _LINE NEEDS TO BE DELAYED  ?
  THEN
    BEGIN                                   _YES PERFORM LINE DELAY    ?
    V6LCBP'.BZSTATE := V4LDELAYED;          _SET LINE STATE DELAYED    ?
    PT4IO (NIL);                            _DELAY LINE FOR A WHILE    ?
    V6LCBP'.BZSTATE := V4LACTIVE;           _SET LINE STATE ACTIVE     ?
    END; _IF V6LCBP'.BZ4DELAYLINE THEN? 
  
UNTIL FALSE;
END; _PROCEDURE PT4LINEDRIVER?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 T C B I N I T                                 * 
*                                                                     * 
*       INITIALIZE NEW TCB                                            * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE INITIALIZES A NEWLY BUILT TCB.            * 
*              IF THIS IS THE FIRST TCB BUILT FOR A CLUSTER THEN      * 
*              A CLUSTER CONTROL BLOCK (CCB) IS CREATED, INITIALIZED  * 
*              AND LINKED INTO THE LCB-CCB CHAIN.                     * 
*              THE NEW TCB WILL BE LINKED INTO THE CCB-TCB CHAIN.     * 
*                                                                     * 
** INPUT -     V6LCBP              CURRENT LCB POINTER                * 
*              V6TCBP              CURRENT TCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*                                                                     * 
** OUTPUT -    TCB INITIALIZED AND LINKED, AND POSSIBLY               * 
*              CCB INITIALIZED AND LINKED                             * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBGET1BF            GET A BUFFER                       * 
*              PBCLR               CLEAR AN AREA OF MEMORY            * 
*              PBFCOPY             COPY CHARACTERS INTO A BUFFER      * 
*                                                                     * 
** SPECIAL NOTE -                                                     * 
*              THE CLUSTER CONTROL BLOCK CONTAINS A CANNED MESSAGE    * 
*              PORTION WHICH IS USED WHEN ISSUING POLLS, STATUS       * 
*              REQUESTS AND CONFIGURATION REQUESTS.                   * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4TCBINIT; 
  
VAR 
      V6PREVP  : B0BUFPTR;                  _PREVIOUS CNTRL BLK POINTER?
      V6CANNED : ARRAY [0..6] OF INTEGER;   _CANNED POLL / STATUS MSG  ?
  
VALUE 
      V6CANNED = ($0D02,                    _LCD, FCD FOR PBFCOPY      ?
                  $0B03,                    _   L C D          F C D   ?
                  $1016,                    _   F L A G S      S Y N   ?
                  $1616,                    _   S Y N          S Y N   ?
                  $1601,                    _   S Y N          S O H   ?
                  $0000,                    _   C A            T A     ?
                  $0003);                   _   M T I          E T X   ?
  
BEGIN 
WITH V6TCBP'.BSTCB DO                       _SET INDEX TO CURRENT TCB  ?
  BEGIN 
_ 
* * * *   FIND THE CCB FOR THIS TCB, IF THERE IS ONE
? 
  V6CCBP  := V6LCBP'.BZ4CCBPTR;             _START WITH THE FIRST CCB  ?
  V6PREVP := NIL;                           _PRESET PREVIOUS CCB TO NIL?
  WHILE (V6CCBP " NIL) &                    _WHILE MORE CCBS ON LINE   ?
        (V6CCBP'.BVCCB.                     _AND HAVE NOT FOUND A CCB  ?
                 BVCANNED.BVCA " BSCA) DO   _WITH MATCHING CLUSTER ADDR?
    BEGIN 
    V6PREVP := V6CCBP;                      _PREVIOUS BECOMES THIS ONE ?
    V6CCBP  := V6CCBP'.BVCCB.BVCCBPTR;      _GET POINTER TO NEXT CCB   ?
    END;
  IF V6CCBP = NIL                           _CCB DOES NOT ALREADY EXIST?
  THEN
_ 
* * * *   NO CCB FOR THIS TCB, CREATE AND INITIALIZE ONE
? 
    BEGIN 
    V6CCBP := PBGET1BF (B0S16);             _GET A BUFFER FOR THE CCB  ?
    PBCLR (V6CCBP, 16);                     _CLEAR THE CCB             ?
    WITH V6CCBP'.BVCCB DO                   _SET INDEX TO NEW CCB      ?
      BEGIN 
      BVTCBPTR := V6TCBP;                   _NEW TCB IS FIRST OF CHAIN ?
      BVTIMER  := CTIMER.CT100MS;           _START POLL / STATUS TIMER ?
  
      ADDR (V6CANNED, V6BUFP);              _GET ADDRESS OF CANNED AREA?
      PBFCOPY (V6BUFP, V6CCBP);             _LOAD CANNED POLL/STATUS   ?
      BVCANNED.BVCA := BSCA;                _STORE CLUSTER ADDRESS     ?
  
      IF (BSTCLASS = N0200UT) !             _200 UT, 214 AND           ?
         (BSTCLASS = N0734)                 _731, 734, CYB18 - MODE 4A ?
      THEN
        BVM4A := TRUE 
      ELSE                                  _711-10 - MODE 4B          ?
        BVM4C := BSTCLASS " N0711;          _714-10/20, 714-30  MODE 4C?
      END; _WITH V6CCBP'.BVCCB DO?
_ 
* * * *   INSERT NEW CCB IN LCB-CCB CHAIN 
? 
    IF V6PREVP = NIL                        _THIS CCB IS THE FIRST ONE ?
    THEN
      V6LCBP'.BZ4CCBPTR := V6CCBP           _YES INSERT PTR INTO LCB   ?
    ELSE
      BEGIN 
      V6PREVP'.BVCCB.BVCCBPTR := V6CCBP;    _NO  INSERT PTR INTO CCB   ?
      V6LCBP'.BZ4MLTCLS       := TRUE;      _SET MULTIPLE CLUSTERS FLAG?
      END; _IF V6PREVP = NIL ELSE?
    END _IF V6CCBP = NIL THEN?
  ELSE
_ 
* * * *   INSERT NEW TCB IN CCB-TCB CHAIN 
? 
    BEGIN 
    V6PREVP := V6CCBP'.BVCCB.BVTCBPTR;      _PICK UP FIRST TCB OF CHAIN?
    WHILE V6PREVP'.BSTCB.BS4TCBPTR " NIL DO _FIND LAST TCB OF CHAIN    ?
      V6PREVP := V6PREVP'.BSTCB.BS4TCBPTR;
    V6PREVP'.BSTCB.BS4TCBPTR := V6TCBP;     _THIS TCB BECOMES THE LAST ?
  
    END; _IF V6CCBP = NIL ELSE? 
_ 
* * * *   COMPLETE INITIALIZATION OF THE NEW TCB
? 
  BS4CCBPTR := V6CCBP;                      _STORE BACKWARD PTR TO CCB ?
  
  END; _WITH V6TCBP'.BSTCB DO?
END; _PROCEDURE PT4TCBINIT? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 S T A R T   O F   P T M O D E 4 T I P               * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
BEGIN 
V6DBGA[V6DBGI] := BWWLENTRY[OPS].B0TIPWLE;  _SAVE WORKLIST ENTRY       ?
V6DBGI         := (V6DBGI + 1) MOD 25;      _UPDATE INDEX INTO ARRAY   ?
  
WITH BWWLENTRY [OPS].B0EWLQ DO              _OPS LVL INTERMEDIATE ARRAY?
  BEGIN 
  V6WKCODE      := MMWKCODE;                _GET WORKCODE              ?
  V6BUFP        := MMIBP;                   _    INPUT BUFFER POINTER  ?
  V6LINO.BDLINO := MMLINO;                  _    LINE NUMBER           ?
  V6CMDP.NKLINO := V6LINO.BDLINO;           _STORE IT IN COMMAND PACKET?
  ADDR (CGLCBP'[MMPORT], V6LCBP);           _GET LCB ADDRESS           ?
  END;
  
V6LSTATE := V6LCBP'.BZSTATE;                _SAVE CURRENT LINE STATE   ?
V6CCBP   := V6LCBP'.BZ4CURCCB;              _GET CURRENT CCB POINTER   ?
V6LCBP'.BZWKCODE := V6WKCODE;               _SAVE WORK CODE IN LCB     ?
IF V6WKCODE " V4WKDLCMD                     _NOT CALLED BY PT4SCAN     ?
THEN
  V6TCBP   := V6CCBP'.BVCCB.BVCURTCB;       _GET POSSIBLE CURRENT TCB  ?
  
CASE V6WKCODE OF                            _PROCESS THE RCVD WORKCODE ?
  
  
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*      P R O C E S S   W O R K L I S T S   F R O M   S V M            * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
_ 
* * * *   E N A B L E   L I N E 
? 
  A0SMEN: 
  
  BEGIN 
  V6LCBP'.BZ4MLTCLS := FALSE;               _RESET MULTI CLUSTERS FLAG ?
  IF V6LCBP'.BZAUTO                         _AUTO-RECOGNITION REQUESTED?
  THEN
_ 
* * * *   AUTO-RECOGNITION REQUESTED - GO DO IT 
? 
    BEGIN 
    V6LCBP'.BZ4ARINPROG := TRUE;            _AUTO RECOGNITION ACTIVE   ?
    V6TCBP := PBGET1BF (B0S64);             _GET A BUFFER FOR A-R TCB  ?
    PBCLR (V6TCBP, 64);                     _CLEAR THE TCB BUFFER      ?
    V6TCBP'.BSTCB.BSDEVTYPE := V4AUTOREC;   _SET A-R DEVICE TYPE       ?
    V6TCBP'.BSTCB.BSCA      := V4ARCA;      _INITIALIZE CLUSTER ADDRESS?
    V6TCBP'.BSTCB.BSTA      := V4ARTA;      _AND TERMINAL ADDRESS      ?
    V6TCBP'.BSTCB.BSTCLASS  := N0200UT;     _SET MODE 4A SO NO STATUS  ?
                                            _AND ERRORS COUNTED IN CCB ?
    PT4TCBINIT;                             _INITIALIZE A-R TCB (+ CCB)?
    PT4LINEDRIVER;                          _START THE LINE DRIVER     ?
    END;
_ 
* * * *   NO AUTO-RECOGNITION REQUESTED, REPORT LINE OPERATIONAL
? 
  V6LCBP'.BZSTATE := V4LWAITCB;             _LINE STATE WAIT FOR TCB   ?
  PT4TELLSVM (D0LINE, D5OPER);              _LINE OPERATIONAL TO SVM   ?
  END; _A0SMEN? 
_ 
* * * *   D I S A B L E   L I N E 
? 
  A0SMDA: 
  
  BEGIN 
  PT4DNLINE (V4LDISABLED);                 _TAKE THE LINE DOWN        ? 
  END; _A0SMDA? 
_ 
* * * *   T C B   B U I L T 
? 
  A0SMTCB:  
  
  BEGIN 
  V6TCBP := V6BUFP;                         _PICK UP PTR TO NEW TCB    ?
  PT4TCBINIT;                               _INITIALIZE THE NEW TCB    ?
  IF V6LSTATE = V4LWAITCB                   _WAITING FOR FIRST TCB     ?
  THEN
    PT4LINEDRIVER;                          _START THE LINE DRIVER     ?
  END; _A0SMTCB?
_ 
* * * *   D E L E T E   T C B 
? 
  A0SMDLTCB:  
  
  BEGIN 
  V6TCBP := V6BUFP;                         _PICK UP THE TCB POINTER   ?
  V6CCBP := V6TCBP'.BSTCB.BS4CCBPTR;        _GET POINTER TO CCB        ?
  WITH V6CCBP'.BVCCB,                       _SET INDEX TO CCB          ?
       V6LCBP' DO                           _             AND LCB      ?
    BEGIN 
_ 
* * * *   DOWN THE TCB, DELINK IT FROM CHAINS, AND INFORM SVM 
? 
    V6BUFP := NIL;                          _CLEAR INPUT BUFFER POINTER?
    PT4DNDEVICE (V4EDELETE);                _TCB IS DOWN, AND MAYBE CCB?
    PT4DELINK (V6TCBP, BZTCBPTR, V6BSCHAIN);_DELINK FROM LCB-TCB CHAIN ?
    PT4DELINK (V6TCBP, BVTCBPTR, V6BS4TCB); _DELINK FROM CCB-TCB CHAIN ?
    PT4TELLSVM (D0TCB, D5DELE);             _TELL SVM TO RELEASE TCB   ?
_ 
* * * *   DETERMINE IF ANY CURRENT I/O AFFECTED BY THIS DELETION
? 
    V6TERMIO :=  (BZ4CURCCB = V6CCBP) &     _TERMINATE I/O IF DOING IT ?
                ((BVCURTCB = V6TCBP) !      _WITH THIS CCB AND EITHER  ?
                 (BVTCBPTR = NIL));         _WITH THIS DELETED TCB OR  ?
                                            _DELETED ALL TCBS ON CCB   ?
_ 
* * * *   IF ALL TCBS ON CCB DELETED THEN DELINK AND RELEASE THE CCB
? 
    IF BVTCBPTR = NIL                       _DELETED LAST TCB ON CCB   ?
    THEN
      BEGIN                                 _CCB NO LONGER REQUIRED    ?
      PT4DELINK (V6CCBP, BZ4CCBPTR, 
                 V6BVCCB);                  _DELINK FROM LCB-CCB CHAIN ?
      PBREL1BF (V6CCBP, B0S16);             _RELEASE THE CCB BUFFER    ?
      END;
_ 
* * * *   STOP, RESTART, OR CONTINUE LINE SERVICE 
? 
    IF V6LSTATE \ V4LTERMIO                 _I/O OR TIMEOUT OUTSTANDING?
    THEN
      IF BZ4CCBPTR = NIL                    _DELETED ALL TCBS (+ CCBS) ?
      THEN
        PT4TERMIO (V4LWAITCB)               _YES STOP SERVICING LINE   ?
      ELSE
        IF V6TERMIO                         _    I/O FOR THIS TCB/CCB  ?
        THEN
          PT4LINEDRIVER;                    _    YES RESTART THE DRIVER?
    END; _WITH V6CCBP'.BVCCB, V6LCBP' DO? 
  END; _A0SMDLTCB?
_ 
* * * *   B A T C H   C O N N E C T I O N   B R O K E N 
? 
  A0TIP:  
  
  BEGIN 
  V6TCBP := V6BUFP;                         _PICK UP THE TCB POINTER   ?
  V6TCBP'.BSTCB.BS4CCBPTR'.                 _CLEAR MODE 4A BATCH FLAGS ?
                BVCCB.BVBTCHFLGS := 0;
  PBRELZRO (V6TCBP'.BSTCB.BS4OUTBUF,        _RELEASE POSSIBLE OUTPUT   ?
            BEDBSIZE);
  PT4TPREL;                                 _RELEASE PRINTER TP BFRS   ?
  END; _A0TIP?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*      P R O C E S S   D O W N L I N E   D A T A / C O M M A N D S    * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
_ 
* * * *   O U T P U T   Q U E U E D 
? 
  A0QUEOUT: 
  
  BEGIN 
  IF V6LSTATE = V4LDELAYED                  _LINE SERVICE BEING DELAYED?
  THEN
    PT4RETURN (V6LCBP'.BZRET1ADDR);         _WAKE UP THE LINE DRIVER   ?
  END; _A0QUEOUT? 
_ 
* * * *   P R I N T E R   C O M M A N D   R E C E I V E D 
? 
  V4WKDLCMD:  
  
  BEGIN 
  PT4PROCESSCMD;                            _PROCESS THE CMD/ICMD BLOCK?
  END; _V4WKDLCMD?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*      P R O C E S S   P A R T I A L   I N P U T   D A T A            * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
  V4WKPART :  
  
  BEGIN 
  IF V6LSTATE = V4LACTIVE                   _LINE ACTIVE WITH I/O      ?
  THEN
    PT4INQUEUE                              _QUEUE PARTIAL INPUT DATA  ?
  ELSE
    PBRELZRO (V6BUFP, BEDBSIZE);            _RELEASE THE INPUT DATA    ?
  END; _V4WKPART? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*      P R O C E S S   I / O   C O M P L E T I O N   E V E N T S      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
_ 
* * * *   F R O M   I N P U T   S T A T E S 
? 
  V4WKE1 , V4WKE2 , V4WKE3 , V4WKSLC, 
  V4WKREJ, V4WKACK, V4WKERR,
  V4WKASC, V4WKBCD :  
  
  BEGIN 
  IF V6LSTATE = V4LACTIVE                   _LINE ACTIVE WITH I/O      ?
  THEN
    BEGIN 
    IF V6WKCODE @ V4WKSLC                   _POSSIBLE PARTIAL INPUT    ?
    THEN
      BEGIN 
      PT4INQUEUE;                           _QUEUE INPUT RECEIVED      ?
      V6RXCATA.V5INT :=                     _PICK UP RECEIVED CA/TA    ?
        V6TCBP'.BSTCB.BS4INBUF'.BIINT [V4XIDX]; 
      END 
    ELSE
      V6RXCATA.V5INT :=                     _GET CA/TA FROM INPUT BFR  ?
        V6BUFP'.BIINT [V4XIDX]; 
_ 
* * * *   CHECK THAT INPUT IS FROM CORRECT TERMINAL 
? 
    WITH V6CCBP'.BVCCB DO                   _SET FIRST INDEX TO CCB    ?
      BEGIN 
      V6ADDRMASK.V5INT := V6RXMASK [BVM4A]; _USE CORRECT ADDRESS MASK  ?
      IF V6RXCATA.V5SET & V6ADDRMASK.V5SET "_RESPONSE FROM INCORRECT TM?
         BVCANNED.BVSET & V6ADDRMASK.V5SET
      THEN
        V6WKCODE := V4WKBAD;                _SET WORKCODE OF BAD ADDR  ?
100:  
      V6RESPONSE.V5BITS :=
        BITMASK [V6WKCODE - A0WK1];         _SET RESPONSE TYPE BIT     ?
      WITH V6TCBP'.BSTCB DO                 _SET SECOND INDEX TO TCB   ?
        PT4RETURN (V6LCBP'.BZRET1ADDR);     _RETURN TO PT4IO CALLER    ?
  
      END; _WITH V6CCBP'.BVCCB DO?
    END; _IF V6LSTATE = V4LACTIVE THEN? 
 _ELSE? 
    PBRELZRO (V6BUFP, BEDBSIZE);            _RELEASE POSSIBLE INPUT BFS?
  
  END; _V4WKE1 .... V4WKBCD?
_ 
* * * *    F R O M   I N P U T   S T A T E S   ( N O   C A  /  T A )
? 
  V4WKSOFT :                                _SOFT ERROR DETECTED       ?
  
  BEGIN 
200:  
  IF V6LSTATE = V4LACTIVE                   _LINE ACTIVE WITH I/O      ?
  THEN
    WITH V6CCBP'.BVCCB DO                   _SET FIRST INDEX TO CCB    ?
      GOTO 100;                             _RETURN TO PT4IO CALLER    ?
 _ELSE? 
    PBRELZRO (V6BUFP, BEDBSIZE);            _RELEASE POSSIBLE INPUT    ?
  END; _V4WKSOFT? 
  
  V4WKBUFT :                                _BUFFER THRESHOLD REACHED  ?
  
  BEGIN 
  V6BUFP := NIL;                            _BUFFERS ALREADY RELEASED  ?
  GOTO 200;                                 _RETURN TO PT4IO CALLER    ?
  END; _V4WKBUFT? 
_ 
* * * *   I N P U T   T E R M I N A T E D 
? 
  V4WKINPTERM:  
  
  BEGIN 
  WITH V6LCBP' DO                           _SET INDEX TO LCB          ?
    BEGIN 
    IF BWWLENTRY [OPS].B0EWLQ.              _MATCHING WAIT COUNT       ?
       MMWTCOUNT = BZWTCOUNT
    THEN
      BEGIN 
      IF V6LSTATE = V4LTERMIO               _TERMIO DONE ON ACTIVE LINE?
      THEN
        BZSTATE := V4LACTIVE;               _DECLARE LINE ACTIVE AGAIN ?
      PT4RETURN (BZRET2ADDR);               _RETURN TO PT4TERMIO CALLER?
      END;
    END; _WITH V6LCBP' DO?
  END; _V4WKINPTERM?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*      P R O C E S S   W O R K L I S T S   F R O M   S Y S T E M      * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
_ 
* * * *   H A R D   E R R O R 
? 
  A0HARDERR:  
  
  BEGIN 
  IF V6LSTATE > V4LINOPERATIVE              _NOT DISABLED / INOPERATIVE?
  THEN
    PT4DNLINE (V4LINOPERATIVE);             _BRING THE LINE DOWN       ?
  END; _A0HARDERR?
_ 
* * * *   L I N E   T I M E O U T 
? 
  A0TIMEOUT:  
  
  BEGIN 
  IF V6LCBP'.BZWTCOUNT =
     BWWLENTRY [OPS].B0EWLQ.MMWTCOUNT       _VALID TIMEOUT RECEIVED    ?
  THEN
    BEGIN 
    IF V6LSTATE = V4LDELAYED                _LINE SERVICE BEING DELAYED?
    THEN
      PT4RETURN (V6LCBP'.BZRET1ADDR);       _WAKE UP THE LINE DRIVER   ?
  
    IF V6LSTATE = V4LACTIVE                 _LINE ACTIVE WITH I/O      ?
    THEN
      BEGIN 
      PT4TERMIO (V4LTERMIO);                _IGNORE POSSIBLE QUED INPUT?
      V6WKCODE := V4WKTIMO;                 _INTERNAL WORKCODE- TIMEOUT?
      V6BUFP   := NIL;                      _CLEAR INPUT BUFFER POINTER?
      WITH V6CCBP'.BVCCB DO                 _SET FIRST INDEX TO CCB    ?
        GOTO 100;                           _RETURN TO PT4IO CALLER    ?
      END; _IF V6LSTATE = V4LACTIVE THEN? 
    END; _IF V6LCBP'.BZWTCOUNT .... THEN? 
  END; _A0TIMEOUT?
  
  END; _CASE V6WKCODE OF? 
_ 
* * * *   R E T U R N   T O   O P S   M O N I T O R   O R  P T 4 S C A N
? 
999:  
END; _PROCEDURE PTMODE4TIP? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 T P R E L                                     * 
*                                                                     * 
*       RELEASE TEXT PROCESSING INFORMATION                           * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE RELEASES THE TPCB AND ANY REMAINING       * 
*              SOURCE AND DESTINATION BUFFERS.                        * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4DNDEVICE         BRING A DEVICE DOWN                * 
*              PT4PROCESSCMD       PROCESS CMD / ICMD BLOCKS          * 
*              PT4MODE4TIP         MODE 4  WORKLIST PROCESSOR         * 
*              PT4TEXTPROCESS      MODE 4 OUTPUT TEXT PROCESSOR       * 
*                                                                     * 
** OUTPUT -    BUFFERS RELEASED, AND TCB FIELDS UPDATED               * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PTTPRSMRK           RELEASE BUFFER WITH TPMARKS        * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*              PBREL1BF            RELEASE A SINGLE BUFFER            * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4TPREL; 
  
VAR 
      V6TPCB : B0BUFPTR;                    _LOCAL TPCB POINTER        ?
  
BEGIN 
V6TPCB := V6TCBP'.BSTCB.BS4TPCB;            _PICK UP POINTER TO TPCB   ?
IF V6TPCB " NIL                             _TPCB ASSIGNED             ?
THEN
  BEGIN                                     _RELEASE ALL TP INFORMATION?
  PBRELZRO (V6TPCB'.BGMLCB.NCFSBA,          _RELEASE POSSIBLE SOURCE   ?
            BEDBSIZE);
  PBRELZRO (V6TPCB'.BGMLCB.NCFDBA,          _RELEASE POSSIBLE DESTIN.  ?
            BEDBSIZE);
  IF V6TCBP'.BSTCB.BS4MARK " NIL            _BUFFER WITH TPMARKS       ?
  THEN                                      _YES, RELEASE THE BUFFER   ?
    PTTPRSMRK (V6TCBP'.BSTCB.BS4MARK, TRUE);
  PBREL1BF (V6TCBP'.BSTCB.BS4TPCB,          _RELEASE THE TPCB BUFFER   ?
            BETPSIZE);
  END;
END; _PROCEDURE PT4TPREL? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 T E X T P R O C E S S                         * 
*                                                                     * 
*       MODE 4 OUTPUT TEXT PROCESSOR                                  * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE TEXT PROCESSES SOURCE DATA INTO           * 
*              DESTINATION TRANSMISSION BLOCKS.                       * 
*                                                                     * 
** INPUT -     V6TCBP              CURRENT TCB POINTER                * 
*              V6BLKTYPE           CURRENT BLOCK TYPE                 * 
*              POINTER TO SOURCE DATA                                 * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PT4BUILDWRITE       BUILD A CANNED WRITE MESSAGE       * 
*              PT4PREOUTPUT        PRE-OUTPUT PROCESSING              * 
*              PT4SCAN             PREVIEW OUTPUT DATA AND COMMANDS   * 
*                                                                     * 
** OUTPUT -    BATCH       - NORMALLY NIL (TRANSMISSION BLOCKS        * 
*                            QUEUED DIRECTLY) OR                      * 
*                            POINTER TO EOI MARKER BLOCK              * 
*              INTERACTIVE - POINTER TO TRANSMISSION BLOCK OR         * 
*                            NIL IF EMPTY TRANSMISSION BLOCK BUILT    * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PT4TPREL            RELEASE TEXT PROCESSING INFORMATION* 
*              PBGET1BF            GET A BUFFER                       * 
*              PBREL1BF            RELEASE A BUFFER                   * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*              PBRELZRO            RELEASE POSSIBLE CHAIN OF BUFFERS  * 
*              PBCLR               CLEAR AN AREA OF MEMORY            * 
*              PBFCOPY             COPY CHARACTERS INTO A BUFFER      * 
*              PTADDCHR            ADD CHARACTER INTO A BUFFER        * 
*              PTCHAIN             CHAIN BUFFER AT END OF BUFFER CHAIN* 
*              PTTPINF             TEXT PROCESSING INTERFACE          * 
*              PBQUEMAINT          MAINTAIN QUEUES                    * 
*              PTTPSVMRK           SAVE LAST LEVEL 1/2 MARKS FROM TP  * 
*              PTTPRSMRK           RESTORE LAST SAVED LEVEL 1/2 MARKS * 
*              PTTPUSREL           RELEASE UNMARKED TP SOURCE BUFFERS * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4TEXTPROCESS (VAR V6TBUF : B0BUFPTR); 
  
CONST 
      V4HDR    = 4;                         _STATE INDEX BUILD HEADER  ?
      V4DFCD   = 8;                         _FCD OF DESTINATION BUFFERS?
      V4LHDR   = 7;                         _LENGTH OF XPT HEADER      ?
      V4AESC   = $1B;                       _ESCAPE FOR ASCII          ?
      V4BESC   = $3E;                       _EXTERNAL BCD ESCAPE       ?
      V4E1     = $42;                       _E1                        ?
      V4E4     = $22;                       _E4                        ?
      V4ETX    = $03;                       _ETX CHARACTER             ?
      V4MCOMP  = $1F3F;                     _M4A MAX. SPACE COMP. EQUS ?
      V4BCOMP  = $0220;                     _M4A BASE SPACE COMP. EQUS ?
      V4TPMCP  = 9;                         _TPCB IDX. MAX. SPACE EQUS ?
      V4TPBCP  = 15;                        _TPCB IDX. BASE SPACE EQUS ?
      V4TPRMT  = 3;                         _FILE REG. PROMPT CHARACTER?
      V4TPLSR  = 4;                         _FILE REG. LINES REMAINING ?
      V4TPPGL  = 5;                         _FILE REG. PAGE LENGTH     ?
      V4TPEOL  = 6;                         _FILE REG. EOL SEQUENCE    ?
      V4TPSLK  = 10;                        _FILE REG. XMIT BLOCK SLACK?
      V4TPBLK  = 13;                        _FILE REG. BATCH BLANK CHAR?
      V4TPTTA  = 14;                        _FILE REG. BATCH XLATE TBL ?
  
TYPE
      V5SFLAG  = PACKED RECORD              _SOURCE FLAG WORD          ?
                 CASE V5X : INTEGER OF
                   1: (V5WORD : INTEGER);   _INTEGER OVERLAY           ?
                   2: (V5SP1  : B012BITS; 
                       V5FE   : BOOLEAN;    _FORMAT EFFECTORS PRESENT  ?
                       V5FRAG : BOOLEAN;    _SOURCE DATA IS FRAGMENTED ?
                       V5MSG  : BOOLEAN;    _SOURCE IS A MSG BLOCK     ?
                       V5SP2  : BOOLEAN); 
                 END; 
  
      V5DFLAG  = PACKED RECORD              _DESTINATION FLAG WORD     ?
                 CASE V5Y : INTEGER OF
                   1: (V5WORD : INTEGER);   _INTEGER OVERLAY           ?
                   2: (V5SP3  : B09BITS;
                       V5PM   : BOOLEAN;    _PM MESSAGE IN THIS BUFFER ?
                       V5EOI  : BOOLEAN;    _EOI IN THIS BUFFER        ?
                       V5EOR  : BOOLEAN;    _EOR IN THE BUFFER         ?
                       V5ACCT : BOOLEAN;    _ACCOUNTING DATA IN BUFFER ?
                       V5ETB  : BOOLEAN;    _END OF TRANSMISSION BLOCK ?
                       V5MPT  : BOOLEAN;    _THIS BUFFER EMPTY         ?
                       V5SP4  : BOOLEAN); 
                 END; 
  
      V5BADDR  = PACKED RECORD              _BUFFER ADDRESS            ?
                 CASE V5Z : INTEGER OF
                   1: (V5ADDR : B0BUFPTR);  _BUFFER POINTER OVERLAY    ?
                   2: (V5ASET : SETWORD);   _SETWORD OVERLAY           ?
                   3: (V5AINT : INTEGER);   _INTEGER OVERLAY           ?
                 END; 
  
VAR 
      V6TPCB   : B0BUFPTR;                  _POINTER TO TPCB           ?
      V6SBUF   : B0BUFPTR;                  _SOURCE BUFFER POINTER     ?
      V6DBUF   : B0BUFPTR;                  _DESTINATION BUFFER POINTER?
      V6FIRST  : B0BUFPTR;                  _FIRST BUFFER OF XMIT BLOCK?
      V6NEXT   : B0BUFPTR;                  _NEXT BUFFER TO INSPECT    ?
      V6LAST   : B0BUFPTR;                  _LAST BUFFER OF XMIT BLOCK ?
      V6ASCII  : BOOLEAN;                   _ASCII CODE SET FLAG       ?
      V6PRU    : BOOLEAN;                   _BATCH PRU SOURCE FILE FLAG?
      V6XLTA   : INTEGER;                   _BATCH XLATE TABLE ADDRESS ?
      V6CCNT   : INTEGER;                   _CHARACTER COUNT ON PAGE   ?
      V6DBC    : DBDBC;                     _DBC OF SOURCE             ?
      V6SFLAG  : V5SFLAG;                   _SOURCE FLAG WORD          ?
      V6DFLAG  : V5DFLAG;                   _DESTINATION FLAG WORD     ?
      V6ADR1   : V5BADDR;                   _BUFFER ADDRESS 1          ?
      V6ADR2   : V5BADDR;                   _BUFFER ADDRESS 2          ?
      V6XPTHDR : PACKED ARRAY [1..V4LHDR]   _CANNED HEADER FOR XPT DATA?
                   OF INTEGER;
      V6LCDFCD : ARRAY [BOOLEAN] OF INTEGER;_LCD AND FCD FOR PBFCOPY   ?
      V6IEOL   : ARRAY [BOOLEAN] OF INTEGER;_END OF LINE CHARS INTER.  ?
      V6BEOL   : ARRAY [BOOLEAN] OF INTEGER;_END OF LINE CHARS BATCH   ?
      V6BLANK  : ARRAY [BOOLEAN] OF INTEGER;_BATCH BLANK CHARACTER     ?
      V6SINGLE : PACKED ARRAY [BOOLEAN]     _BATCH SINGLE SPACE CC     ?
                   OF CHAR; 
  
VALUE 
      V6XPTHDR = ($0000,
                  $1616,$1616,$1601,$0000,$111B,$2900); 
      V6LCDFCD = ($0A02,$0C02); 
      V6IEOL   = ($3E41,$1B41); 
      V6BEOL   = ($3E50,$1B40); 
      V6BLANK  = ($20,$2D); 
      V6SINGLE = ($5020); 
  
BEGIN 
WITH V6TCBP'.BSTCB DO                       _SET INDEX TO TCB          ?
  BEGIN 
_ 
* * * *   SAVE INFORMATION FROM THE SOURCE BUFFERS
? 
  V6SBUF := V6TBUF;                         _PICK UP SOURCE BUFFER PTR ?
  V6ASCII := BSCODE = N0ASCII;              _SET ASCII FLAG            ?
  WITH V6SBUF' DO                           _SET INDEX TO THE SOURCE   ?
    BEGIN 
    IF BS4PSOURCE = V6SBUF                  _FRAGMENT OF PREVIOUS SRCE ?
    THEN
      BEGIN 
      V6SFLAG.V5WORD := BIINT [2];          _PICK UP SOURCE FLAGS      ?
      V6BLKTYPE      := HTMSG;              _DEFAULT BLOCK TYPE TO MSG ?
      V6DBC.DBCHAR := CHR ($0);             _CLEAR THE LOCAL DBC CHAR. ?
      END 
    ELSE
      BEGIN 
      V6DBC.DBCHAR   := BFDATAC [DBC];      _PICK UP THE DBC FROM BFR  ?
      BFFCD          := DATA + 1;           _SET FCD TO START OF DATA  ?
      IF BSBATCH = FALSE                    _INTERACTIVE DEVICE        ?
      THEN
        BEGIN 
        V6SFLAG.V5WORD := 0;                _CLEAR SOURCE FLAG WORD    ?
        V6SFLAG.V5FE   := NOT V6DBC.DBDLFE; _SET IF FORMAT EFFECTORS   ?
        V6SFLAG.V5MSG  := V6BLKTYPE = HTMSG;_SET IF MSG BLOCK          ?
        IF V6DBC.DBDLXPT
        THEN                                _TRANSPARENT DATA          ?
_ 
* * * *   TRANSPARENT INTERACTIVE DATA, TEXT PROCESS AT THE PASCAL LEVEL
? 
          BEGIN 
          V6XPTHDR [1] :=                   _SET LCD, FCD FOR PBFCOPY  ?
            V6LCDFCD [BSTCLASS = N071430];
          ADDR (V6XPTHDR, V6NEXT);          _SET SOURCE BUFFER POINTER ?
          V6FIRST := NIL;                   _HAVE PBFCOPY GET THE BFR  ?
          PBFCOPY (V6NEXT, V6FIRST);        _COPY TRANSPARENT HEADER   ?
          PTCHAIN (V6SBUF, V6FIRST);        _CHAIN SOURCE TO HEADER    ?
          IF BS4CCBPTR'.BVCCB.BVM4A         _IF MODE 4A                ?
          THEN
            BEGIN 
            IF V6ASCII                      _ IF ASCII                 ?
            THEN
              BEGIN 
              PTADDCHR(CHR(V4AESC),V6SBUF); _ADD ESCAPE CHARACTER      ?
              PTADDCHR(CHR(V4E4),V6SBUF);   _ADD E4                    ?
              END 
            ELSE
              BEGIN 
              PTADDCHR(CHR(V4BESC),V6SBUF); _ADD ESCAPE CHARACTER      ?
              PTADDCHR(CHR(V4E1),V6SBUF);   _ADD E1                    ?
              END;
          END;
          IF V6SFLAG.V5MSG                  _MSG BLOCK BEING PROCESSED ?
          THEN
            BEGIN 
            BS4XPTURN := BSPGWAIT;          _INPUT REQUIRED IF PAGE WT ?
            IF BSPACER " 0                  _SIMULATED TERMINAL        ?
            THEN                            _STORE PROMPT CHARACTER    ?
              PTADDCHR (CHR(BSPACER), V6SBUF);
            END; _IF V6SFLAG.V5MSG THEN?
          PTADDCHR (CHR(V4ETX), V6SBUF);    _STORE ETX CHARACTER       ?
          V6TBUF := V6FIRST;                _RETURN XMIT BLOCK POINTER ?
          GOTO 999;                         _EXIT TEXT PROCESSING      ?
          END _IF V6DBC.DBDLXPT THEN? 
        ELSE
_ 
* * * *   NON TRANSPARENT INTERACTIVE DATA, CHECK FOR EMPTY SOURCE
? 
          BEGIN                             _NON TRANSPARENT DATA      ?
          IF BFLCD < DATA + 1               _EMPTY SOURCE BUFFER       ?
          THEN
            IF BSPACER = 0                  _NOT SIMULATED TERMINAL    ?
            THEN
              BEGIN 
              PBREL1BF (V6TBUF, BEDBSIZE);  _DISCARD SOURCE BUFFER     ?
              GOTO 999;                     _BYPASS TEXT PROCESSING    ?
              END 
            ELSE
            BEGIN 
            IF V6SFLAG.V5FE                 _FORMAT EFFECTORS PRESENT  ?
            THEN                            _INSERT NO ACTION FE       ?
              PTADDCHR (CHR(I9FNA), V6SBUF);
            PTADDCHR (CHR(I9US), V6SBUF);   _INSERT UNIT SEPARATOR     ?
            END;
          END; _IF V6DBC.DBDLXPT ELSE?
        END; _IF BSBATCH = FALSE THEN?
      END; _IF BS4PSOURCE = V6SBUF ELSE?
    END; _WITH V6SBUF' DO?
  V6TPCB  := BS4TPCB;                       _GET POINTER TO TPCB       ?
  IF V6TPCB = NIL                           _NO TPCB ALREADY EXISTS    ?
  THEN
    BEGIN 
_ 
* * * *   NO TPCB ASSIGNED, GET ONE AND PRE-INITIALIZE IT 
? 
    V6TPCB  := PBGET1BF (BETPSIZE);         _GET A BUFFER FOR THE TPCB ?
    BS4TPCB := V6TPCB;                      _INSERT PTR TO IT IN TCB   ?
    PBCLR (V6TPCB, TPBUFLEN);               _CLEAR THE TPCB            ?
    WITH V6TPCB'.BGMLCB DO                  _SET INDEX TO TPCB         ?
      BEGIN 
      NCSTAI := V4HDR;                      _FIRST STATE BUILD HEADER  ?
      NCBFCD := V4DFCD;                     _FCD OF DESTINATION BUFFERS?
      NCUOP1 := V6ASCII;                    _SET IF ASCII CODE SET     ?
      NCUOP2 := NOT BS4CCBPTR'.BVCCB.BVM4A; _SET IF MODE 4B OR 4C      ?
      IF BSBATCH                            _BATCH DEVICE              ?
      THEN
        BEGIN 
        NCBLKL := BSXBZ;                    _TRANSMISSION BLOCK SIZE   ?
        NCSCHR := V6SINGLE [V6ASCII];       _SET SINGLE SPACE CC CHAR  ?
        NCTPML [V4TPMCP] := V4MCOMP;        _SET MAX. COMP COUNT / CHAR?
        NCTPML [V4TPBCP] := V4BCOMP;        _SET BASE COMP COUNT / CHAR?
        NCTPF1 [V4TPSLK] := BSPGWIDTH / 2;  _SET XMIT BLOCK SIZE SLACK ?
        NCTPF1 [V4TPEOL] := V6BEOL [V6ASCII]; _SET END OF LINE CHARS   ?
        END _IF BSBATCH THEN? 
      ELSE                                  _INTERACTIVE DEVICE        ?
        NCTPF1 [V4TPEOL] := V6IEOL [V6ASCII]; _SET END OF LINE CHARS   ?
      END; _WITH V6TPCB'.BGMLCB DO? 
    END _IF V6TPCB = NIL THEN?
  ELSE
_ 
* * * *   TPCB ALREADY ASSIGNED, RESTORE SAVED -TPMARK- POINTERS
? 
    PTTPRSMRK (BS4MARK, FALSE);             _RESTORE SAVED MARKS FOR TP?
_ 
* * * *   INITIALIZE VARIANT PART OF TPCB PRIOR TO EACH -PTTPINF- CALL
? 
  WITH V6TPCB'.BGMLCB DO                    _SET INDEX TO TPCB         ?
    BEGIN 
    IF BSBATCH                              _BATCH DEVICE              ?
    THEN
_ 
* * * *   BATCH INITIALIZATION
? 
      BEGIN 
      IF V6SBUF'.BFLCD < DATA + 1           _EMPTY SOURCE BUFFER       ?
      THEN
        IF NCFSBA " NIL                     _AND SOME LEFT OVER SOURCE ?
        THEN
          PBRELCHN (V6SBUF, BEDBSIZE);      _RELEASE THE EMPTY SOURCE  ?
      PTCHAIN (V6SBUF, NCFSBA);             _CHAIN NEW SOURCE TO OLD   ?
      NCUOP3  := V6DBC.DBBEOI;              _SET IF EOI IN THIS BLOCK  ?
      NCUOP7  := V6DBC.DBBEOR & BS4LPEOF;   _SET IF EOF SIGNAL AT EOI  ?
      NCUOP4  := BSSUPCC;                   _SET IF SUPPRESSING CC     ?
      V6PRU   := BSFTYPE " B9ASCII;         _SAVE PRU SOURCE FILE FLAG ?
      V6XLTA  := V6OBCXLTA [V6PRU, V6ASCII];_GET TRANSLATION TABLE ADDR?
      IF V6PRU = FALSE                      _ASCII SOURCE FILE         ?
      THEN
        IF V6ASCII                          _AND DEVICE USES ASCII CODE?
        THEN
          IF BSSUBDT " B9ASC96              _AND FOLDING REQUIRED      ?
          THEN
            ADDR (ASKFLD, V6XLTA);          _USE FOLDING TRANSLATE TBL ?
      NCCXLTA          := V6XLTA;           _STORE XLATE TBL IN TPCB   ?
      NCTPF1 [V4TPTTA] := V6XLTA;           _AND IN FILE REGISTER      ?
      IF NCUOP2                             _MODE 4C PRINTER           ?
      THEN
        BEGIN 
        NCUOP5  := BS4LPIP;                 _SET IF M4C IMPACT PRINTER ?
        NCUOP6  := BSPGLENGTH " 0;          _SET IF PAGING ACTIVE      ?
        NCSPTA  := V6CBTPSPT [V6PRU];       _SET UP STATE POINTER TABLE?
        END _IF NCUOP2 THEN?
      ELSE
        NCSPTA  := V6ABTPSPT [V6PRU];       _SET UP STATE POINTER TABLE?
      NCTPF1 [V4TPBLK] := V6BLANK [V6PRU];  _SET SOURCE BLANK CHARACTER?
      NCTPF1 [V4TPPGL] := BSPGLENGTH;       _SET PAGE LENGTH           ?
      END _IF BSBATCH THEN? 
    ELSE
_ 
* * * *   INTERACTIVE INITIALIZATION
? 
      BEGIN 
      NCFSBA  := V6SBUF;                    _SET FIRST SOURCE BFR ADDR ?
      NCUOP3  := V6SFLAG.V5MSG;             _SET IF MSG BLOCK          ?
      NCUOP4  := V6SFLAG.V5FE;              _SET IF FORMAT EFFECTORS   ?
      NCUOP5  := V6SFLAG.V5FRAG;            _SET IF FRAGMENTED DATA    ?
      NCUOP6  := BSPGWAIT &                 _SET IF PAGING IN EFFECT   ?
                (BSPGLENGTH " 0); 
      NCUOP7  := TRUE;                      _SET START OF XMIT BLOCK   ?
      ADDR (MD4ITP, NCSPTA);                _SET UP STATE POINTER TABLE?
      NCCXLTA := V6OICXLTA [V6ASCII];       _SET TRANSLATE TABLE ADDR  ?
      IF BSPACER " 0                        _SIMULATED TERMINAL        ?
      THEN
        BEGIN 
        NCUOP8 := TRUE;                     _SET SIMULATED TERMINAL FLG?
        NCTPF1 [V4TPRMT] := BSPACER;        _SET UP PROMPT CHARACTER   ?
        END; _IF BSPACER " 0 THEN?
      IF NCUOP6                             _PAGING IN EFFECT          ?
      THEN
        BEGIN 
        V6CCNT := BSPGLENGTH*BSPGWIDTH;     _CALCULATE CHARACTERS      ?
        IF BSXBZ  \ V6CCNT                  _IF TRANSMISSION SIZE .GT. ?
        THEN                                _PAGE SIZE, USE PAGE SIZE  ?
          NCTPF1[V4TPPGL]  := BSPGLENGTH - 1  _MINUS ONE               ?
        ELSE
          NCTPF1[V4TPPGL] := BSXBZ/BSPGWIDTH - 1  _ USE XBZ SIZE       ?
        END 
      ELSE
        BEGIN                               _PAGING NOT IN EFFECT      ?
        NCTPF1 [V4TPPGL] :=                 _STORE LINES IN XMIT BLOCK ?
          BSXBZ / BSPGWIDTH - 1;
        BS4LCOUNT := NCTPF1 [V4TPPGL];      _AND LINES REMAINING       ?
        END; _IF NCUOP6 ELSE? 
      END; _IF BSBATCH ELSE?
_ 
* * * *   COMPLETE INITIALIZATION, AND DIVE INTO TEXT-PROCESSING
? 
    NCCNTL := BSPGWIDTH;                    _SET PAGE WIDTH            ?
    IF BS4LCOUNT = 0                        _AT END OF PAGE            ?
    THEN                                    _RESET LINE COUNTER        ?
      BS4LCOUNT := NCTPF1 [V4TPPGL];
    NCTPF1 [V4TPLSR] := BS4LCOUNT;          _SET REMAINING LINES ON PGE?
    PTTPINF (V6TPCB');                      _ESCAPE TO FIRMWARE FOR TP ?
    V6DBUF := NCFDBA;                       _PICK UP FIRST DESTN BFR   ?
    IF BSBATCH                              _BATCH DEVICE              ?
    THEN
_ 
* * * *   FOR BATCH DATA, UNRAVEL THE BUFFERS INTO TRANSMISSION BLOCKS
? 
      BEGIN 
      V6FIRST := V6DBUF;                    _SET FIRST BFR OF XMIT BLK ?
      V6NEXT  := V6DBUF;                    _SET NEXT BFR TO INSPECT   ?
      V6LAST  := V6DBUF;                    _SET LAST BFR OF XMIT BLK  ?
      WHILE V6NEXT " NIL DO                 _MORE BUFFERS TO INSPECT   ?
        BEGIN 
        V6DFLAG.V5WORD := V6NEXT'.BIINT [2];_PICK UP FLAG WORD OF BFR  ?
        IF V6DFLAG.V5ETB                    _END OF TRANSMISSION BLOCK ?
        THEN
          BEGIN 
          IF V6DFLAG.V5ACCT                 _ACCOUNTING INFORMATION    ?
          THEN
            BEGIN 
            V6FIRST'.BIINT [4] :=           _STORE INFO IN FIRST BFR   ?
              V6NEXT'.BIINT [5];
            PBREL1BF (V6NEXT, BEDBSIZE);    _RELEASE OLD ACCOUNTING BFR?
            END 
          ELSE
            BEGIN                           _NOT ACCOUNTING INFORMATION?
            V6LAST := V6NEXT;               _PM MESSAGE OR EMPTY BFR   ?
            V6NEXT := V6NEXT'.BCCHAINS      _UPDATE NEXT BFR TO INSPECT?
                        [DBUFLENGTH]; 
            END; _IF V6DFLAG.V5ACCT ELSE? 
          V6LAST'.BCCHAINS [DBUFLENGTH] :=  _CLEAR CHAIN WORD LAST BFR ?
            NIL;
          IF V6DFLAG.V5MPT                  _EMPTY BUFFER (NO XMIT BLK)?
          THEN
            PBRELCHN (V6FIRST, BEDBSIZE)    _RELEASE THE EMPTY BUFFER  ?
          ELSE
            BEGIN                           _HAVE A XMIT BLK TO QUEUE  ?
            V6FIRST'.BF4LPTP := TRUE;       _DECLARE BLK TEXT PROCESSED?
            PBQUEMAINT (V6TCBP, V6FIRST,    _PLACE BLK IN TCB OUTPUT Q ?
                        K4PUT); 
            END; _IF V6DFLAG.V5MPT ELSE?
  
          V6FIRST := V6NEXT;                _SET FIRST OF POSS NEW XMIT?
  
          END _IF V6DFLAG.V5ETB THEN? 
        ELSE
          BEGIN 
          V6LAST := V6NEXT;                 _UPDATE LAST OF XMIT BLK   ?
          V6NEXT := V6NEXT'.BCCHAINS        _INSPECT NEXT BFR IN CHAIN ?
                      [DBUFLENGTH]; 
          END; _IF V6DFLAG.V5ETB ELSE?
        END; _WHILE V6NEXT " NIL DO?
_ 
* * * *   FOR BATCH DATA, PUT ANY LEFT OVER DESTINATION BACK IN TPCB
? 
      NCFDBA := V6FIRST;                    _INSERT POSS PTR TO XMIT BK?
      IF V6FIRST = NIL                      _NO INCOMPLETE XMIT BLK    ?
      THEN
        BEGIN 
        NCDBP  := NIL;                      _CLEAR CURRENT DESTINATION ?
        NCSTAI := V4HDR;                    _SET STATE TO BUILD HEADER ?
        END; _IF NCFDBA = NIL THEN? 
_ 
* * * *   FOR BATCH DATA, PROCESS EOI CONDITION 
? 
      IF NCUOP3                             _EOI DETECTED              ?
      THEN
        BEGIN 
        BS4LCOUNT := 0;                     _RESET LINE COUNT          ?
        PT4TPREL;                           _RELEASE ALL TP BUFFERS    ?
        V6DBUF := PBGET1BF (BEDBSIZE);      _GET A BUFFER FOR EOI      ?
        V6DBUF'.BIINT [BTWD] := 0;          _CLEAR BLOCK TYPE (ACCTING)?
        END 
      ELSE
        BEGIN                               _EOI NOT FOUND             ?
        BS4LCOUNT := NCTPF1 [V4TPLSR];      _SAVE LINES REMAINING      ?
        PTTPSVMRK (BS4MARK);                _SAVE TP MARKS             ?
        PTTPUSREL (V6TPCB, BS4MARK, 1);     _RELEASE UNMARKED LVL1 SRC ?
        V6DBUF := NIL;                      _PASS NOTHING BACK TO BIP  ?
        END; _IF NCUOP3 ELSE? 
  
      END _IF BSBATCH THEN? 
    ELSE
_ 
* * * *   FOR INTERACTIVE DATA, RELEASE THE TEXT-PROCESSED SOURCE 
? 
      BEGIN 
      V6NEXT        := V6SBUF;              _GET FIRST SOURCE BUFFER   ?
      V6ADR1.V5ADDR := NCSBP;               _GET RAW CURRENT SOURCE PTR?
      V6ADR2.V5ASET := V6ADR1.V5ASET -      _GET BASE ADDRESS OF REST  ?
                       BEDBSIZE'.BEMSK.     _OF SOURCE                 ?
                       BASET; 
      V6SBUF        := V6ADR2.V5ADDR; 
      IF NCEOSR                             _END OF BUFFER BOUNDARY    ?
      THEN
        V6SBUF := V6SBUF'.BCCHAINS          _YES, CHAIN TO NEXT BUFFER ?
                  [DBUFLENGTH]
      ELSE
        V6SBUF'.BFFCD :=                    _NO,  CALCULATE THE FCD    ?
          ((V6ADR1.V5AINT - 
            V6ADR2.V5AINT) * 2 +
            ORD (NCRIGHTC)) - 1;
      WHILE V6NEXT " V6SBUF DO              _RELEASE TEXT-PROCESSED    ?
        PBREL1BF (V6NEXT, BEDBSIZE);        _SOURCE BUFFERS            ?
_ 
* * * *   FOR INTERACTIVE DATA, SAVE ANY LEFT OVER SOURCE DATA
? 
      IF V6BLKTYPE " V4B4AUNL               _NOT MODE 4A UNLOCK        ?
      THEN
        BEGIN 
        BS4LCOUNT  := NCTPF1 [V4TPLSR];     _SAVE LINES REMAINING      ?
        IF BS4LCOUNT = 0                    _FILLED COMPLETE PAGE      ?
        THEN
          BS4PGTURN := NCUOP6;              _PAGE TURN REQ IF PAGE WAIT?
        BS4PSOURCE := V6NEXT;               _PLACE ANY LEFT OVER IN TCB?
        IF V6NEXT " NIL                     _PARTIAL SOURCE LEFT OVER  ?
        THEN
          BEGIN 
          BS4PGTURN         := NCUOP6;      _PAGE TURN REQUIRED MAYBE  ?
          V6SFLAG.V5FRAG    := NCUOP5;      _MIGHT BE FRAGMENTED SOURCE?
          V6NEXT'.BIINT [2] := V6SFLAG.V5WORD;
          END;
        END; _IF V6BLKTYPE " V4B4AUNL THEN? 
      IF NCUOP7                             _XMIT BLOCK IS EMPTY       ?
      THEN
        PBRELZRO (V6DBUF, BEDBSIZE);        _RELEASE THE EMPTY BLOCK   ?
      PBREL1BF (BS4TPCB, BETPSIZE);         _RELEASE THE TPCB          ?
      END; _IF BSBATCH ELSE?
_ 
* * * *   RETURN ADDRESS OF DATA TO QUEUE, OR TRANSMIT
? 
    V6TBUF := V6DBUF;                       _RETURN RESULT TO CALLER   ?
    END; _WITH V6TPCB'.BGMLCB DO? 
  END; _WITH V6TCBP'.BSTCB DO?
  
999:                                        _TRANSPARENT DATA EXIT     ?
END; _PROCEDURE PT4TEXTPROCESS? 
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 S C A N                                       * 
*                                                                     * 
*       PREVIEW OUTPUT DATA AND COMMANDS                              * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE IS CALLED BY BIP PRIOR TO THE QUEUING     * 
*              OF OUTPUT IN THE TCB. ONLY DATA AND COMMANDS FOR       * 
*              PRINTER DEVICES ARE IMMEDIATELY PROCESSED.             * 
*                                                                     * 
** INPUT -     TCB ADDRESS                                            * 
*              BUFFER ADDRESS                                         * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              BIP                 BLOCK INTERFACE PROGRAM            * 
*                                                                     * 
** OUTPUT -    BUFFER ADDRESS TO QUEUE                                * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PTMODE4TIP          MODE 4 WORKLIST PROCESSOR          * 
*              PT4TEXTPROCESS      MODE 4 OUTPUT TEXT PROCESSOR       * 
*              PBRELCHN            RELEASE A CHAIN OF BUFFERS         * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4SCAN (V6TCBB : B0BUFPTR; VAR V6BUFB : B0BUFPTR); 
  
BEGIN 
V6TCBP := V6TCBB;                           _SET GLOBAL TCB POINTER    ?
IF V6TCBP'.BSTCB.BS4STATE < V4DRECOVER      _DEVICE IS ALIVE AND WELL  ?
THEN
  BEGIN 
  IF V6TCBP'.BSTCB.BSDEVTYPE = N1LP         _ONLY PROCESS FOR PRINTERS ?
  THEN
    BEGIN 
    V6BLKTYPE := V6BUFB'.BIINT [BTWD];      _SET GLOBAL BLOCK TYPE     ?
    IF V6BLKTYPE \ HTCMD                    _COMMAND OR ICMD BLOCK     ?
    THEN
_ 
* * * *   DOWNLINE PRINTER COMMAND, CALL MAIN TIP DIRECTLY
? 
      BEGIN 
      WITH BWWLENTRY [OPS].B0EWLQ DO        _OPS LVL INTERMEDIATE ARRAY?
        BEGIN 
        MMWKCODE := V4WKDLCMD;              _WORK CODE FOR THE TIP     ?
        MMLINO   := V6TCBP'.BSTCB.          _LINE NUMBER               ?
                    BSLCBP'.BZLINO.BDLINO;
        MMIBP    := V6BUFB;                 _COMMAND BUFFER POINTER    ?
        END; _WITH BWWLENTRY [OPS].B0EWLQ DO? 
      PTMODE4TIP;                           _CALL THE TIP DIRECTLY     ?
      V6BUFB := NIL;                        _TIP RELEASES THE BUFFER   ?
      END _IF V6BLKTYPE \ HTCMD THEN? 
    ELSE
_ 
* * * *   DOWNLINE PRINTER DATA, PRE-TEXTPROCESS THE DATA 
? 
      PT4TEXTPROCESS (V6BUFB);              _GO TEXT PROCESS THE OUTPUT?
    END; _IF V6TCBP'.BSTCB.BSDEVTYPE = N1LP THEN? 
  END _IF V6TCBP'.BSTCB.BS4STATE < V4DRECOVER?
ELSE
  PBRELCHN (V6BUFB, BEDBSIZE);              _RELEASE THE BUFFER(S)     ?
END; _PROCEDURE PT4SCAN?
_$J+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
*                 P T 4 M U X L E V E L                               * 
*                                                                     * 
*       MODE 4 MUX LEVEL TIP                                          * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
*                                                                     * 
** OVERVIEW -  THIS ROUTINE HANDLES THE WORKLISTS FROM THE            * 
*              MUX SUBSYSTEM BY PASSING THEM ON TO THE OPS LEVEL TIP. * 
*                                                                     * 
** INPUT -     WORKLISTS FROM THE MUX SUBSYSTEM                       * 
*                                                                     * 
** CALLING PROGRAMS -                                                 * 
*              PMWOLP              MUX SYSTEM WORKLIST PROCESSOR      * 
*                                                                     * 
** OUTPUT -    WORKLISTS TO MODE 4 OPS LEVEL TIP                      * 
*                                                                     * 
** EXTERNAL SUBROUTINES -                                             * 
*              PBLSPUT             MAKE A WORKLIST ENTRY              * 
*                                                                     * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
? 
PROCEDURE PT4MUXLEVEL;
  
BEGIN 
PBLSPUT (BWWLENTRY [MUX2],                  _PASS WORKLIST TO OPS TIP  ?
         BYWLCB [B0M4WL]);
  
END; _PROCEDURE PT4MUXLEVEL?
