       ASB,HEX        ;MPTS2 11/10/76 1200 HRS  MP
; 
; 
; 
; 
;  COMMON EQUATES - CM34 - 6/10/76 - 1315 HRS.
; 
FSTRAM EQU  110400Q   ;FAST RAM LOWER LIMIT 
;***************************************
; KBDCSW - KEYBOARD DATA COMM SWITCHES *
;***************************************
FULDUP EQU  200Q      ;HALF/FULL DUPLEX 
;************************************** 
; KBJMPR - KEYBOARD INTERFACE JUMPERS * 
;************************************** 
; 
;  JUMPERS SENSED AS 0' WHEN INSERTED 
; 
;  ALL JUMPERS ARE NORMALLY INSERTED
; 
CONDIS EQU 001Q     ;CONTROL CODE DISABLE 
;                     (0=DISABLED)
SPLDIS EQU 002Q     ;SPOW LATCH DISABLE 
;                     (0=DISABLED)
LINWRP EQU 004Q     ;COLUMN 80 AUTO CR,LF 
;                     (0=ENABLED) 
PAGSTR EQU 010Q     ;PAGE MODE STRAP
;                     (0=LINE-FIELD MODE) 
LFPOS  EQU 20Q      ;LINE FEED POSITION 
;                     (0 = POSITION LINE FEED 
;                         AT START OF NEXT I/O
;                         READ
;                      1 = PUT LINE FEED AT END 
;                         OF RECORD)
FSTSND EQU 40Q      ;9600 BAUD DATACOM SHIFT
;                     (0=9600 BAUD FOR ESC,E) 
HNDSHK EQU 100Q     ;BLOCK TRANSFER HANDSHAKE 
;                     (0 = FOLLOW DC2SND SETTING
;                      1 = SEND DC2 BEFORE DATA)
DC2SND EQU 200Q 
;                     (0 = SEND DC2 ON ENTER
;                          AND FUNCTION KEY IN
;                          BLOCK MODE 
;                      1 = INHIBIT ALL DC2
;                          HANDSHAKE) 
 
;****************************************** 
; KBJMP2 - SECOND SET OF KEYBOARD JUMPERS * 
;****************************************** 
AUTTRM EQU  1Q        ;AUTO TERMINATE ON "ENTER"
CLRTRM EQU  2Q        ;CLEAR TERMINATOR ON TRANSMI
NOTEST EQU  4Q        ;INHIBIT TERMINAL SELF-TEST 
EDTWRP EQU  10Q       ;INVERT SENSE OF EDIT WRAP
PRNTAL EQU  20Q       ;SEND ALL CODES TO PRINTER
DCJMP0 EQU  200Q      ;DATA COMM JUMPER 
;*****************************************
; KBJMP3 - THIRD SET OF KEYBOARD JUMPERS *
;*****************************************
DCJMP1 EQU  1Q        ;DATA COMM JUMPERS
DCJMP2 EQU  2Q              ;.
DCJMP3 EQU  4Q              ;.
DCJMP4 EQU  10Q             ;.
NODCST EQU  20Q       ;INHIBIT DATA COMM SELF-TEST
;                       (0 = DISABLED)
SETCH  EQU  40Q       ;TURN ON "CH" CONTROL LINE
;                       (0 = OFF, 1 = ON) 
CHEKCC EQU  100Q      ;MONITOR CC CONTROL LINE
;                       (1 = ENABLED) 
FRCPTY EQU  200Q      ;FORCE PARITY ON/NO IN CHECK
;                       (1 = ENABLED) 
;************************ 
; CMFLGS - COMMON FLAGS * 
;************************ 
BLKTRG EQU  1Q        ;BLOCK TRANSFER TRIGGER 
INSWRP EQU  2Q        ;INSERT WITH WRAP AROUND
FRCRST EQU  4Q        ;FORCE FULL TERMINAL RESET
DEFSKY EQU  10Q       ;DEFINE SOFT KEY MODE ENABLE
REMSET EQU  20Q       ;REMOTE MODE ENABLED
RCVMDE EQU  40Q       ;TERMINAL IN RECEIVE MODE 
;***********************
; ERRFLG - ERROR FLAGS *
;***********************
DCMERR EQU  1Q        ;DATACOM (1 = ERROR)
TESTOK EQU  2Q        ;SELF-TEST (0 = ERROR)
LDRCHK EQU  4Q        ;LOADER CHECKSUM (0 = ERROR)
;************************** 
; INTFLG - INTERRUPT FLAG * 
;************************** 
TMRINT EQU  3         ;TIMER INTERRUPT
 
;***********************************
; PRCCTL - PROCESSOR CONTROL FLAGS *
;***********************************
TMIACK EQU  0Q        ;ACKNOWLEDGE TIMER INTERRUPT
;                       (BIT 1 OFF) 
TMRON  EQU  1Q        ;SET TIMER ON 
TMIEN  EQU  2Q        ;RE-ENABLE TIMER INTERRUPT
DCIOFF EQU  20Q       ;DISABLE DATA COMM INTERRUPT
TMIOFF EQU  40Q       ;DISABLE TIMER INTERRUPTS 
POLL   EQU  100Q      ;POLL CTU INTERRUPTS
;V*V*V*V*  SET TO ZERO FOR ROM VERSION  *V*V*V*V* 
SETROM EQU  200Q      ;DISABLE (1)/ENABLE (0) ROM 
;*********************************
; MDFLG1 - TERMINAL MODE FLAGS 1 *
;*********************************
DSPFNC EQU  1Q        ;DISPLAY FUNCTIONS ENABLED
INSCHR EQU  2Q        ;INSERT CHARACTER ENABLED 
MEMLOK EQU  4Q        ;MEMORY LOCK ENABLED
FORMAT EQU  10Q       ;FORMAT MODE ENABLED
EDIT   EQU  20Q       ;EDIT MODE ENABLED
SELECT EQU  40Q       ;SELECT MODE ENABLED
RECORD EQU  100Q      ;RECORD MODE ENABLED
FORGN  EQU  200Q      ;FOREIGN MODE ENABLED 
;*********************************
; MDFLG2 - TERMINAL MODE FLAGS 2 *
;*********************************
CAPSLK EQU  1Q        ;CAPS LOCK ENABLED
BLKMDE EQU  2Q        ;BLOCK MODE ENABLED 
AUTOLF EQU  4Q        ;AUTO LF ENABLED
REMOTE EQU  10Q       ;REMOTE ENABLED 
WBSR   EQU  40Q       ;WRITE-BACKSPACE-READ MODE
;********************************************** 
; RADIX - BASE OF INPUT PARAMETER FOR ESC SEQ * 
;********************************************** 
DECRDX EQU  10        ;DECIMAL NUMBERS
OCTRDX EQU  8         ;OCTAL NUMBERS
 
;*******************
; COMMON VARIABLES *
;*******************
INTVEC EQU  FSTRAM+145Q  ;CENTRAL INTERRUPT VECTOR
SCNVEC EQU  INTVEC+3  ;FOREIGN TERMINAL DISPLY SCA
; 
COMMON EQU  177777Q   ;UPPER LIMIT OF COMMON AREA 
CMBASE EQU  COMMON/256  ;MSB OF COMMON ADDRESSES
CMSTOR EQU  CMBASE*256  ;MSB ADJUSTMENT FACTOR
; 
DISPST EQU  COMMON-1  ;DISPLAY REFRESH START PTR
TRMTYP EQU  DISPST-1  ;TERMINAL TYPE NUMBER 
KBDCSW EQU  TRMTYP-1  ;KEYBOARD DATACOM SWITCHES
KBJMPR EQU  KBDCSW-1  ;KEYBOARD STRAPS
KBJMP2 EQU  KBJMPR-1    ;SET 2
KBJMP3 EQU  KBJMP2-1    ;SET 3
CMFLGS EQU  KBJMP3-1  ;COMMON FLAGS 
ERRFLG EQU  CMFLGS-1  ;ERROR FLAGS
INTFLG EQU  ERRFLG-1  ;INTERRUPT FLAG 
PRCCTL EQU  INTFLG-1  ;PROCESSOR CONTROL FLAGS
MDFLG1 EQU  PRCCTL-1  ;TERMINAL MODE FLAGS 1
MDFLG2 EQU  MDFLG1-1    ;AND 2
MSGPT1 EQU  MDFLG2-2  ;MESSAGE POINTERS 
MSGPT2 EQU  MSGPT1-2       ;. 
MSGPT3 EQU  MSGPT2-2       ;. 
MSGPT4 EQU  MSGPT3-2       ;. 
MSGPT5 EQU  MSGPT4-2       ;. 
MSGPT6 EQU  MSGPT5-2       ;. 
MSGPT7 EQU  MSGPT6-2       ;. 
MSGPT8 EQU  MSGPT7-2       ;. 
CTIVEC EQU  MSGPT8-2  ;CTU INTERRUPT VECTOR 
CTIJMP EQU  CTIVEC-1  ;JUMP CODE FOR VECTOR 
IODATA EQU  CTIJMP-2  ;ESQ SEQ PARM ACCUMULATOR 
IOCSGN EQU  IODATA-1  ;SIGN FOR PARAMETER 
IOPSGN EQU  IOCSGN-1  ;PARAMETER SIGN 
PARM1  EQU  IOPSGN-1  ;ESCAPE SEQUENCE PARAMETERS 
PARM2  EQU  PARM1-1        ;. 
PARM3  EQU  PARM2-1        ;. 
PARM4  EQU  PARM3-1        ;. 
PARM5  EQU  PARM4-1        ;. 
PARM6  EQU  PARM5-2        ;. 
RADIX  EQU  PARM6-1   ;RADIX OF PARAMETERS
RNGTA  EQU  RADIX-2   ;CHAR FUNCTION TABLE ADDRESS
ESCFLG EQU  RNGTA-1   ;ESCAPE SEQUENCE FLAG 
;                       = 0, NOT IN ESCAPE SEQ
;                       # 0, ESC SEQ IN PROGRESS
RSTTMR EQU  ESCFLG-1  ;SOFT RESET TIMER 
; * * * * * * * * * * * * * * * * * * * * * * * * 
;  END OF COMMON EQUATES                        * 
;^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^* 
 
;*********************************
; KEYBOARD ENTRY VECTOR POINTERS *
;*********************************
ZKBBAS EQU  44000Q    ;KEYBOARD START ADDRESS 
ZINIKB EQU  ZKBBAS+2  ;INIT KB VECTORS  TO ROM +2 
ZGETKY EQU  ZINIKB+3  ;GET KEYBOARD KEY 
ZKBCTL EQU  ZGETKY+3  ;PERFORM KEYBOARD CONTROL 
ZKBMON EQU  ZKBCTL+3  ;MONITOR KEYBOARD 
ZSTMD1 EQU  ZKBMON+3  ;SET MODE 1 FLAGS 
ZCLMD1 EQU  ZSTMD1+3  ;CLEAR MODE 1 FLAGS 
ZBELL  EQU  ZCLMD1+3  ;SOUND THE BELL 
ZSTXMT EQU  ZBELL+3   ;TURN ON TRANSMIT LED 
ZCLXMT EQU  ZSTXMT+3  ;TURN OFF TRANSMIT LED
ZSTJPR EQU  ZCLXMT+3  ;SET JUMPERS ESC SEQ ROUTINE
ZSTLKY EQU  ZSTJPR+3  ;SET LATCHING KEYS ROUTINE
; 
;  KEYBOARD CONSTANTS 
; 
ZKBCON EQU  ZKBBAS+50Q
FRSALT EQU  ZKBCON    ;INITIAL ALTERNATE CHAR SET 
ALTOUT EQU  FRSALT+1  ;INITIAL ALTERNATE CHAR OUT 
; 
;  KEYBOARD CONTROL CALLS 
; 
LOCKKB EQU  1         ;LOCK KEYBOARD
UNLKKB EQU  2         ;UNLOCK KEYBOARD
RPTKEY EQU  3         ;REPEAT LAST KEY HIT
STBLMD EQU  4         ;SET PERMANENT BLOCK MODE 
STRTST EQU  5         ;START SELF-TEST
ENDTST EQU  6         ;END SELF-TEST
RSETKB EQU  7         ;RESET KEYBOARD 
CKIOKY EQU  8         ;CHECK FOR I/O CONTROL KEY
 
;*************************************************
; 
;        DATACOM CONSTANTS
; 
;*************************************************
ZDCBAS EQU  50000Q    ;DATACOM START ADDRESS
TRIGGR EQU  ZDCBAS+2  ;BLOCK TRANSFER TRIGGER 
RECSEP EQU  TRIGGR+1  ;RECORD SEPARATOR CHARACTER 
BLKTRM EQU  RECSEP+1  ;BLOCK TERMINATOR CHARACTER 
DCJMSK EQU  BLKTRM+1  ;DATA COMM JUMPER MASK
DCJMS2 EQU  DCJMSK+1  ;DATA COMM JUMPER MASK #2 
;*************************************************
; 
;        DATACOM ENTRY VECTOR POINTERS
; 
;*************************************************
ZINIDC EQU  ZDCBAS+10Q   ;INITIALIZE DATACOM
ZIN2DC EQU  ZINIDC+3  ;INITIALIZATION CONTINUATOR 
ZDCMON EQU  ZIN2DC+3  ;MONITORING ROUTINE 
ZDCCTL EQU  ZDCMON+3  ;MISC CONTROL FUNCTIONS 
ZDCTST EQU  ZDCCTL+3  ;SELF-TEST
ZGETDC EQU  ZDCTST+3  ;GET DC CHARACTER 
ZPUTDC EQU  ZGETDC+3  ;PUT DC CHARACTER 
ZGTBIN EQU  ZPUTDC+3  ;GET BINARY DC CHARACTER
ZSTBIN EQU  ZGTBIN+3  ;START BINARY OUTPUT
ZNDBIN EQU  ZSTBIN+3  ;END BINARY OUTPUT
ZDCINT EQU  ZNDBIN+3  ;DATACOM INTERRUPTS 
;*************************************************
; 
;        DATACOM CONTROL CALL CODES 
; 
;*************************************************
CLRTRG EQU  0         ;CLEAR BLOCK TRANSFER TRIGGE
SETTRG EQU  1         ;SET BLOCK TRANSFER TRIGGER 
RSETDC EQU  2         ;RESET DATACOM
SETREM EQU  3         ;SET REMOTE MODE
SETLCL EQU  4         ;SET LOCAL MODE 
PUTBRK EQU  5         ;OUTPUT BREAK SIGNAL
DISCNT EQU  6         ;MODEM DISCONNECT 
ENDBLK EQU  7         ;TERMINATE OUTPUT MESSAGE 
SETMON EQU  8         ;ENTER MONITOR MODE 
SETNRM EQU  9         ;ENTER NORMAL MODE
FSTBIN EQU  10        ;ENTER FAST BINARY OUT MODE 
SNDATN EQU  11        ;SEND ATTENTION CODE
SNDFCT EQU  12        ;SEND FUNCTION DATA 
PROMPT EQU  13        ;SEND PROMPT CODE 
 
;*************************************************
; 
;        SYMBOL DEFINITION CONVENTIONS
; 
;   THE PURPOSE IS TO KEEP RAM BYTE SYMBOL
;   DEFINITIONS RELATIVE TO DCCOMA OR SLWRAM
;   AND ALSO DISTINGUISH THOSE SYMBOLS THAT ARE 
;   ASSUMED TO BE CONTIGUOUS IN RAM (BY DATACOM 
;   CODE) 
; 
;   A)   SYMBOLS DEFINED IN TERMS OF OTHER SYMBOLS
;        HAVE CONTINUITY REQUIREMENTS, BECAUSE THE
;        DATACOM CODE ASSUMES THE SPECIFIED ORDER 
;        (EG, "SYM1   EQU  SYM2+1") 
;        NOTE THAT BECAUSE OF THE ORDERING, ONE 
;        MAY NOT FIND ALL REFERENCES IN THE 
;        CROSS-REFERENCE LISTING. 
;   B)   SYMBOLS WHOSE COMMENTS BEGIN WITH "!"
;        REQUIRE CONTINUITY BECAUSE THE BYTES ARE 
;        INITIALIZED (BY INI2DC) VIA A TABLE COPY 
;        (EG, "SYM1   EQU  DCCOMA+1    !COMMENT").
;   C)   SYMBOLS DEFINED ONLY IN TERMS OF "DCCOMA"
;        OR "SLWRAM" AND WITHOUT "!" HAVE NO
;        CONTINUITY REQUIREMENTS. 
;   D)   SOME FLAGS ARE ASSUMED TO BE IN PARTIC-
;        ULAR BIT POSITIONS.  REFERENCES TO SUCH
;        FLAGS MAY NOT BE FOUND IN THE CROSS- 
;        REFERENCE LISTING (EG, TO TEST BIT 6 
;        ONE MAY "ADD A" AND "JM" OR "JP", RATHER 
;        THAN "ANI FLAG").  SUCH FLAGS ARE
;        COMMENTED BY A STATEMENT SUCH AS:
;        "ASSUMED = 100B" (SEE CRC16 FOR EXAMPLE) 
;************************************************ 
 
;*************************************************
; 
;   KBDCSW -  KEYBOARD DATACOM SWITCHES 
; 
;*************************************************
KBDPAR EQU  FRCPTY/4  ;PARITY, 0=ENABLE 1=DISABLE 
KBDODD EQU  020Q      ;PARITY, 0=ODD 1=EVEN 
KBDBAU EQU  216Q      ;BAUD RATE, D7=HI/LOW SWITCH
;                            (D7=0 MEANS HI)
;************************************************ 
; 
;   KBJMP2 -  KEYBOARD JUMPER #2
; 
;************************************************ 
KB2SMN EQU  200Q      ;1 = SIEMEN'S PROTOCOL
;                     TPAD COMPATIBILITY
;                     (WHEN 8-BIT MODE, TPAD=377) 
;                     ASSUMED = 200B
;*************************************************
; 
;   KBJMP3 -  KEYBOARD JUMPER #3
; 
;*************************************************
KB3PMS EQU  FRCPTY    ;1=FORCE PARITY 
;                     ASSUMED = 200B
KB3CCL EQU  100Q      ;1=MONITOR CC TO OPERATE LED
;                     0=OPERATE LED WHEN TERM 
;                       COMMUNICATING WITH CPU
KB3CH  EQU  040Q      ;1=TURN ON CH; 0=TURN OFF CH
KB3STM EQU  020Q      ;1=SELF-TEST INHIBITED
KB3CC  EQU  010Q      ;1=CONTINUOUS CARRIER MODEM 
;                     0=NON-CONTINUOUS CARRIER
KB3BSZ EQU  006Q      ;MAX # BUFFERS PER XMIT BLOC
;                            00 = 1/2 # BUFFERS 
;                                 ALLOCATED 
;                            01 = 2 BUFFS/BLOCK 
;                            10 = 4 BUFFS/BLOCK 
;                            11 = 8 BUFFS/BLOCK 
;                     IF KB3BSZ > JC1BSZ THEN 
;                            DEFAULTS TO 00 
 
;*************************************************
; 
;        DATACOM FAST-RAM AREAS 
; 
;*************************************************
DCCOMA EQU  FSTRAM+200Q      ;DATACOM FAST-RAM ARE
;*************************************************
; 
;   ASFLAG -  INTERRUPT PROCESSOR FLAGS 
; 
;*************************************************
ASFLAG EQU  DCCOMA+0Q        ;FLAGS FOR ASYNC CODE
; 
;   ASFLGS BIT DEFINITIONS
; 
HDRSW  EQU  004Q             ;1=PUT HEADER ON NEXT
;                            TEXT BLK TRANSMITTED 
;                            ASSUMED = 004B 
LBCAST EQU  HDRSW*2          ;1=LINE BROADCAST
GBCAST EQU  LBCAST*2         ;1=GROUP BROADCAST 
BCAST  EQU  LBCAST+GBCAST    ;NZ=LINE/GRP BROADCAS
SELEC  EQU  GBCAST*2         ;1=DEVICE SELECT 
POL    EQU  SELEC*2          ;1=DEVICE POLL 
;                            ASSUMED=100B BY CTLIN
GPOLL  EQU  POL*2            ;1=GROUP POLL
;                            ASSUMED=200B BY CTLIN
WRU    EQU  HDRSW/4          ;1=WHO-ARE-YOU 
;                            ASSUMED=001B BY CTLIN
; 
RCVN   EQU  SELEC+BCAST      ;CONTROL SEQUENCE FLG
;                            FOR WHICH DATACOM IS 
;                            IN RECEIVE MODE
 
;*************************************************
; 
;   CONFIG -  CONFIGURATION FLAGS 
; 
;*************************************************
CONFIG EQU  ASFLAG+1         ;DATACOM CONFIGURATIO
; 
;   CONFIG BIT DEFINITIONS
; 
;   WARNING: HCODE,CRC16,M3270 ASSUMED TO BE
;            THE HIGH ORDER 3 BITS
HCODE  EQU  FRCPTY           ;1=EBCDIC, 0=ASCII 
;                            ASSUMED=200B 
CRC16  EQU  100Q             ;1=CRC16 BCC,0=LRC BC
;                            ASSUMED=100B 
M3270  EQU  040Q             ;0=NO SYNC FILL
;                            1=SYNC FILL
PMASK  EQU  020Q             ;1=PARITY TO BE CALC-
;                            ULATED BY SOFTWARE 
TPAR   EQU  010Q             ;1=TRANSPARENT MODE
;                            ASSUMED = 010B 
DLC    EQU  004Q      ;1=HAVE SEEN DLE
VRC2   EQU  002Q
VRC1   EQU  001Q
VRC    EQU  VRC2+VRC1        ;PARITY MASK ASSUMED=
;   WARNING: CODE ASSUMES THESE MASK DEFS 
VRCFC0 EQU  0Q               ;FORCE 0 PARITY
VRCODD EQU  VRC1             ;ODD PARITY
VRCEVN EQU  VRC2             ;EVEN PARITY 
VRCFC1 EQU  VRC2+VRC1        ;FORCE 1 PARITY
 
;*************************************************
; 
;   CONFG2 -  CONFIGURATION FLAGS, SET #2 
; 
;*************************************************
CONFG2 EQU  CONFIG+1Q        ;!DATACOM CONFIG 
; 
;   CONFG2 BIT DEFINITIONS
; 
DVRON  EQU  200Q             ;1=DRIVER MODE 
;                            ASSUMED=200B 
MONTR  EQU  100Q             ;1=MONITOR MODE
;                            ASSUMED=200B 
;                            (DVRON & MONTR CANNOT
;                            BE ON SIMULTANEOUSLY)
NAKERR EQU  002Q             ;1=ABORT WITH NAK
;                            ASSUMED = 002B 
EOTO   EQU  001Q             ;1=ABORT WITH EOT
;                            OR, 1=COMPUTER SENT
;                               TERM AN ETX BLK 
;                            OR, 1=TERM SENT COMP-
;                               UTER AN ETX BLK 
;                            ASSUMED = 001B 
;*************************************************
; 
;   ASACNT -  ABORT TIMER COUNT 
; 
;*************************************************
ASACNT EQU  DCCOMA+3Q        ;!ABORT TIMER COUNT
ABORTT EQU  113Q             ;=3 SEC IF CONTINUOUS
;                               CARRIER, ELSE 40MS
;*************************************************
; 
;   ASJMP1 -> ASVCT2    INTERRUPT VECTORS 
; 
;*************************************************
ASJMP1 EQU  DCCOMA+4Q        ;!DISPATCH VECTOR #1 
JMPOP  EQU  303Q             ;"JUMP" OPCODE 
ASVCT1 EQU  ASJMP1+1
ASJMP2 EQU  DCCOMA+7Q        ;!DISPATCH VECTOR #2 
ASVCT2 EQU  ASJMP2+1
 
;*************************************************
; 
;   ASACK -   "ACK" FLAG
; 
;*************************************************
ASACK  EQU  DCCOMA+12Q       ;"ACK" TO SEND/RECEIV
;                            = LAST ACK SENT OR 
;                            NEXT ACK EXPECTED
; 
;   ASACK FLAG DEFINITIONS
;   WARNING: CODE ASSUMES THE FOLLOWING DEFS
; 
ACK0F  EQU  000Q             ;SEND/RECEIVE "ACK-0"
ACK1F  EQU  001Q             ;SEND/RECEIVE "ACK-1"
ACKDC  EQU  200Q             ;ACK DON'T CARE
;*************************************************
; 
;   ASTCNT -  TIMER COUNT 
; 
;*************************************************
ASTCNT EQU  DCCOMA+13Q       ;TIMER COUNT 
; 
;      TIMER VALUES 
; 
;                            1 = 40 MSEC TIMER
ONESEC EQU  031Q             ;1 SEC TIMER 
TRISEC EQU  113Q             ;3 SEC TIMER 
;*************************************************
; 
;   CTL1 & CTL2 
; 
;*************************************************
CTL1   EQU  DCCOMA+14Q       ;COPY OF IODC+OCTL1
CTL2   EQU  DCCOMA+15Q       ;COPY OF IODC+OCTL2
 
;*************************************************
; 
;   HEXIN, HEXOUT -     TRANSLATE TABLE ADDR'S
; 
;*************************************************
HEXIN  EQU  DCCOMA+17Q       ;HI-ORDER ADDR OF
;                            EBCDIC->ASCII TABLE
;                            (ALWAYS 256-ALIGNED) 
HEXOUT EQU  DCCOMA+20Q       ;2-BYTE ADDR OF
;                            ASCII->EBCDIC TABLE
;                            (ALWAYS 128-ALIGNED) 
;*************************************************
; 
;   ASWK1 -> ASWK3
; 
;*************************************************
ASWK1  EQU  DCCOMA+22Q       ;INTERRUPT PROCESSOR'
ASWK2  EQU  DCCOMA+24Q       ;WORK AREAS
ASWK3  EQU  DCCOMA+26Q
 
;*************************************************
; 
;             DIAGNOSTIC WORK AREAS 
; 
;*************************************************
DCFLGS EQU  DCCOMA+30Q       ;DIAGNOSTIC FLAGS
;                            COPY OF IODC0+IODCST 
;                            NZ=STANDARD DATACOM
;                            CARD PRESENT 
;      DCSPTR = BUFEND-1     2-BYTE ADDR OF WHERE 
;                            TO "PUT" NEXT CHAR 
;                            IN BUFFER
DCBPTR EQU  ASWK2            ;2-BYTE ADDR OF WHERE
;                            TO "GET" NEXT CHAR 
;                            FROM BUFFER
;*************************************************
; 
;      STANDARD DATACOM CARD DEFINITIONS
; 
;*************************************************
IODC0  EQU  100400Q          ;BASE ADDR FOR MOD. 1
IODCST EQU  040Q             ;INPUT STATUS BYTE 
; 
;   INPUT STATUS BYTE BIT DEFINITIONS 
; 
DCTBE  EQU  002Q             ;TRANSMIT BUFFER EMPT
; 
IODCDI EQU  000Q             ;DATACOM DATA IN 
IODCCT EQU  100Q             ;DATACOM CONTROL OUT 
IODCDO EQU  140Q             ;DATACOM DATA OUT
;*************************************************
; 
;   CHARACTER DEFINITIONS 
; 
;*************************************************
ACK    EQU  006Q             ;DATACOM ACKNOWLEDGE 
ADEL   EQU  177Q             ;DELETE CHARACTER
 
;*************************************************
; 
;   QMANGR -  QUEUE MANAGEMENT WORK AREA
; 
;*************************************************
QMANGR EQU  DCCOMA+40Q       ;BEGINNING OF Q-AREA 
;                            LENGTH = 16B BYTES 
;*************************************************
; 
;   FLAG -    BUFFER MANAGEMENT FLAGS 
; 
;*************************************************
FLAG   EQU  QMANGR+0Q        ;PUTDC/GETDC FLAGS 
; 
;   FLAG BIT DEFINITIONS
; 
BUFF1  EQU  200Q             ;START NEW BLOCK 
;                            ASSUMED = 200B 
;                            (USED IN XMIT ONLY)
NEWBUF EQU  100Q             ;START NEW BUFFER
;                            ASSUMED = 100B 
;                            (USED IN XMIT ONLY)
BLKIN  EQU  040Q             ;1=BLOCK INPUT MODE
;                            (USED IN RECEIVE)
BINARY EQU  001Q             ;1=BIN BLK IN PROGRES
;                            ASSUMED=001B 
;                            (USED IN XMIT ONLY)
;*************************************************
; 
;   FQ -      FREE QUEUE
; 
;*************************************************
FQ     EQU  QMANGR+1Q        ;QUEUE OF FREE BUFFER
FQT    EQU  FQ+0             ;TAIL (ADDR OF LAST
;                            BUFFER IN QUEUE) 
FQH    EQU  FQ+1             ;HEAD (ADDR OF FIRST)
FQI    EQU  FQT 
FQO    EQU  FQH 
;*************************************************
; 
;   DQ -      DATA QUEUE
; 
;*************************************************
DQ     EQU  FQ+2             ;QUEUE OF FILLED BUFF
BUFPCO EQU  DQ+0             ;PRODUCER COUNT OFFSE
;                            (=APCNT OR PCNT) 
;                            "LHLD BUFPCO" GETS 
;                            THE ADDR OF CURRENT
;                            PRODUCER COUNT 
DQT    EQU  DQ+1             ;TAIL (ADDR OF LAST) 
DQH    EQU  DQ+2             ;HEAD (ADDR OF FIRST)
DQI    EQU  DQT 
DQO    EQU  DQH 
;*************************************************
; 
;   TQ -      TEMPORARY QUEUE 
; 
;*************************************************
TQ     EQU  DQ+3             ;QUEUE OF FILLED BUFF
;                            WAITING FOR TRANSMIT 
;                            ACKNOWLEDGE FROM CPU 
TQT    EQU  TQ+0             ;TAIL (ADDR OF LAST) 
TQH    EQU  TQ+1             ;HEAD (ADDR OF FIRST)
TQI    EQU  TQT 
TQO    EQU  TQH 
;*************************************************
; 
;   BUFBP -   BUFFER BOUNDARY POINTER 
; 
;*************************************************
BUFBP  EQU  TQ+2             ;BLOCK INPUT MODE ONL
;                            =ADDR OF BUFFER CON- 
;                            TAINING 1ST CHAR OF
;                            CURRENT BLOCK BEING
;                            RECEIVED FROM CPU
;*************************************************
; 
;   ASBCNT -  QUEUE CONTROL BUFFER COUNT
; 
;*************************************************
ASBCNT EQU  BUFBP+1          ;# OF COMPLETED BLOCK
;                            IN DATA QUEUE; COUNT 
;                            POSITIVE = # BLKS RDY
;                            TO XMIT: CNT NEGATIVE
;                            = # BLKS RCVD
;*************************************************
; 
;   BUFEND, BUFBEG      BOUNDARIES OF RAM-AREA
;                       ALLOCATED FOR DC BUFFERS
; 
;*************************************************
;   MAINCODE ALLOCATES A CONTIGUOUS RAM-AREA
;   FOR DC BUFFERS, THE TOP (HIGHEST ADDR) IS 
;   256-ALIGNED; GIVEN THAT A=2-BYTE ADDR OF THE
;   1ST BYTE (BYTE WITH SMALLEST ADDR), AND 
;   B=2-BYTE ADDR OF LAST BYTE, THEN
;        BUFBEG = B/256      (HI-BYTE OF B) 
;        BUFEND = A/256      (HI-BYTE OF A) 
; 
BUFLOC EQU  QMANGR+12Q       ;BUFFER BOUNDARIES 
BUFEND EQU  BUFLOC           ;LAST 256-BYTE BUFF
DCSPTR EQU  BUFEND-1         ;DIAGNOSTIC BUFF PTR 
BUFBEG EQU  BUFEND+1Q        ;FIRST 256-BYTE BUFF 
;*************************************************
; 
;   BUFMAX, BUFCNT      BUFFERS PER BLOCK COUNT 
; 
;*************************************************
BUFMAX EQU  QMANGR+14Q       ;MAXIMUM SIZE OF XMIT
;                            BLOCKS; = # OF BUFFS 
;                            TO FILL (LESS 1) 
;                            BEFORE TERMINATING 
;                            BLOCK WITH ETB 
BUFCNT EQU  BUFMAX+1         ;COUNTDOWN FROM BUFMA
 
;*************************************************
; 
;   INDIVIDUAL BUFFER FORMAT
; 
;*************************************************
; 
;   APCNT -   AUXILIARY PRODUCER COUNT
; 
;*************************************************
APCNT  EQU  000Q             ;IN USE ONLY WHEN
;                            BUFBC=1 AND BUFPCO=1 
;                            USED FOR MARKING BLK 
;                            BOUNDARIES & RECEIVE 
;                            ERRORS (ALLOWS PROD- 
;                            UCER TO CONT PUTTING 
;                            CHARS IN BUFF WHILE
;                            CONSUMER STOPPED AT
;                            PCNT)
;*************************************************
; 
;   PCNT -    PRODUCER COUNT
; 
;*************************************************
PCNT   EQU  APCNT+1          ;ALWAYS = LOW-ORDER
;                            ADDR OF LAST CHAR IN 
;                            BUFFER, PLUS 1 
;                            (=0 WHEN BUFFER FULL)
; 
;   NOTE THAT BUFPCO DETERMINES WHICH COUNT TO USE
;   (IT CONTAINS 0 OR 1); BUFPCO AND DQT TOGETHER 
;   GIVE THE 2-BYTE ADDRESS OF THE CURRENT
;   PRODUCER COUNT (APCNT OR PCNT)
; 
BUFIP  EQU  005+1Q    ;INITIAL VALUE OF BOTH
;                            PRODUCER COUNTS WHEN 
;                            RETRIEVED FROM FQ
;   NOTE THAT BUFIP SHOULD=5 BUT SET TO 6 SO THAT 
;   MAX NO OF CHARS IN OUTPUT BLOCK CAN BE = 256
;        256 = STX + GID + DID + AID + CCA + CCA
;                  + 249 DATA CHARACTERS
;*************************************************
; 
;   CCNT -    CONSUMER COUNT
; 
;*************************************************
CCNT   EQU  PCNT+1           ;ALWAYS = LOW-ORDER
;                            ADDR OF LAST CHAR
;                            CONSUMED FROM BUFFER 
;                            (=PCNT-1 WHEN THE
;                            CONSUMER HAS CAUGHT
;                            UP WITH PRODUCER)
; 
BUFIC  EQU  BUFIP-1          ;INITIAL VALUE OF
;                            CONSUMER COUNT WHEN
;                            RETRIEVED FROM FQ
; 
;*************************************************
; 
;   BFLG -    BUFFER FLAGS
; 
;*************************************************
BFLG   EQU  CCNT+1
; 
;   BFLG BIT DEFINITIONS
; 
BUFBC  EQU  004Q             ;=1 SIGNALS BLOCK
;                            BOUNDARY (WHEN CCNT= 
;                            PCNT-1)
BUFRER EQU  002Q             ;=1 SIGNAL RECEIVE 
;                            ERROR (WHEN CCNT=
;                            PCNT-1)
BUFBCT EQU  EOTO             ;VALID ONLY WHEN 
;                            BUFBC=1; 
;                            0=ETB BLOCK BOUNDARY 
;                            1=ETX BLOCK BOUNDARY 
; 
BUFIF  EQU  000Q             ;INITIAL BUFFER FLAGS
;                            WHEN BUFFER RETRIEVED
;                            FROM FQ
;*************************************************
; 
;   CHN -     BUFFER CHAIN POINTER
; 
;*************************************************
CHN    EQU  BFLG+1           ;HI-ORDER ADDR OF NEX
;                            BUFFER IN THE CHAIN
;                            (IE, NEXT IN QUEUE)
;                            0 TERMINATES CHAIN 
;                            (IF 0, BUFF = TAIL)
; 
BUFICH EQU  000Q             ;INITIAL CHAIN POINTE
;                            WHEN BUFFER RETRIEVED
;                            FROM FQ
 
;*************************************************
; 
;        DATACOM SLOW-RAM AREAS 
; 
;*************************************************
SLWRAM EQU  177200Q          ;DATACOM SLOW-RAM ARE
;*************************************************
; 
;   BCSTOP -  POINTER TO END OF BCC XMIT STRING 
; 
;*************************************************
BCSTOP EQU  SLWRAM+0Q        ;!LO-ORDER ADR OF LAS
;                            BYTE IN BCC STRING 
;                            IF LRC, PTS TO ASBCC 
;                            IF CRC PTS TO ASBCC+1
;*************************************************
; 
;   XEND -    BEGINNING OF TRANSPARENT BCC STRING 
; 
;*************************************************
XEND   EQU  SLWRAM+1Q        ;! = TRANSLATED DLE
;                            ! XEND+1 = BEG OF
;                            NON-TPAR BCC STRING
;                            (= TRANSLATED ETB/ETX
;                            DEPENDING ON BLOCK)
; 
;   WARNING: USAGE OF XEND REQUIRES THAT BCC
;   TRANSMIT STRING HAVE AN ADDRESS LESS THAN 
;   THAT OF ANY OTHER TRANSMIT STRING 
;*************************************************
; 
;   ASBCC -   BCC ACCUMULATION AREA 
; 
;*************************************************
ASBCC  EQU  XEND+2Q          ;!BEG OF 3-BYTE STRIN
;                            CRC: 2-BYTE BCC+TPAD 
;                            LRC: BCC+TPAD+STOPER 
ASBHI  EQU  (ASBCC+1)/256*256;ASBLOW = LO-ORDER AD
ASBLOW EQU  ASBCC+1-ASBHI    ;OF LAST CHAR IN CRC1
;                            BCC XMIT STRING
;*************************************************
; 
;   ASBCC0 -  INITIAL VALUE OF BCC WORK AREA
; 
;*************************************************
ASBCC0 EQU  ASBCC+3Q         ;!BEG OF 2-BYTE STRIN
;                            CRC: STOPER+STOPER 
;                            LRC: STOPER+TPAD 
 
;*************************************************
; 
;   DLESTX -  BLOCK HEADER WITHOUT ID'S 
; 
;*************************************************
DLESTX EQU  SLWRAM+10Q       ;!BEG OF TPAR HDR
;                            (= TRANSLATED DLE) 
STX    EQU  DLESTX+1Q        ;!BEG OF NON-TPAR HDR
;                            (= TRANSLATED STX) 
;                            !DLESTX+2 = STOPER 
;*************************************************
; 
;   EOT 
; 
;*************************************************
EOT    EQU  SLWRAM+13Q       ;!TRANSLATED EOT 
;*************************************************
; 
;   THDR -    BLOCK HEADER WITH ID'S
; 
;*************************************************
THDR   EQU  DLESTX+HDRSW     ;!BEG OF TPAR HDR
;                            (= TRANSLATED DLE) 
;                            NOTE: "HDRSW" FLAG 
;                            USED IN CALCULATING
;                            ADDR OF CORRECT HDR
HDR    EQU  THDR+1Q          ;!BEG OF NON-TPAR HDR
;                            (= TRANSLATE DLE)
GID    EQU  THDR+2Q          ;!TRANSLATED GROUP ID
ID1    EQU  GID 
POLRAT EQU  GID       ;TIMER FOR DRIVER POLL RATE 
;                     USE ESC-&-B TO MODIFY 
DID    EQU  THDR+3Q          ;!TRANSLATED DEVICE I
ID2    EQU  DID 
;*************************************************
; 
;   IBM 3270 MODE HEADER EXTENSION
; 
;*************************************************
;                            !THDR+4 & THDR+5:
;                            NON-3270-MODE =
;                               STOPER+STOPER 
;                            3270-MODE =
;                               XLATED ENTER+SPACE
;                            !THDR+6 = XLATED SPAC
;                            !THDR+7 = STOPER 
 
;*************************************************
; 
;   TLR -     TERMINAL RESPONSE STRING
; 
;*************************************************
TLR    EQU  SLWRAM+24Q       ;! = TRANSLATED DLE
;                            !TLR+1 = RESPONSE CHA
TPADIO EQU  TLR+2Q           ;! = TRANSLATED TPAD 
;                            !TLR+3 = STOPER
;*************************************************
; 
;   LDR -     SYNCRONOUS TRANSMISSION LEADER
;                  AND SYNC-FILL
; 
;*************************************************
LDR    EQU  SLWRAM+30Q       ;! IF SYNC-CARD (OR
;                            3270-BIT ASYNC) = SYN
;                            ELSE = STOPER
;                            !LDR+1 & LDR+2 = SYN'
SYNC   EQU  LDR+3Q           ;! = TRANSLATED SYNC 
;                            !SYNC+1 = STOPER 
;*************************************************
; 
;   ENTAID -  COPY OF ENTER-AID IN HEADER 
; 
;*************************************************
ENTAID EQU  SLWRAM+35Q       ;!SAME AS 1ST 2 BYTES
;                            OF 3270 HDR EXTENSION
;*************************************************
; 
;   DLE -     TRANSPARENT-SYNCRONOUS SYNC-FILL
; 
;*************************************************
DLE    EQU  LDR+TPAR-1       ;!BEG OF TPAR-SYN FIL
;                            TO USE IF 1SEC TIMER 
;                            WENT OFF AND DLC ON
;                            (= TRANSLATED DLE) 
DLESYN EQU  LDR+TPAR         ;!BEG OF NORMAL
;                            TPAR-SYNC FILL 
;                            (= TRANSLATED DLE) 
;                            !DLESYN+1 =XLATED SYN
;                            !DLESYN+2 =XLATED DLE
;                            !DLESYN+3 =XLATED SYN
;                            !DLESYN+4 =STOPER
 
;*************************************************
; 
;   NAK -> WACK    RESPONSE CONTROL CHARACTERS
; 
;*************************************************
NAK    EQU  SLWRAM+45Q       ;! = TRANSLATED NAK
RVI    EQU  NAK+1Q           ;! = TRANSLATED RVI
ACK0   EQU  RVI+1Q           ;! = TRANSLATED ACK-0
ACK1   EQU  ACK0+1Q          ;! = TRANSLATED ACK-1
WACK   EQU  ACK1+1Q          ;! = TRANSLATED WACK 
;*************************************************
; 
;   CTLTBL -  TABLE OF CONTROL SEQUENCE CHARACTERS
; 
;*************************************************
CTLTBL EQU  SLWRAM+52Q       ;!1ST 3 CHARS ARE THE
;                            ONLY LEGAL 1ST CHARS 
;                            OF A CONTROL SEQUENCE
;                            (= XLATED GROUP ID)
;                            !CTLTBL+1 = DEVICE ID
;                            !CTLTBL+2 = TILDA
;                            LAST 6 CHARS ARE THE 
;                            ONLY LEGAL 3RD CHARS 
;                            OF A CONTROL SEQUENCE
;                            !CTLTBL+3 = TILDA
;                            !CTLTBL+4 = DEVICE ID
;                            !CTLTBL+5 = DEVICE ID
;                            !CTLTBL+6 = QUOTE
;                            !CTLTBL+7 = RT BRACE 
 
;*************************************************
; 
;   PLIST -   POLL LIST FOR DRIVER
; 
;*************************************************
PLIST  EQU  SLWRAM+62Q       ;! = XLATED GROUP ID 
;                            ! PLIST+1 = GROUP ID 
;                            ! PLIST+2 = DEVICE ID
;                            ! PLIST+3 = DEVICE ID
;                            ! PLIST+4 = ENQ
;                            ! PLIST+5 = TPAD 
;                            ! PLIST+6 = STOPER 
;*************************************************
; 
;   SLIST -   SELECT LIST FOR DRIVER
; 
;*************************************************
SLIST  EQU  SLWRAM+71Q       ;! = SELECT GROUP ID 
;                            ! SLIST+1 = SAME 
;                            ! SLIST+2 = DEVICE ID
;                            ! SLIST+3 = SAME 
;                            ! SLIST+4 = ENQ
;                            ! SLIST+5 = TPAD 
;                            ! SLIST+6 = STOPER 
 
;*************************************************
; 
;   ETB -> ENQ     TERMINATOR CONTROL CHARACTERS
; 
;*************************************************
ETB    EQU  SLWRAM+100Q      ;! = XLATED ETB
ETX    EQU  ETB+BUFBCT       ;! = XLATED ETX
ENQ    EQU  ETX+1            ;! = XLATED ENQ
; 
;                            ENQ+1 = HOLE FOR 
;                            MATCH CHAR (TO 
;                            TERMINATE SEARCH)
;*************************************************
; 
;   SLFID, WRUSTS  SELF-TEST MESSAGE
;                  WHO-ARE-YOU STATUS STRING
; 
;*************************************************
SLFID  EQU  SLWRAM+110Q      ;BEG OF SELF-TEST MSG
;                            (= NON-XLATED GRP ID)
;                            SLFID+1 = DEV ID 
WRUSTS EQU  SLFID+2Q         ;WRU STATUS BYTE #1
;                            BIT#7=PARITY 
;                            BIT#6=1 (ALWAYS) 
;                            BIT#5-4=VRC TYPE 
;                            BIT#3-0=BAUD RATE
;                               (AS FROM KBDCSW)
;                            WRU STATUS BYTE #2 
;                            BIT#7=PARITY 
;                            BIT#6=1 (ALWAYS) 
;                            BIT#5=HCODE, #4=CRC16
;                            BIT#3=M3270
;                            BIT#2-1=BUFSIZ 
;                            BIT#0=BLKIN
;                            WRU STATUS BYTE #3 
;                            BIT#7=PARITY 
;                            BIT#6=1 (ALWAYS) 
;                            BIT#5=1 IF ASBCNT>0
;                            BIT#4=REMSET 
;                            BIT#3-0=TRMTYP 
;*************************************************
; 
;   DCMSG -   DATACOM MESSAGE AREA
; 
;*************************************************
DCMSG  EQU  SLWRAM+120Q 
 
;*************************************************
; 
;   MULTIPOINT DATACOM CARD DEFINITIONS 
; 
;*************************************************
IODC   EQU  107000Q   ;BASE ADDRESS FOR MODULE #7 
;                     ALL DC CARD ADDR'S ARE OF 
;                     THE FORM IODC+OFFSET
;*************************************************
; 
;   ST1 -     INPUT STATUS BYTE #1
; 
;*************************************************
ST1    EQU  040Q      ;INPUT STATUS BYTE #1 
; 
;   BIT DEFINITIONS FOR INPUT STATUS BYTE #1
; 
ST1IBF EQU  200Q      ;1 = INPUT BUFFER FULL
;                     CLEARED BY INPUTTING CHAR 
ST1PER EQU  100Q      ;1 = PARITY ERROR 
;                     VALID ONLY IF ST1IBF=1
ST1OER EQU  040Q      ;1 = OVERRUN ERROR
;                     VALID ONLY IF ST1IBF=1
ST1NU  EQU  030Q      ;NOT USED 
ST1SYN EQU  004Q      ;1 = AUTOMATIC SYNC FILL
;                     CLEARED BY INPUTTING STATUS 
ST1TIM EQU  002Q      ;1 = 40 MSEC TIMER TICKED OF
;                     CLEARED BY RESETTING TIMER
ST1XMT EQU  001Q      ;1 = TRANSMIT BUFFER EMPTY
;                     CLEARED BY OUTPUTTING CHAR
;                     CLEARED BY LOWERING CA
;                     (NOTE THAT AFTER RAISING CA 
;                     ST1XMT COMES UP WHEN CB=1)
;*************************************************
; 
;   ST2 -     INPUT STATUS BYTE #2
; 
;*************************************************
ST2    EQU  050Q      ;INPUT STATUS BYTE #2 
; 
;   BIT DEFINITIONS FOR INPUT STATUS BYTE #2
; 
ST2MPT EQU  200Q      ;1 = MULTIPOINT DATACOM CARD
ST2SYC EQU  M3270*2   ;1 = SYNCHRONOUS CARD 
ST2CAZ EQU  040Q      ;0 = DOWNLINE CA ON 
ST2CEZ EQU  020Q      ;0 = CE ON (DATA SET RINGING
;                     (1=LOOP-BACK SELF-TEST HOOD)
ST2SBZ EQU  010Q      ;0 = SB ON (SECONDARY CHANNL
ST2CCZ EQU  004Q      ;0 = CC ON (DATA SET READY) 
ST2CFZ EQU  002Q      ;0 = CF ON (CARRIER)
ST2CBZ EQU  001Q      ;0 = CB ON (CLEAR TO SEND)
; 
ST2Z   EQU  ST2CEZ+ST2SBZ+ST2CCZ+ST2CFZ+ST2CBZ
;*************************************************
; 
;   CHARIN -  RECEIVED CHARACTER
; 
;*************************************************
CHARIN EQU  000Q      ;INPUT CHARACTER
 
;*************************************************
; 
;   OCTL1 -   OUTPUT CONTROL BYTE #1
; 
;*************************************************
OCTL1  EQU  040Q      ;OUTPUT DATACOM COMMANDS
; 
;   OCTL1 BIT DEFINITIONS 
; 
CT1ND2 EQU  200Q      ;# OF DATA BITS 
CT1ND1 EQU  100Q      ;# OF DATA BITS 
CT1D7  EQU  CT1ND2           ;7 DATA BITS 
CT1D8  EQU  CT1ND1+CT1ND2    ;8 DATA BITS 
CT1PAR EQU  KBDPAR    ;0 = ENABLE PARITY
;                     MUST BE IN SAME POSITION AND
;                     HAVE SAME SENSE AS KBDPAR 
CT1ODD EQU  KBDODD    ;0 = ODD PARITY, 1 = EVEN 
;                     (USED ONLY WHEN CT1PAR = 0) 
;                     MUST BE IN SAME POSITION AND
;                     HAVE SAME SENSE AS KBDODD 
CT1BAU EQU  017Q      ;BAUD RATE, ASSUMED = 017B
;                            00 = 19.2K BAUD
;                            01 =    50 BAUD
;                            02 =    75 BAUD
;                            03 =   110 BAUD
;                            04 = 134.5 BAUD
;                            05 =   150 BAUD
;                            06 =   300 BAUD
;                            07 =   600 BAUD
;                            10 =   200 BAUD
;                            11 =  1200 BAUD
;                            12 =  1800 BAUD
;                            13 =  2400 BAUD
;                            14 =  3600 BAUD
;                            15 =  4800 BAUD
;                            16 =  7200 BAUD
;                            17 =  9600 BAUD
;*************************************************
; 
;   OCTL2 -   OUTPUT CONTROL BYTE #2
; 
;*************************************************
OCTL2  EQU  100Q      ;OUTPUT DATACOM COMMANDS
; 
;   OCTL2 BIT DEFINITIONS 
; 
CT2CBD EQU  200Q      ;1 = INHIBIT DOWNLINE CA & C
CT2NU  EQU  140Q      ;NOT USED 
CT2CMM EQU  020Q      ;1 = CHANNEL MONITOR MODE 
CT2CHZ EQU  KB3CH/4   ;0 = CH ON (EUROPEAN SPEED) 
CT2CDZ EQU  004Q      ;0 = CD ON (DATA TERM READY)
CT2SAZ EQU  002Q      ;0 = SA ON (SECONDARY RTS)
CT2CAZ EQU  001Q      ;0 = CA ON (REQUEST TO SEND)
; 
CT2Z   EQU  CT2CHZ+CT2CDZ+CT2SAZ+CT2CAZ 
;*************************************************
; 
;   TMIT -    OUTPUT CHARACTER
; 
;*************************************************
TMIT   EQU  140Q      ;OUTPUT DATA FOR TRANSMISSIO
XCOMP  EQU  010Q      ;ENABLE TRANSMIT COMPLETE 
;                     INTERRUPTS
DISXMT EQU  200Q      ;DISABLE TRANSMIT COMPLETE
;                     INTERRUPTS
 
;*************************************************
; 
;   MISCELLANEOUS IO COMMANDS 
; 
;*************************************************
RTIME  EQU  001Q      ;RESET TIMER (TURN OFF) 
STIME  EQU  002Q      ;SET TIMER (TURN ON)
RRECV  EQU  004Q      ;RESET SYNCRONOUS RECEIVER
;                     (IGNORED BY ASYNC CARD) 
DCSYN  EQU  150Q      ;DEFINE SYNC CHARACTER
;                     (IGNORED BY ASYNC CARD) 
 
;*************************************************
; 
;   JC0 -     DATACOM INPUT JUMPER #0 
; 
;*************************************************
JC0    EQU  100Q      ;DATACOM OPTIONS
; 
;   BIT DEFINITIONS FOR JC0 
; 
JC0EBC EQU  HCODE     ;1 = EBCDIC; 0 = ASCII
JC0CRC EQU  CRC16     ;1 = CRC16 BCC; 0 = LRC BCC 
JC0IBM EQU  M3270     ;IF SYNC CARD,
;                            1 = IBM 3270 DATACOM 
;                            COMPATIBILITY OPTION 
;                     IF ASYNC CARD,
;                            1 = PROVIDE SYNC FILL
JC0ID  EQU  037Q      ;GROUP ID (0-32B; @-Z+SPACE)
MASKID EQU  JC0ID 
MAXID  EQU  032Q      ;MAXIMUM ID (OTHERS -> SPACE
;*************************************************
; 
;   JC1 -     DATACOM INPUT JUMPER #1 
; 
;*************************************************
JC1    EQU  110Q      ;DATACOM OPTIONS
; 
;   BIT DEFINITION FOR JC1
; 
JC1BSZ EQU  300Q      ;INPUT BUFFER SIZE
;                            00 = 512 BYTES 
;                            01 = 1024 BYTES
;                            10 = 2048 BYTES
;                            11 = 4096 BYTES
BUFSIZ EQU  JC1BSZ
JC1BKI EQU  BLKIN     ;1 = BLOCK INPUT MODE 
JC1ID  EQU  MASKID    ;DEVICE ID; SAME RULES AS 
;                            GROUP ID 
 
;*************************************************
; 
;        CHARACTER DEFINITIONS
; 
;*************************************************
ACK0I  EQU  060Q             ;ASCII ACK0
ACK0E  EQU  160Q             ;EBCDIC ACK0 
ACK1I  EQU  061Q             ;ASCII ACK1
ACK1E  EQU  141Q             ;EBCDIC ACK1 
EOTI   EQU  004Q             ;ASCII EOT 
ETXI   EQU  003Q             ;ASCII ETX 
ETBI   EQU  027Q             ;ASCII ETB 
ENQI   EQU  005Q             ;ASCII ENQ 
DLEI   EQU  020Q             ;ASCII DLE 
WACKI  EQU  073Q             ;ASCII WACK
WACKE  EQU  153Q             ;EBCDIC WACK 
RVII   EQU  074Q             ;ASCII RVI 
RVIE   EQU  174Q             ;EBCDIC RVI
RVIACK EQU  70174Q           ;ACK0E*256+RVIE
ACKWAC EQU  65541Q           ;WACKE*256+ACK1E 
NAKI   EQU  025Q             ;ASCII NAK 
GCHARI EQU  042Q             ;ASCII QUOTE 
;                            GROUP POLL CHARACTER 
WCHARI EQU  175Q             ;ASCII RIGHT BRACE 
;                            WHO-ARE-YOU CHARACTER
BCHARI EQU  176Q             ;ASCII TILDA 
;                            BROADCAST CHARACTER
STXI   EQU  002Q             ;ASCII STX 
ENTERI EQU  047Q             ;ASCII ENTER KEY 
;                            (3270 COMPATIBILITY) 
SPACEI EQU  040Q             ;ASCII SPACE 
SYNCI  EQU  026Q             ;ASCII SYNC
ATSINI EQU  100Q             ;ASCII @ 
DASHI  EQU  055Q             ;ASCII - 
LOWERI EQU  040Q             ;BIT TO TURN ON FOR
;                            UPPER-TO-LOWER 
;                            CASE CONVERSION
TPADI  EQU  177Q             ;ASCII TRAILING PAD
TPADE  EQU  377Q             ;EBCDIC TRAILING PAD 
DC1    EQU  021Q             ;BLOCK TRIGGER 
RS     EQU  036Q             ;RECORD SEPERATOR
GS     EQU  035Q             ;BLOCK TERMINATOR
 
;*************************************************
; 
;   MISCELLANEOUS DEFINITIONS 
; 
;*************************************************
STOPER EQU  000Q      ;TERMINATES ALL TRANSMITION 
;                     STRINGS (EXCEPT BCC)
; 
EOP    EQU  316Q      ;TERMINATES MAINCODE MSGS 
; 
BLKMIN EQU  256-64    ;IF FQ EMPTY AND
;                     PCNT > BLKMIN IN LAST BUFF
;                     IN DQ, THEN SEND WACK 
; 
CNT327 EQU  003Q      ;# OF CHARS TO STRIP OFF
;                     IN 3270 TEXT MODE 
; 
AIDFLG EQU  200Q      ;FLAGS SHORT ENTER-AID
;                     ASSUMED = 200B
 
;*************************************************
; 
;        DATACOM CONSTANTS
; 
;*************************************************
       ORG  ZDCBAS
; 
       DB   'Q'       ;ROM IDENTIFIER BYTE PAIR 
;                     (DATACOM VERSION #2)
       DB   ZDCBAS/256
; 
       ORG  TRIGGR
; 
       DB   DC1       ;TRIGGR - BLOCK TRIGGER 
       DB   RS        ;RECSEP - RECORD SEPARATOR
       DB   GS        ;BLKTRM - BLOCK TERMINATOR
       DB   000Q      ;DCJMSK - JUMPER MASK 
;                     (ALL DC JUMPERS MODIFIABLE
;                     BY ESCAPE SEQUENCES)
       DB   000Q      ;DCJMS2 - JUMPER MASK #2
;*************************************************
; 
;        DATACOM ENTRY VECTORS
; 
;*************************************************
       ORG  ZINIDC    ;BEGINNING OF JUMP VECTORS
; 
       JMP  INITDC    ;ZINIDC - INITIALIZE DATACOM
       JMP  INI2DC    ;ZIN2DC - CONTINUE INIT 
       JMP  DCMON     ;ZDCMON - MONITORING ROUTINE
       JMP  DCCTL     ;ZDCCTL - MISC CTL FUNCTIONS
       JMP  DCTEST    ;ZDCTST - SELF-TEST 
       JMP  GETDC     ;ZGETDC - CHARACTER INPUT 
       JMP  PUTDC     ;ZPUTDC - CHARACTER OUTPUT
       JMP  GETBIN    ;ZGTBIN - BINARY INPUT
       JMP  STBIN     ;ZSTBIN - START BINARY OUT
       JMP  ENDBIN    ;ZNDBIN - END BINARY OUTPUT 
 
;************************************************ 
; 
;        STANDARD ENTRY POINT FOR ALL 
;        INTERRUPTS; SAVE STATUS AND
;        JUMP THROUGH VECTOR #1 
; 
;************************************************ 
DCINTR EQU  $         ;WARNING: MUST FOLLOW ENDBIN
ENTRY: PUSH B         ;WARNING: REGISTERS MUST BE 
       PUSH D           ;PUSHED IN THIS ORDER 
       PUSH H           ;REQUIRED BY DCCTL
       PUSH PSW 
; 
       LDA  IODC+ST1  ;DATACOM STATUS BYTE #1 
       MOV  D,A 
; 
       LXI  H,IODC+CHARIN     ;INPUT CHARACTER
       MOV  B,M 
; 
       LXI  H,CONFIG  ;CONFIGURATION BYTE 
       MOV  C,M 
; 
       JMP  ASJMP1    ;DISPATCH INTERRUPT 
 
; 
;   INITIAL RAM VALUES
; 
COPY1  EQU  BCSTOP    ;INIT BCSTOP -> ENQ 
XLAT1  EQU  COPY1+1   ;TRANSLATE ALL BUT BCSTOP 
; 
;   BCC TRANSMIT STRING 
; 
RAMTBL:DB   ASBLOW    ;LOW ORDER ADDR OF LAST 
;                     BYTE IN TRANSMIT BCC
; 
       DB   DLEI      ;START OF TRANSPARENT BCC 
       DB   ETBI      ;BEGINNING OF BCC TRAILER 
       DB   0,0       ;WORK AREA TO COMPUTE CRC 
       DB   TPADI     ;FOLLOW BCC BY PAD
       DB   STOPER    ;TRANSMIT TERMINATOR
       DB   STOPER    ;INITIAL RT BYTE OF BCC 
; 
;   BLOCK HEADER WITH NO GROUP/DEVICE ID'S
; 
       DB   DLEI      ;START OF TRANSPARENT HEADER
       DB   STXI      ;BEG OF NON-TRANSPARENT HDR 
       DB   STOPER    ;TRANSMIT TERMINATOR
; 
       DB   EOTI      ;EOT
; 
;   BLOCK HEADER WITH GROUP/DEVICE ID'S 
; 
       DB   DLEI      ;START OF TRANSPARENT HDR 
       DB   STXI      ;BEGINNING OF HEADER
       DB   0         ;HOLE FOR GROUP ID
       DB   0         ;HOLE FOR DEVICE ID 
       DB   ENTERI    ;FILL IN WITH STOPER
;                     TO SET UP NON-3270 HDR
       DB   SPACEI    ;3270 MODE HEADER 
       DB   SPACEI
       DB   STOPER    ;TERMINATOR FOR 3270 HDR
; 
       DB   DLEI      ;START OF TRAILER 
       DB   0         ;HOLE FOR RESPONSE
       DB   TPADI     ;RESPONSES FOLLOWED BY PAD
       DB   STOPER    ;TRAILER TERMINATOR 
; 
;   SYNCHRONOUS LEADER
;        AND NON-TRANSPARENT SYNC FILL
; 
       DB   SYNCI,SYNCI,SYNCI,SYNCI 
       DB   STOPER    ;TRANSMIT TERMINATOR
; 
       DB   ENTERI,SPACEI    ;COPY OF ENTER-SPACE 
;                            FILL IN WITH STOPERS 
;                            TO SET UP NON-3270 
; 
;   TRANSPARENT SYNC FILL 
; 
       DB   DLEI,DLEI,SYNCI,DLEI,SYNCI
       DB   STOPER    ;TRANSMIT TERMINATOR
; 
       DB   NAKI      ;NAK
       DB   RVII      ;RVI
       DB   ACK0I     ;ACK0 
       DB   ACK1I     ;ACK1 
       DB   WACKI     ;WACK 
; 
;   CONTROL SEQUENCE TABLE
; 
       DB   0,0       ;HOLES FOR GROUP&SELECT IDS 
       DB   BCHARI,BCHARI  ;BROADCAST CHAR
       DB   0,0       ;2 HOLES FOR DEVICE ID
       DB   GCHARI    ;GENERAL POLL CHAR
       DB   WCHARI    ;WHO-ARE-YOU CHAR 
; 
;   POLL LIST FOR DRIVER
; 
       DB   101Q,101Q        ;GROUP "A" 
       DB   GCHARI,GCHARI    ;GENERAL POLL
       DB   ENQI,TPADI,STOPER 
; 
;   SELECT LIST FOR DRIVER
; 
       DB   141Q,141Q        ;GROUP "A" 
       DB   101Q,101Q        ;DEVICE "A"
       DB   ENQI,TPADI,STOPER 
; 
;   CONTROL CHARACTERS WHICH TERMINATE DATA BLKS
; 
       DB   ETBI,ETXI,ENQI
; 
NCOPY1 EQU  $-RAMTBL
NXLAT1 EQU  NCOPY1-1
; 
COPY2  EQU  CONFG2    ;INIT CONFG2 -> ASJMP2
; 
RAMTB2:DB   0         ;INITIAL VALUE FOR CONFG2 
       DB   1         ;ABORT TIMER = 40MSEC 
       DB   JMPOP     ;ASJMP1 
       DW   EOTIN     ;1ST DATACOM INTERRUPT
       DB   JMPOP     ;ASJMP2 
; 
NCOPY2 EQU  $-RAMTB2
 
;*************************************************
; 
;        COMPRESSED TRANSLATE TABLES
; 
;   THE TRANSLATE TABLES ARE COMPRESSED BY
;   REPLACING CERTAIN CHARACTER STRINGS 
;   BY SPECIAL COMPRESSION CODES
; 
;   1)   OPCODE = SET-TO-SYNC 
;        BIT 0 = 1
;        BITS 5-1 = # OF BYTES TO BE FILLED LESS 1
;             WITH SYNC CHARS 
;        BITS 7-6 = 0 
; 
;   2)   OPCODE = SEQUENTIAL-STRING 
;        BIT 0 = 0
;        BIT 1 = 1
;        BITS 6-2 = # OF BYTES TO BE FILLED LESS 1
;        BIT 7 = 0
; 
;        NEXT BYTE IN XTABLE = 1ST BYTE IN STRING 
; 
;   3)   OPCODE = EXCEPTION STRING
;        BITS 1-0 =0
;        BIT 2 = 1
;        BITS 7-3 = # OF BYTES TO BE FILLED LESS 1
; 
;        THE NEXT N BYTES (N = # IN BITS 7-3) 
;        CONTAIN THE EXCEPTION STRING 
; 
;   4)   TERMINATOR 
;        BITS 2-0 = 0 
; 
; 
CPYSYN EQU  1Q        ;OPCODE = SET-TO-SYNC 
MLTSYN EQU  2Q        ;MULTIPLIER FOR COUNT 
; 
CPYSEQ EQU  2Q        ;OPCODE = SEQUENTIAL-STRING 
MLTSEQ EQU  4Q        ;MULTIPLIER FOR COUNT 
; 
CPYSTR EQU  4Q        ;OPCODE = EXCEPTION-STRING
MLTSTR EQU  10Q       ;MULTIPLIER FOR COUNT 
 
; 
;   COMPRESSED HEXOUT TABLE 
;   (ASCII TO EBCDIC TRANSLATE TABLE) 
; 
;        TABLE IS 1-TO-1 WITH THE 
;        FOLLOWING EXCEPTIONS 
;        1)   LEFT-BRACKET CONVERTED TO LEFT-PAREN
;        2)   RGHT-BRACKET CONVERTED TO RGHT-PAREN
;        3)   CIRCUMFLEX CONVERTED TO SEMI-COLON
; 
XTABLE:DB   3*MLTSEQ+CPYSEQ     ;(ASCII 0-3)
       DB   0                   ;NUL SOH STX ETX
; 
       DB   6*MLTSTR+CPYSTR     ;(ASCII 4-12) 
       DB   67Q,55Q,56Q,57Q     ;EOT ENQ ACK BEL
       DB   26Q,5Q,45Q          ;BS HT LF 
; 
       DB   8*MLTSEQ+CPYSEQ     ;(ASCII 13-23)
       DB   13Q                 ;VT FF CR SO SI DL
;                               DC1 DC2 DC3 
; 
       DB   7*MLTSTR+CPYSTR     ;(ASCII 24-33)
       DB   74Q,75Q,62Q,46Q     ;DC4 NAK SYN ETB
       DB   30Q,31Q,77Q,47Q     ;CAN EM SUB ESC 
; 
       DB   3*MLTSEQ+CPYSEQ     ;(ASCII 34-37)
       DB   34Q                 ;FS GS RS US
; 
       DB   15*MLTSTR+CPYSTR    ;(ASCII 40-57)
       DB   100Q,132Q,177Q      ;SPACE ! "
       DB   173Q,133Q,154Q      ;# $ %
       DB   120Q,175Q,115Q      ;& ' (
       DB   135Q,134Q,116Q      ;) * +
       DB   153Q,140Q,113Q      ;, - .
       DB   141Q                ;/
; 
       DB   9*MLTSEQ+CPYSEQ     ;(ASCII 60-71)
       DB   360Q                ;0 1 2 3 4 5
;                               6 7 8 9 
; 
       DB   6*MLTSTR+CPYSTR     ;(ASCII 72-100) 
       DB   172Q,136Q,114Q      ;: ; <
       DB   176Q,156Q,157Q      ;= > ?
       DB   174Q                ;@
; 
       DB   8*MLTSEQ+CPYSEQ     ;(ASCII 101-111)
       DB   301Q                ;A B C D E F G H I
; 
       DB   8*MLTSEQ+CPYSEQ     ;(ASCII 112-122)
       DB   321Q                ;J K L M N O P Q R
; 
       DB   7*MLTSEQ+CPYSEQ     ;(ASCII 123-132)
       DB   342Q                ;S T U V W X Y Z
; 
       DB   5*MLTSTR+CPYSTR     ;(ASCII 133-140)
       DB   115Q                ;LEFT-BRACKET 
       DB   340Q                ;BACK-SLASH 
       DB   135Q                ;RIGHT-BRACKET
       DB   136Q                ;CIRCUMFLEX 
       DB   155Q                ;UNDERSCORE 
       DB   171Q                ;ACCENT 
; 
       DB   8*MLTSEQ+CPYSEQ     ;(ASCII 141-151)
       DB   201Q                ;A B C D E F G H I
; 
       DB   8*MLTSEQ+CPYSEQ     ;(ASCII 152-162)
       DB   221Q                ;J K L M N O P Q R
; 
       DB   7*MLTSEQ+CPYSEQ     ;(ASCII 163-172)
       DB   242Q                ;S T U V W X Y Z
; 
       DB   4*MLTSTR+CPYSTR     ;(ASCII 173-177)
       DB   300Q                ;LEFT-BRACE 
       DB   152Q                ;BROKN VERTICAL BA
       DB   320Q                ;RIGHT-BRACE
       DB   241Q                ;TILDA
       DB   007Q                ;DELETE 
 
;   COMPRESSED HEXIN TABLE
;   (EBCDIC TO ASCII TRANSLATE TABLE
; 
;        UNTRANSLATABLE AND UNDEFINED 
;        CHARACTERS CONVERTED TO SYNC'S 
;        DNT MEANS DOES NOT TRANSLATE 
;        ND MEANS NOT DEFINED 
; 
       DB   3*MLTSEQ+CPYSEQ     ;(EBCDIC 0-3) 
       DB   0                   ;NUL SOH STX ETX
; 
       DB   3*MLTSTR+CPYSTR     ;(EBCDIC 4-7) 
       DB   SYNCI,11Q           ;DNT HT 
       DB   SYNCI,177Q          ;DNT DELETE 
; 
       DB   2*MLTSYN+CPYSYN     ;(EBCDIC 8-A) 
;                               ND ND DNT 
; 
       DB   8*MLTSEQ+CPYSEQ     ;(EBCDIC B-13)
       DB   13Q                 ;VT FF CR SO SI 
;                               DLE DC1 DC2 DC3 
; 
       DB   1*MLTSYN+CPYSYN     ;(EBCDIC 14-15) 
;                               DNT DNT 
; 
       DB   3*MLTSTR+CPYSTR     ;(EBCDIC 16-19) 
       DB   10Q,SYNCI           ;BS DNT 
       DB   30Q,31Q             ;CAN EM 
; 
       DB   1*MLTSYN+CPYSYN     ;(EBCDIC 1A-1B) 
;                               DNT ND
; 
       DB   3*MLTSEQ+CPYSEQ     ;(EBCDIC 1C-1F) 
       DB   34Q                 ;IFS IGS IRS IUS
; 
       DB   4*MLTSYN+CPYSYN     ;(EBCDIC 20-24) 
;                               DNT DNT DNT ND DNT
; 
       DB   2*MLTSTR+CPYSTR     ;(EBCDIC 25-27) 
       DB   12Q,27Q,33Q         ;LF ETB ESC 
; 
       DB   4*MLTSYN+CPYSYN     ;(EBCDIC 28-2C) 
;                               DNT DNT DNT ND DNT
; 
       DB   2*MLTSEQ+CPYSEQ     ;(EBCDIC 20-2F) 
       DB   5Q                  ;ENQ ACK BEL
; 
       DB   6*MLTSYN+CPYSYN     ;(EBCDIC 30-36) 
;                               ND ND SYNC ND 
;                               DNT DNT DNT 
; 
       DB   0*MLTSTR+CPYSTR     ;(EBCDIC 37)
       DB   4Q                  ;EOT
; 
       DB   3*MLTSYN+CPYSYN     ;(EBCDIC 38-38) 
;                               ND ND ND ND 
; 
       DB   4*MLTSTR+CPYSTR     ;(EBCDIC 3C-40) 
       DB   24Q,25Q,SYNCI       ;DC4 NAK ND 
       DB   32Q,40Q             ;SUB SPACE
; 
       DB   9*MLTSYN+CPYSYN     ;(EBCDIC 41-4A) 
;                               ND ND ND ND ND
;                               ND ND ND ND DNT 
; 
       DB   5*MLTSTR+CPYSTR     ;(EBCDIC 4B-50) 
       DB   56Q,74Q,50Q         ;. < (
       DB   53Q,SYNCI,46Q       ;+ DNT &
; 
       DB   8*MLTSYN+CPYSYN     ;(EBCDIC 51-59) 
;                               ND ND ND ND ND
;                               ND ND ND ND 
; 
       DB   7*MLTSTR+CPYSTR     ;(EBCDIC 5A-61) 
       DB   41Q,44Q,52Q,51Q     ;! $ * )
       DB   73Q,SYNCI,55Q       ;; DNT -
       DB   57Q                 ;/
; 
       DB   7*MLTSYN+CPYSYN     ;(EBCDIC 62-69) 
;                               ND ND ND ND 
;                               ND ND ND ND 
; 
       DB   5*MLTSTR+CPYSTR     ;(EBCDIC 6A-6F) 
       DB   174Q                ;BROKN VERTICAL BA
       DB   54Q,45Q,137Q        ;, % -
       DB   76Q,77Q             ;> ?
; 
       DB   8*MLTSYN+CPYSYN     ;(EBCDIC 70-78) 
;                               ND ND ND ND ND
;                               ND ND ND ND 
; 
       DB   7*MLTSTR+CPYSTR     ;(EBCDIC 79-80) 
       DB   140Q,72Q,43Q        ;' : #
       DB   100Q,47Q,75Q        ;@ ' =
       DB   42Q,SYNCI           ;' ND 
; 
       DB   8*MLTSEQ+CPYSEQ     ;(EBCDIC 81-89) 
       DB   141Q                ;A B C D E F G H I
; 
       DB   6*MLTSYN+CPYSYN     ;(EBCDIC 8A-90) 
;                               ND ND ND ND ND
;                               ND ND 
; 
       DB   8*MLTSEQ+CPYSEQ     ;(EBCDIC 91-99) 
       DB   152Q                ;J K L M N O P Q R
; 
       DB   6*MLTSYN+CPYSYN     ;(EBCDIC 9A-A0) 
;                               ND ND ND ND ND
;                               ND ND 
; 
       DB   0*MLTSTR+CPYSTR     ;(EBCDIC A1)
       DB   176Q                ;TILDA
; 
       DB   7*MLTSEQ+CPYSEQ     ;(EBCDIC A2-A9) 
       DB   163Q                ;S T U V W X Y Z
; 
       DB   21*MLTSYN+CPYSYN    ;(EBCDIC AA-BF) 
;                               ND ND .... ND ND
; 
       DB   0*MLTSTR+CPYSTR     ;(EBCDIC C0)
       DB   173Q                ;LEFT-BRACE 
; 
       DB   8*MLTSEQ+CPYSEQ     ;(EBCDIC C1-C9) 
       DB   101Q                ;A B C D E F G H I
; 
       DB   5*MLTSYN+CPYSYN     ;(EBCDIC CA-CF) 
;                               ND ND ND ND ND ND 
; 
       DB   0*MLTSTR+CPYSTR     ;(EBCDIC D0)
       DB   175Q                ;RIGHT-BRACE
; 
       DB   8*MLTSEQ+CPYSEQ     ;(EBCDIC D1-D9) 
       DB   112Q                ;J K L M N O P Q R
; 
       DB   5*MLTSYN+CPYSYN     ;(EBCDIC DA-DF) 
;                               ND ND ND ND ND ND 
; 
       DB   1*MLTSTR+CPYSTR     ;(EBCDIC E0-E1) 
       DB   134Q,SYNCI          ;BACKSLASH ND 
; 
       DB   7*MLTSEQ+CPYSEQ     ;(EBCDIC E2-E9) 
       DB   123Q                ;S T U V W X Y Z
; 
       DB   5*MLTSYN+CPYSYN     ;(EBCDIC EA-EF) 
;                               ND ND ND ND ND
; 
       DB   9*MLTSEQ+CPYSEQ     ;(EBCDIC F0-F9) 
       DB   60Q                 ;0 1 2 3 4
;                               5 6 7 8 9 
; 
       DB   5*MLTSYN+CPYSYN     ;(EBCDIC FA-FF) 
;                               ND ND ND ND ND ND 
; 
       DB   STOPER              ;TERMINATES TABLES
 
;*************************************************
; 
;   INITDC
;        INITIALIZE DATA COMMUNICATIONS 
; 
;   ENTRY     DATACOM INTERRUPTS DISABLED 
; 
;   EXIT      A DESTROYED 
;             ALWAYS RETURNS NC 
;             B,C = # CONTIGUOUS BYTES NEEDED FOR 
;                  DATACOM BUFFERS (NOTE B,C ALSO 
;                  SAVED IN BUFLOC) 
; 
;*************************************************
; 
;   ENTRY POINT 
; 
;   CALCULATE REQUIRED BUFFER SIZE
;   # BYTES = 512 * (2**N) + 256+128, WHERE 
;        N=JC1SIZ JUMPERS AND EXTRA 384 BYTES 
;        INCLUDED ONLY IF HCODE JUMPER SET
; 
INITDC:LDA  IODC+JC1  ;DATACOM JUMPER #1
       RLC            ;WANT BUFFER SIZE (BUFSIZ)
       RLC            ;RIGHT JUSTIFIED
       CALL SHIFT     ;CALCULATE 1*(2**A) 
       RLC            ;RESULT IS # BUFFERS TO GET 
;                     (00=2, 01=4, 10=8, 11=16) 
; 
;   ADD IN TRANSLATION TABLE SIZE IF NECESSARY
; 
INIS10:PUSH H         ;H,L = # BYTES TO REQUEST 
       MOV  H,A       ;(NOTE H=# 256 BYTE BUFFERS 
       MVI  L,0       ;L=0 FOR 256 ALIGNMENT) 
       LDA  IODC+JC0  ;DATACOM JUMPER #0
       ANI  HCODE     ;IF HCODE JUMPER SET
       MOV  C,A       ;THEN B,C = 384=128+256 
       RLC            ;ELSE B,C = 0 
       MOV  B,A 
       DAD  B         ;H,L = TOTAL # BYTES
; 
       SHLD BUFLOC    ;SAVE FOR INI2DC
       MOV  B,H       ;RET BUFFER REQUEST IN B,C
       MOV  C,L 
       POP  H 
       RET
 
;*************************************************
; 
;   INI2DC
;        INITIALIZE DATA COMMUNICATIONS 
; 
;   ENTRY     DATACOM INTERRUPTS SHOULD BE
;             DISABLED UNTIL AFTER CALL TO INI2DC 
; 
;             D,E = STARTING ADDRESS OF DATA COM
;                  BUFFER SPACE 
;             BUFLOC = # OF BYTES REQUESTED BY
;                  INITDC 
;             NOTE THAT 256 ALIGNMENT IS REQUIRED 
;                  AT THE TOP OF SPACE ALLOCATED
;                  (IE, D,E + BUFEND MUST RESULT
;                  IN A 0 LOW ORDER BYTE) 
; 
;   EXIT      A,D,E DESTROYED 
;             NC   NO ERRORS DETECTED 
;             C    ERROR = NO MULTIPOINT CARD 
;                  H,L = ADDR OF ERROR MESSAGE
; 
;*************************************************
;   COMPUTE BUFFER AND TRANSLATE TABLE LOCATIONS
;        ENTRY     D,E = STARTING ADDRESS 
;                  BUFLOC = # BYTES REQUESTED 
;        EXIT      HCODE JUMPER OFF 
;                  BUFBEG = D 
;                  BUFEND = (D + #BUFFS) - 1
; 
;                  HCODE JUMPER ON
;                  HEXOUT = D,E 
;                  HEXIN  = D+1 
;                  BUFBEG = D+2 
;                  BUFEND = (D+2 + #BUFFS) - 1
;             IN EITHER CASE, BUFMAX=0,1,3, OR 7
;                  AS GIVEN BY BLKSIZ 
 
; 
;   ENTRY POINT 
; 
INI2DC:PUSH H         ;SAVE CALLER'S REGS 
; 
       LHLD BUFLOC    ;D,E = # BYTES REQUESTED
       XCHG           ;H,L = STARTING ADDR
       MOV  A,E       ;HCODE JUMPER ON ?
       ANA  A         ;(YES,#BYTES NOT 256 ALIGNED
       JZ   INIZ10    ;NO, BRANCH 
; 
;   HERE TO SET UP TRANSLATE TABLE ADDRESSES
; 
       SHLD HEXOUT    ;HEXOUT TABLE = 1ST 128 BYTE
       INR  H         ;(ASSUMES TOP OF TABLE ON 
       MOV  A,H       ;256 BOUNDARY)
       STA  HEXIN     ;HEXIN TABLE = NEXT 256 BYTE
       INR  H         ;NEXT 256 CHUNK = 1ST BUFFER
       DCR  D         ;ADJUST #256 CHUNKS REQUESTE
;                     TO REFLECT ONLY # BUFFS 
; 
;   HERE TO SET UP BUFFER BOUNDARIES
; 
INIZ10:MOV  A,H       ;STARTING ADDRESS,LESS TABLE
       STA  BUFBEG    ;ADDR OF 1ST 256-BYTE BUFFER
       ADD  D         ;PLUS # BUFFERS REQUESTED 
       DCR  A         ;(ADJUST TO LOWER ADDR) 
       STA  BUFEND    ;ADDR OF LAST 256-BYTE BUFFE
; 
;   HERE TO SET UP BUFMAX 
;   (MAXIMUM # BUFFERS PER OUTPUT BLOCK)
; 
       LDA  KBJMP3    ;KEYBOARD DATACOM JUMPERS 
       RRC            ;WANT BLOCK SIZE (BLKSIZ) 
;                     RIGHT JUSTIFIED 
       DCR  A         ;MAP 0->3, 1->0, 2->1, 3->2 
       CALL SHIFT     ;CALCULATE 1*(2**A) 
;                     RESULT: 1,2,4 OR 8
       CMP  D         ;BLKSIZ SHOULD BE LESS THAN 
       JC   INIZ20    ;THE # BUFFERS REQUESTED
       MOV  A,D       ;IF NOT, TAKE MAX ALLOWED 
       RAR            ;2->1, 4->2, 8->4, 16->8
INIZ20:DCR  A         ;(PUTDC WANTS TO DCR BUFCNT 
;                     AND JUMP ON MINUS)
       STA  BUFMAX    ;MAX #BUFFERS IN
;                     TRANSMISSION BLOCK
; 
       POP  H         ;FALL INTO "SOFT RESET" 
 
;************************************************ 
; 
;   INIRST
;        "SOFT RESET" - ALL DATACOM INIT
;        EXCEPT BUFFER ALLOCATION 
; 
;   ENTRY     MUST ENTER WITH INTERRUPTS DISABLED 
; 
;   EXIT      A DESTROYED 
;             INTERRUPTS AS AT ENTRY
; 
;************************************************ 
INIRST:PUSH B         ;SAVE CALLER'S REGS 
       PUSH D 
       PUSH H 
; 
;   INITIALIZE RAM AREAS
;   SPECIFICALLY, COPY1 --> COPY1+NCOPY1-1
;                 COPY2 --> COPY2+NCOPY2-1
; 
       LXI  H,RAMTBL  ;SOURCE OF COPY = RAMTBL
       LXI  D,COPY1   ;DESTINATION OF COPY
       MVI  C,NCOPY1-1  ;# BYTES TO COPY, LESS 1
       CALL CPYTBL    ;COPY THE TABLE 
; 
;                     SOURCE OF COPY = RAMTB2 
       LXI  D,COPY2   ;DESTINATION OF COPY
       MVI  C,NCOPY2-1  ;# BYTES TO COPY, LESS 1
       CALL CPYTBL    ;COPY THE TABLE 
; 
       LXI  H,CMFLGS  ;DATACOM IS NOW IN CONTROL
       MOV  A,M       ;MODE, SO MUST TURN ON
       ORI  BLKTRG    ;BLOCK-TRIGGER MODE FOR 
       MOV  M,A       ;MAINCODE 
; 
;   CHECK FOR DIAGNOSTIC HOOKS
; 
       LDA  IODC0+IODCST  ;DIAGNOSTIC HOOKS 
       STA  DCFLGS    ;SET DIAGNOSTIC FLAGS 
       ANA  A         ;DIAGNOSTIC DC BOARD ?
       JNZ  DIAGDC    ;YES, GO TO DIAGNOSTIC INIT 
; 
       MVI  A,STBLMD  ;SET PERMANENT BLOCK MODE 
       CALL ZKBCTL    ;KEYBOARD CONTROL ROUTINE 
; 
       STA  IODC+RTIME  ;START DATACOM TIMER
       STA  IODC+STIME
; 
       LDA  IODC+JC0  ;DATACOM JUMPER #0
       MOV  B,A 
       ANA  A         ;EBCDIC TRANSMISSION ?
       JP   INIT99    ;NO, SKIP TRANSLATE TBL INIT
 
;   THIS SECTION EXPANDS CODE TRANSLATION TABLES
;   CONSULT DEFINITION OF XTABLE FOR DESCRIPTION
;   OF COMPRESSED TABLE FORMAT. 
; 
;   ENTRY     HEXOUT = ADDR OF 128-ALIGNED BLOCK
;                  TO BE USED FOR ASCII TO EBCDIC 
;                  TRANSLATE TABLE
;             HEXIN = ADDR OF 256-ALIGNED BLOCK 
;                  TO BE USED FOR EBCDIC TO ASCII 
;                  TRANSLATE TABLE
;             CAUTION: HEXIN MUST = HEXOUT+128
; 
; 
       LHLD HEXOUT    ;D,E = ADDR OF 1ST BYTE IN
       XCHG           ;ASCII TO EBCDIC TRANSLATE
;                     TABLE (128 ALIGNED) 
       LXI  H,XTABLE-1  ;H,L=ADDR OF 1ST BYTE IN
;                     COMPRESSED TRANSLATE TABLE
       PUSH B         ;SAVE DATACOM JUMPERS 
 
; 
;   LOOP TO EXPAND XTABLE ONE 
;   COMPRESSION CODE AT A TIME
; 
INITRN:INX  H         ;PT TO NXT COMPRESSION CODE 
INIT10:CMP  A         ;SET CARRY TO 0 
       MOV  A,M       ;FETCH NEXT COMPRESSION CODE
       RAR            ;OPCODE = SET-TO-SYNC ? 
       MOV  C,A       ;ASSUME YES, C=# OF SYNC BYT
       MVI  A,SYNCI   ;SET UP TO STORE (C) SYNC'S 
       MVI  B,0       ;(DON'T INR THE CONSTANT) 
       JC   INIT20    ;BRANCH WHEN SET-TO-SYNC COD
; 
;   HERE WHEN OPCODE = SEQUENTIAL-STRING
;                 OR = EXCEPTION-STRING 
; 
       INX  H         ;IN EITHER CASE, WILL NEED
;                     H,L POINTING TO NEXT BYTE 
       MOV  A,C       ;RESTORE COMPRESSION CODE 
       RAR            ;OPCODE = SEQUENTIAL-STRING?
       JNC  INIT30    ;NO 
       MOV  C,A       ;YES, C=# BYTES IN STRING 
       MOV  A,M       ;FIRST # IN THE STRING
       INR  B         ;SEQUENTIAL-STRING =
;                     (A), (A)+1, (A)+2,... 
; 
;   HERE WHEN OPCODE = SET-TO-SYNC
;                 OR = SEQUENTIAL-STRING
; 
INIT20:CALL CONSTI    ;EXPAND THE STRING
       JMP  INITRN    ;CONTINUE WITH NEXT OPCODE
; 
;   HERE WHEN OPCODE = EXCEPTION-STRING 
; 
INIT30:RAR            ;OPCODE = EXCEPTION-STRING? 
       JNC  INIT40    ;NO THEN JUST SAW TERMINATOR
       MOV  C,A       ;YES, C=# BYTES IN STRING 
       CALL CPYTBL    ;COPY STRING INTO TABLE 
       JMP  INIT10    ;CONTINUE WITH NEXT OPCODE
; 
;    HERE WHEN DONE 
; 
INIT40:POP  B         ;RESTORE DATACOM JUMPERS
INIT99 EQU  $ 
 
;   THIS SECTION COMPUTES THE BAUD RATE FROM THE
;   KEYBOARD DATACOM SWITCHES; OPERATES CH
; 
;   1)   MAPS KBDBAU (BITS 7,3,2,1) OF KBDCSW 
;        (KEYBOARD DC SWITCHES) INTO CT1BAU 
;        (BITS 3,2,1,0) OF IODC+OCTL1 (DC BOARD)
;        ACCORDING TO THE FOLLOWING MAPPING:
;             (0,1,2,...,7)  -->  (11,12,...,17,0)
;             (10,11,...,14) -->  (1,2,...,5) 
;             (15)           -->  (10)
;             (16,17)        -->  (6,7) 
; 
;   ENTRY     B = IODC+JC0
; 
;   EXIT      B = IODC+JC0   DATACOM JUMPER #0
;             C = IODC+JC1   DATACOM JUMPER #1
;             D = KBDCSW      KEYBOARD DC SWITCHES
;             E = BAUD RATE, MAPPED, RT-JUSTIFIED 
; 
       LDA  IODC+JC1  ;DATACOM JUMPER #1
       MOV  C,A 
       LDA  KBDCSW    ;KEYBOARD DATACOM SWITCHES
       MOV  D,A 
; 
;   COLLECT BAUD BITS INTO LOWER HALF OF A
; 
       ANI  KBDBAU    ;CLEAR ALL BUT BAUD (7321)
       XRI  200Q      ;FLIP SENSE OF HI/LO SWITCH 
       JP   INIBAU    ;JUMP IF D7 IS OFF
       ORI  020Q      ;IF D7 ON, TURN ON D4 
INIBAU:RRC            ;BITS COLLECTED, NOW RT-JUST
       ANI  CT1BAU    ;AND CLEAR LEFT HALF
; 
;   NOW DO THE MAPPING
; 
       CPI  10Q       ;BRANCH TO INIB10 IF
       JP   INIB10    ;(A) < 10B AND
       CPI  5         ;(A) > 4
       JM   INIB10
;                     WHEN HERE MUST BE 5,6 OR 7
       JNZ  INIB20    ;NO CHANGE IF 6 OR 7
       MVI  A,10Q-1   ;5 MAPS TO 10 
; 
INIB10:INR  A         ;MAP (A) TO (A)+1 
       ANI  CT1BAU    ;MOD 20B
; 
INIB20:MOV  E,A       ;MAPPING DONE 
 
;   THIS SECTION SETS UP CONFIG, IODC+OCTL1,
;        CTL2, WRUSTS+0, WRUSTS+1 AND ASACNT
; 
;   0)   TURN ON CH IF KB3CH=1
;        ENABLE DOWNLINE CB & CA
;        NO MONITOR MODE; CD ON; SA,CA OFF
; 
;   1)   CONFIG FLAGS HCODE,CRC16,M3270 ARE COPIES
;        OF D7,D6,D5 OF DATACOM JUMPER #0 
;        (NOTE THAT M3270 IS TURNED OFF BY
;        LDR-HDR ROUTINE IF RUNNING WITH
;        ASYNCRONOUS DATACOM CARD)
; 
;   2)   CONFIG FLAG PMASK: 
;             PMASK = (KBDPAR OR KB3PMS OR CRC16) 
;                  AND (NOT HCODE)
;        PMASK & HCODE MUST BE MUTUALLY EXCLUSIVE 
; 
;   3)   CONFIG FLAGS VRC2,VRC1 ARE GIVEN BY
;        A)   VRC=00    IF INPUT=1X0 (FORCE 0)
;        B)   VRC=01    IF INPUT=00X (ODD PARITY) 
;        C)   VRC=10    IF INPUT=01X (EVEN PARITY)
;        D)   VRC=11    IF INPUT=1X1 (FORCE 1)
;        WHERE "X" MEANS DON'T CARE AND "INPUT" 
;             REFERS TO THE 3 BITS KBDPAR,
;             KBDODD,KB3PMS, REPECTIVELY
; 
;   4)   # OF DATA BITS (CT1ND2 & CT1ND1) 
;        # OF BITS = 8 WHEN ANY OF THE FOLLOWING
;             BITS ARE = 1: HCODE, CRC16, 
;                           KB3PMS, KBDPAR
;        OTHERWISE # DATA BITS = 7
; 
;   5)   CT1PAR=0 (ENABLE) IF #DATA BITS = 7
;             OTHERWISE CT1PAR=1 (DISABLE PARITY) 
;        CT1ODD=KBDODD (0=ODD)
; 
;   6)   WHO-ARE-YOU STATUS BYTE #1:
;             BITS 3-0 = BAUD RATE
;             BITS 5-4 = VRC2,VRC1
;             BIT  6   = 1
; 
;   7)   WHO-ARE-YOU STATUS BYTE #2:
;             BIT  0   = BLKIN
;             BITS 2-1 = BUFSIZ 
;             BIT  3   = M3270
;             BIT  4   = CRC16
;             BIT  5   = HCODE
;             BIT  6   = 1
; 
;   8)   ASACNT = 1 IF KB3CC = 0
;             (NON-CONTINUOUS CARRIER)
;        ASACNT=ABORTT IF KB3CC=1 
;             (CONTINUOUS CARRIER)
; 
;   ENTRY     B = IODC+JC0   DATACOM JUMPERS
;             C = IODC+JC1
;             D = KBDCSW     KEYBOARD DC SWITCHES 
;             E = BAUD RATE 
; 
;   EXIT      B,C UNMODIFIED; D,E,L DESTROYED 
;             H = CONFIG FLAGS
 
; 
;   OPERATE CH (#0 ABOVE) 
; 
       LDA  KBJMP3    ;KEYBOARD DATACOM JUMPERS 
       MOV  L,A 
       ANI  KB3CH     ;WANT JUST CH BIT 
       RRC            ;MOVE TO CT2CHZ POSITION
       RRC
       XRI  CT2CAZ+CT2SAZ+CT2CHZ
;                     (TURN ON CH IF KB3CH=1) 
       STA  CTL2
; 
;   SET UP ASACNT (SEE #8 ABOVE)
; 
       MOV  A,L       ;KEYBOARD DATACOM SWITCHES
       ANI  KB3CC     ;CONTINUOUS CARRIER?
       JZ   INICNT    ;NO, TIMER ALREADY=40MSECS
       MVI  A,ABORTT  ;YES, SET ABORT TIMER=ABORTT
       STA  ASACNT    ;(ABORT TIMER COUNT)
INICNT EQU  $ 
; 
;   SET UP CONFIG FLAGS (#1 ABOVE)
; 
       MOV  A,B       ;DATACOM JUMPER #0
       ANI  HCODE+CRC16+M3270 
       MOV  H,A       ;CONFIG FLAGS 
; 
;   WHO-ARE-YOU STATUS BYTE #2  (#7 ABOVE)
; 
       MOV  A,C       ;DATACOM JUMPER #1
       ANI  BUFSIZ+BLKIN     ;CLEAR OTHER JUNK
       RRC            ;SHIFT RIGHT
       RRC            ;TO MAKE ROOM FOR 
       RRC            ;HCODE,CRC16,M3270
       ORA  H         ;COLLECT JUMPERS 0 & 1
       STC            ;ALWAYS SET BIT #6
       RAR            ;RIGHT JUSTIFY THE STUFF
       RRC
       STA  WRUSTS+1  ;COMPLETED WRU STATUS #2
; 
;   SET UP VRC1 & VRC2 (#3 ABOVE) 
; 
       MOV  A,D       ;KEYBOARD DATACOM SWITCHES
       ANI  KBDPAR    ;PARITY ODD OR EVEN?
       JZ   INIP10    ;YES,BRANCH 
; 
;   HERE IF PARITY DISABLED 
; 
       MOV  A,L       ;KEYBOARD DATACOM JUMPERS 
       ANI  KB3PMS    ;CHECK FORCE PARITY SWITCH
       RLC            ;KB3PMS=0, VRC2=0, VRC1=0 
       RAL            ;KB3PMS=1, VRC2=1, VRC1=1 
       JMP  INIP20
; 
;   HERE IF PARITY ENABLED
; 
INIP10:MOV  A,D       ;KEYBOARD DATACOM SWITCHES
       ANI  KBDODD    ;JUST ODD/EVEN BIT
       RLC
       RLC            ;SHIFT KBDODD BIT INTO CARRY
       RLC
       RAL            ;KBDODD=0, VRC2=0, VRC1=1 
       ACI  VRCODD    ;KBDODD=1, VRC2=1, VRC1=0 
; 
;   HERE WHEN HAVE VRC MASK SET UP
; 
INIP20:ORA  H         ;COLLECT CONFIG FLAGS 
       MOV  H,A       ;DONE WITH CONFIG 
; 
;   WHO-ARE-YOU STATUS BYTE #1  (#6 ABOVE)
; 
       ANI  VRC2+VRC1  ;WANT JUST VRC2 & VRC1 
       RRC            ;LEFT JUSTIFY 
       RRC
       STC            ;ALWAYS SET BIT #6
       RAR
       RRC            ;NOW HAVE BIT#6 & VRC 
       ORA  E         ;COLLECT BIT#6, VRC & BAUD
       STA  WRUSTS    ;COMPLETE WRU STATUS #1 
; 
;   SET UP CONFIG FLAGS (SEE#2 ABOVE) 
; 
       MOV  A,D       ;KEYBOARD DATACOM SWITCHES
       RLC            ;MOVE KBDPAR TO SIGN BIT
       RLC
       ORA  L         ;KBDPAR OR KB3PMS 
       RRC            ;MOVE TO CRC16 POSITION 
       ORA  H         ;KBDPAR OR KB3PMS OR CRC16
       RLC            ;MOVE BACK TO SIGN BIT
       MOV  L,A       ;L=KBDPAR OR KB3PMS OR CRC16
       CMA            ;IF HCODE = 1, THEN 
       ORA  H         ;MUST FORCE PMASK = 0 
       MOV  A,H       ;(FETCH CONFIG FLAGS) 
       JM   INIPMS    ;IF HCODE=0 AND KBDPAR=1 OR 
       ORI  PMASK     ;KB3PMS=1 OR CRC16=1 THEN 
       MOV  H,A       ;SET PMASK IN CONFIG
INIPMS EQU  $ 
; 
;   SET UP # OF DATA BITS (#4 ABOVE)
;   SET UP CT1PAR (#5 ABOVE)
; 
       ORA  L         ;KBDPAR OR KB3PMS OR CRC16
;                     OR HCODE
       MVI  A,CT1D7   ;IF ALL THOSE ARE 0, THEN 
       JP   INIP30    ;#DATA BITS=7, ENABLE PARITY
       MVI  A,CT1D8+CT1PAR   ;IF ANY=1, THEN #DATA
;                            BITS=8, NO PARITY
; 
;   HERE WHEN HAVE #DATA & PARITY 
; 
INIP30:ORA  E         ;COLLECT BAUD,#DATA,PARITY
       MOV  E,A 
; 
;   SET UP CT1ODD (SEE #5 ABOVE)
;   INITIALIZE IODC+OCTL1 + CTL1
; 
       MOV  A,D       ;KEYBOARD DATACOM SWITCHES
       ANI  KBDODD    ;GET ODD/EVEN BIT 
       ORA  E         ;COLLECT BAUD,#DATA,PARITY
       STA  CTL1
       STA  IODC+OCTL1   ;DATACOM BOARD 
 
;   1)   SET UP LDR & HDR AS FUNCTIONS OF 
;        SYNC/ASYNC AND IBM 3270 MODE:
;             A)   SYNC & 3270    LDR, 3270 HDR 
;             B)   SYNC           LDR, SHORT HDR
;             C)   ASYNC & 3270   LDR, SHORT HDR
;             D)   ASYNC          SHORT HDR 
;        ENTAID = COPY OF 1ST 2 BYTES OF 3270 
;        MODE HEADER EXTENSION (IE, THE 
;        ENTER-SPACE COMBINATION) 
; 
;   2)   TURN OFF M3270 CONFIG BIT IF ASYNC CARD
; 
;   ENTRY     B = IODC+JC0   DATACOM JUMPERS
;             C = IODC+JC1
;             H = CONFIG FLAGS
; 
;   EXIT      B,C UNMODIFIED
;             D,E,H,L DESTROYED 
;             CONFIG STORED 
; 
       LDA  IODC+ST2  ;DATACOM STATUS 
       ANI  ST2SYC    ;1 = SYNCRONOUS CARD
       MOV  L,A       ;(SAVE SYNC/ASYNC BIT)
; 
       RRC            ;MOVE TO M3270 POSITION 
       ORI  377Q-M3270  ;BITS TO LEAVE ON 
       ANA  H         ;M3270 BIT OFF IF ASYNC 
       STA  CONFIG    ;ALL DONE WITH CONFIG FLAGS 
; 
       MOV  A,B       ;DATACOM JUMPER #0
       ANI  M3270     ;3270 MODE BIT
       ORA  L         ;COLLECT THE 2 BITS 
       JNZ  INIHDR
; 
;   NO LEADER (OR SYNC FILL) IF ASYNC & NOT 3270
; 
       LXI  H,LDR     ;ASSUME LDR ALREADY SET UP
       MVI  M,STOPER  ;PUT TERMINATOR IN 1ST BYTE 
; 
INIHDR:CPI  ST2SYC+M3270     ;BOTH SYNC & 3270? 
       JZ   INIH99    ;YES, LEAVE 3270 HDR SET UP 
; 
;   SHORT HEADER UNLESS BOTH SYNC & 3270 MODE 
; 
       LXI  H,STOPER  ;H,L = STOPER'S 
       SHLD ID2+1     ;TERMINATE SHORT HEADER 
       SHLD ENTAID    ;COPY OF ENTER-SPACE
; 
INIH99 EQU  $         ;DONE WITH HEADER JUNK
 
;   THIS SECTION SETS UP DEVICE & GROUP IDS 
; 
;        GID  = GROUP ID + "@" (OR = SPACE
;               IF JUMPER ID > 32B) 
;        DID  = DEVICE ID, AS ABOVE 
;        SID  = GID, CONVERTED TO LOWER CASE
;               (OR = DASH IF GID = SPACE)
;        GID ALSO COPIED INTO  SLFID, CTLTBL
;        DID ALSO COPIED INTO SLFID+1,CTLTBL+4, 
;             CTLTBL+5
; 
;   ENTRY     B = IODC+JC0    DATACOM JUMPERS 
;             C = IODC+JC1
;             CONFIG SET UP 
; 
;   EXIT      B,C UNMODIFIED
;             D,E,H,L DESTROYED 
; 
       MOV  A,B       ;DATACOM JUMPER #0
       CALL INIDS     ;COMPUTE GROUP ID 
       MOV  L,A       ;GROUP ID 
       CPI  SPACEI    ;CHECK FOR SPECIAL CASE 
       JNZ  INII10    ;NOT SPACE SKIP SPECIAL CASE
       MVI  A,DASHI   ;IF GRP ID = SPACE, 
;                     THEN SELECT ID = DASH 
;                     WARNING: ASSUMES DASHI OR'D 
;                     WITH LOWERI GIVES DASHI 
INII10:ORI  LOWERI    ;CONVERT @-Z TO LOWER CASE
       MOV  D,A       ;SELECT GROUP ID
       MOV  A,C       ;DATACOM JUMPER #1
       CALL INIDS     ;COMPUTE DEVICE ID
       MOV  H,A       ;DEVICE ID
; 
       SHLD GID       ;STORE DID AND GID
       SHLD SLFID     ;STORE DID AND GID
       MOV  E,L       ;D=SELECT ID; E=GROUP ID
       MOV  L,H       ;H,L=DEVICE ID
       SHLD CTLTBL+4  ;STORE DID AND DID
       XCHG 
       SHLD CTLTBL    ;STORE SID AND GID
 
; 
;   SET UP FLAG 
; 
;   ENTER     C = IODC+JC1   DATACOM JUMPER 
; 
       MOV  A,C       ;DATACOM JUMPER #1
       ANI  BLKIN     ;ALL OTHER FLAG BITS
       STA  FLAG      ;INIT'D BY THEIR USERS
; 
;   SET UP BCC TRANSMISSION STRING
; 
;   ENTER     B = IODC+JC0
; 
       MOV  A,B       ;DATCOM JUMPER #0 
       ADD  A         ;IS BCC TO BE A CRC OR LRC ?
       JM   INIBCC    ;IF CRC16, ALREADY SET UP 
       LXI  H,BCSTOP  ;IF LRC, SHORTEN BCC STRING 
       DCR  M         ;(ADDR OF LAST BYTE IN BCC) 
       LHLD ASBCC+2   ;MOVE THE TPAD,0 LEFT 
       SHLD ASBCC+1   ;ONE BYTE 
       MOV  A,L       ;IF LRC,
       STA  ASBCC0+1  ;INITIAL BCC = 0,TPAD 
INIBCC EQU  $ 
 
; 
;   TRANSLATE, OR COMPUTE PARITY, 
;   FOR CONTROL CHARACTERS IN RAM TABLES
;   MUST BE DONE AFTER GROUP/DEVICE ID &
;   BCC STRING ARE SET UP 
; 
;   ENTER     B = IODC+JC0
; 
       PUSH B         ;SAVE DATACOM JUMPERS 
       LXI  H,XLAT1   ;BEG OF AREA TO TRANSLATE 
       MVI  E,NXLAT1-1  ;# BYTES, LESS 1
       CALL HEXPAR    ;TRANSLATE OR DO PARITY 
       POP  B         ;RESTORE DATACOM JUMPERS
; 
       MOV  A,B       ;DATCOM JUMPER #0 
       ANA  A         ;DID WE TRANSLATE THE TABLE?
       JP   INIE99    ;NO, BRANCH 
; 
;   SET UP ACK0E,ACK1E,WACKE,RVIE 
; 
       LXI  H,RVIACK  ;FIX UP BAD TRANSLATION OF
       SHLD RVI       ;ACK 0/1 WACK & RVI 
       LXI  H,ACKWAC  ;(THEY DON'T TRANSLATE
       SHLD ACK1      ;THROUGH TABLE CORRECTLY) 
; 
INIE99 EQU  $ 
 
; 
;   DEFINE SYNC CHARACTER 
;   MUST BE DONE AFTER CONTROL CHARACTER
;   TABLES ARE TRANSLATED 
; 
       LDA  SYNC      ;FETCH TRANLSATED SYNC CHAR 
       STA  IODC+DCSYN  ;TELL SYNC BOARD
; 
;   INITIALIZE BUFFERS
; 
       CALL BUFINI
; 
; 
; 
; 
;   ENTRY POINT 
;   HERE TO RETURN WITH NC & Z CONDITION
;   (WITHOUT ENABLING INTERRUPTS) 
; 
RTNCZ2:CMP  A         ;SET Z & NC CONDITION CODES 
       JMP  RTHDB2    ;AND RETURN 
;                     MUST NOT ENABLE INTERRUPTS
;                     (SEE MAINCODE)
 
;*************************************************
; 
;   DCMON 
;        OPERATE THE TRANSMIT LIGHT 
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A DESTROYED 
;             ALWAYS RETURS WITH NC & Z 
;             1)   IF RUNNING WITH CC-LIGHT OPTION
;                  TRANSMIT LIGHT TURNED ON IF CC 
;                  IS ON, ELSE LIGHT OFF
;             2)   IF NOT RUNNING WITH CC-OPTION
;                  LIGHT ON IF DATA COM ACTIVE. 
;                  ELSE LIGHT OFF 
; 
;*************************************************
; 
;   ENTRY POINT 
; 
DCMON: LDA  KBJMP3    ;KEYBOARD JUMPER 3 OPTIONS
       ANI  KB3CCL    ;WANT THE CC-LIGHT OPTION ? 
       JZ   DCM020    ;NO 
; 
;   HERE IF CC-LIGHT OPTION 
; 
       LDA  IODC+ST2  ;YES
       CMA            ;(ST2CCZ=1 IF CC ON)
       ANI  ST2CCZ    ;IS CC ON ? 
       JMP  DCM030    ;NZ= CC ON; Z= CC OFF 
; 
;      HERE IF NO CC-LIGHT OPTION 
; 
DCM020:LDA  ASFLAG    ;ARE WE DOING ANYTHING ?
       ANA  A         ;Z= NO; NZ= YES 
; 
;   HERE TO OPERATE THE LIGHT 
; 
DCM030:JNZ  ZSTXMT    ;NZ = TURN ON THE LIGHT 
       JMP  ZCLXMT    ;Z = TURN OFF THE LIGHT 
 
;************************************************ 
; 
;   DCCTL 
;        PROVIDE MISCELLANEOUS DATACOM CONTROLS 
; 
;   ENTRY     A =  0    CLEAR BLOCK TRANSFER
;                       TRIGGER FLAG
;                  1    SET BLOCK TRANSFER
;                       TRIGGER FLAG
;                  2    RESET DATACOM 
;                  3    NO-OP (SET REMOTE)
;                  4    NO-OP (SET LOCAL) 
;                  5    BREAK-KEY FUNCTIONS 
;                  6    MODEM DISCONNECT
;                  7    TERMINATE MESSAGE 
;                  8    ENTER MONITOR MODE
;                  9    LEAVE MONITOR MODE
;                       OR ENABLE KEYBOARD IN 
;                       DRIVER MODE 
;                 10    FAST BINARY TAPE READ 
;                 11    ENTER SINGLE CHAR AID 
;                       B = AID CHAR
;                 12    ENTER MULTI-CHAR AID
;                       B = AID CHAR
;                 13    INVALID (SEND PROMPT) 
; 
;   EXIT      A DESTROYED 
;             NC   Z    FUNCTION PERFORMED
;                  NZ   ILLEGAL CONTROL PARAMETER 
;             C    Z    CANNOT PERFORM FUNCTION 
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
DCCTL: CPI  DCMAX     ;FUNCTION PARAMETER LEGAL ? 
       RNC            ;NO, RETURN WITH NC & NZ
; 
       PUSH B         ;(SAVE SAME REGS AS INI2DC) 
       PUSH D 
       PUSH H 
 
; 
;   COMPUTE ADDRESS OF APPROPRIATE HANDLER
; 
       LXI  H,DCCTBL  ;ADDR OF DISPATCH TABLE 
       ADD  A         ;MULTIPLY FUNCTION # BY 2 
       MOV  E,A       ;D,E = OFFSET INTO
       MVI  D,0       ;DISPATCH TABLE 
       DAD  D         ;H,L = ADDR OF THE ADDR 
;                     OF THE FUNCTION HANDLER 
       MOV  E,M       ;NOW FETCH HANDLER ADDR 
       INX  H         ;FROM TABLE INTO D,E
       MOV  D,M 
; 
;   DISPATCH TO HANDLING ROUTINE
; 
;   EXIT      D,E = ADDR OF CMFLGS
;             A = B (ENTRY PARAMETER) 
;             B = 0 
;             C = BUFBC+BUFBCT
;             NC CONDITION CODE SET 
;             INTERRUPTS DISABLED 
; 
;   NOTE      HANDLERS SHOULD NORMALLY EXIT 
;             WITH "RET" INSTR (TO RETURN THROUGH 
;             RETNCZ) 
; 
       LXI  H,CMFLGS  ;SOME HANDLERS NEED CMFLGS
       XCHG           ;D,E=CMFLGS, H,L=HANDLER
       MOV  A,B       ;SOME HANDLERS NEED A=B 
       LXI  B,RETNCZ  ;PUT RETURN ADDR ON STACK 
       PUSH B         ;FOR EASIER RETURNS 
       LXI  B,BUFBC+BUFBCT   ;B=0 
;                     C=BUFBC+BUFBCT
       DI             ;** DISABLE INTERRUPTS ** 
       PCHL           ;DISPATCH TO HANDLER
 
; 
;   CLEAR BLOCK TRIGGER 
; 
DCCTRG:LDAX D         ;FETCH CMFLGS 
       ANI  377Q-BLKTRG  ;TURN OFF BLOCK-TRIGGER
       JMP  DCCBT     ;1ST CHECK FOR MPT/DIAG MODE
; 
;   SET BLOCK-TRIGGER 
; 
DCSTRG:LDAX D         ;FETCH CMFLGS 
       ORI  BLKTRG    ;TURN ON BLOCK-TRIGGER
; 
DCCBT: MOV  B,A       ;SAVE NEW CMFLGS
       LDA  DCFLGS    ;ONLY NEED TO OPERATE BLKTRG
       ANA  A         ;HERE FOR DIAGNOSTIC PROTOCO
       RZ             ;IF MULTIPOINT, DO NOTHING
       MOV  A,B       ;IF DIAGNOSTIC MODE,
       STAX D         ;STORE NEW BLOCK-TRIGGER
       RET            ;AND GOTO RETNCZ
; 
;   RESET DATACOM 
; 
DCCRST:CALL DCSTOP    ;WAIT FOR CURRENT DATACOM 
;                     OPERATION TO FINISH 
       CALL INIRST    ;ALWAYS RE-INIT THE WORLD 
DCNOOP:RET            ;JUMP TO RETNCZ 
;                     AND ENABLE INTERRUPTS 
; 
;   BREAK-KEY FUNCTIONS 
; 
DCCBRK:LDA  ASFLAG    ;BREAK-KEY NON-FUNCTIONAL IF
       ANA  A         ;DATACOM TRANSMITTING 
;                     OR RECEIVING
       CZ   BUFINI    ;IF ALL QUIET, CLEAN QUEUES 
       RET            ;AND GOTO RETNCZ
; 
;   MODEM DISCONNECT
; 
DCCMDC:LXI  H,DISCON  ;NXT INTERRUPT TO DISCONNECT
       JMP  DCC100    ;GO SET VECTOR AND EXIT 
; 
;   ENTER-AID 1 
; 
DCENT1:MVI  B,AIDFLG  ;SINGLE CHARACTER ENTER 
; 
;   ENTER-AID N 
; 
DCENTN:CPI  TPADI     ;IF CHAR >= 177B, ILLEGAL 
       JNC  RETPCZ    ;SO RETURN C & Z
;                     (NOTE, RETPCZ POPS STACK) 
       CPI  SPACEI    ;IF CHAR < 40B, ILLEGAL 
       JC   RETPCZ    ;SO RETURN C & Z
;                     (NOTE, RETPCZ POPS STACK) 
; 
       ORA  B         ;CHAR OK, ADD ENTER 1/N FLAG
       MOV  B,A 
; 
;   LOOP TO PUT ENTER-AID CHAR IN BUFFER
; 
DCENT: MOV  A,B       ;AID CHARACTER
       CALL PUTAID    ;TRY TO PUT CHAR IN BUFFS 
       JNZ  DCENT     ;IF OUTPUT BUFS FULL (NC&NZ)
;                     SET UP CHAR & "LAST" FLAG 
;                     AND TRY AGAIN 
       JC   RETPCZ    ;IF DC RECEIVING, RET C & Z 
;                     (NOTE, RETPCZ POPS STACK) 
       MOV  A,B       ;IF CHAR ACCEPTED, THEN 
       RAL            ;CHECK TO SEE IF "PA" OR "PF
       RNC            ;IF "PF", MORE DATA TO FOLLO
;                     (GOTO RETNCZ TO SET NC & Z) 
       JMP  DCCETX    ;IF CHAR ACCEPTED AND "PA"
;                     MUST TERMINATE BLK WITH ETX 
; 
;   HERE TO HANDLE FAST BINARY READ (ESC-E) 
;   WARNING: MAINCODE DOES NOT WAIT FOR 
;   BLKTRG=1 BEFORE STARTING THE BINARY 
;   TRANSFER.  (FOR NORMAL DATA TRANSFERS,
;   MAINCODE WAITS FOR BLKTRG).  THE "FSTBIN" 
;   ROUTINE SIMULATES THE NORMAL MAINCODE 
;   OPERATION BY CALLING GETDC (AND CHUCKING
;   INPUT CHARACTERS) UNTIL BLKTRG COMES ON.
;   NOTE THAT FSTBIN CALLED BEFORE PUTDC. 
;   ALSO NOTE THAT COULD GET CALL TO FSTBIN 
;   WHILE ALREADY IN TRANSMIT STATE.
; 
DCCFST:CALL GETDC     ;NEED TO PURGE BUFFERS
       LDA  CMFLGS    ;NEED TO WAIT FOR BLKTRG
       ANI  BLKTRG    ;(IE, WAIT FOR LINE TO
       JZ   DCCFST    ;TURN-AROUND) 
;                     CONTINUE THIS LOOP TILL 
;                     OK TO TRANSMIT
; 
;   TERMINATE CURRENT OUTPUT BLOCK WITH AN ETB
;   AND TOGGLE SENSE OF "BINARY SWITCH" 
;   ("START-BIN" AND "END-BIN" COME IN PAIRS) 
; 
DCCETB:LXI  H,FLAG    ;STBIN OR FSTBIN WANT TO
       MOV  A,M          ;TURN BINARY FLAG ON 
       XRI  BINARY    ;ENDBIN WANTS TO TURN 
       MOV  M,A          ;BINARY FLAG OFF 
;                     WARNING: ASSUMES THAT 
;                     STBIN (OR FSTBIN) WILL
;                     ALWAYS BE FOLLOWED BY 
;                     AN ENDBIN 
; 
       MVI  C,BUFBC   ;SET BUFFER FLAGS FOR 
;                     ETB BLOCK BOUNDARY
; 
;   TERMINATE CURRENT OUTPUT BLOCK WITH ETB/ETX 
;   (C FLAGS BLOCK BOUNDARY TYPE) 
;   WARNING: DCCETX ASSUMES THAT ENDBLK CALL
;   WILL OCCUR AFTER ENDBIN DURING BINARY OUTPUT
; 
DCCETX:DI             ;DON'T ALLOW INTERRUPTS WHIL
;                     TOUCHING THE QUEUES 
       LDA  ASBCNT    ;IF NOT IN TRANSMIT MODE, 
       ANA  A         ;THEN DON'T DO ANYTHING 
       CP   PUTBLK    ;(CALL MARKS LAST BUFFER IN 
;                     THE DQ AS HAVING A BLOCK
;                     BOUNDARY, AS GIVEN BY C)
       RET
 
; 
;   DISPATCH TABLE
; 
DCCTBL:DW   DCCTRG    ;CLRTRG - CLEAR BLK TRIGGER 
       DW   DCSTRG    ;SETTRG - SET BLK TRIGGER 
       DW   DCCRST    ;RSETDC - "SOFT-RESET"
       DW   DCNOOP    ;SETREM - NO-OP 
       DW   DCNOOP    ;SETLCL - NO-OP 
       DW   DCCBRK    ;PUTBRK - BREAK-KEY FUNCTION
       DW   DCCMDC    ;DISCNT - MODEM DISCONNECT
       DW   DCCETX    ;ENDBLK - TERMINATE MESSAGE 
       DW   DCICR     ;SETMON - INVALID REQUEST 
       DW   DCCNRM    ;SETNRM - NORMAL MODE 
       DW   DCCFST    ;FSTBIN - START BINARY OUTPU
       DW   DCENT1    ;SNDATN - ENTER AID-1 
       DW   DCENTN    ;SNDFCT - ENTER AID-N 
;      DFAD DCICR     PROMPT - INVALID REQUEST
;                     (DCMAX CMP CATCHES PROMPT)
; 
DCMAX  EQU  ($-DCCTBL)/2 ;# OF ENTRIES IN TABLE 
 
;************************************************ 
; 
;   GETDC 
;        GET ONE DATACOM CHARACTER
;        (HI-ORDER BIT GUARANTEED = 0)
; 
;   GETBIN
;        GET ONE BINARY DATACOM CHARACTER 
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      NC   NO ERRORS DETECTED 
;                  Z    A = DATACOM CHARCTER
;                  NZ   A <> 0 WAIT 
;                            (INPUT BUFFER EMPTY) 
;                       A = 0  END-OF-INPUT 
;                            (BUFFS NOW AVAIL 
;                            FOR TRANSMISSION)
;             C    DATACOM ERROR DETECTED 
;                  A DESTROYED
;                  ALWAYS RETURNS Z (NO MESSAGE)
;                  DATACOM RECEIVE ERROR
;                  (PROBABLY OVER-RUN OR PARITY)
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
GETBIN:MVI  A,377Q    ;8-BIT DATA CHARACTERS
       JMP  GETDC5
; 
;   ENTRY POINT 
; 
GETDC: MVI  A,177Q    ;7-BIT DATA CHARACTERS
; 
GETDC5:PUSH B         ;SAVE REGISTERS 
       PUSH D 
       PUSH H 
       MOV  B,A       ;CHARACTER BIT MASK 
; 
       LDA  DCFLGS    ;DIAGNOSTIC HOOKS 
       ORA  A         ;DIAGNOSTIC MODE ON ? 
       JNZ  DIA500    ;YES, BRANCH TO DIAGNOSTIC
 
; 
       DI             ;** DISABLE INTERRUPTS ** 
; 
       LDA  ASBCNT    ;ARE WE IN RECEIVE MODE 
;                     AND CAN WE CONSUME
       INR  A         ;(IE, IS THERE RECEIVED 
;                     DATA IN THE DQ?; IN OTHER 
;                     WORDS, IS ASBCNT < -1)
       JZ   GETLST    ;BRANCH IF WE JUST CAUGHT UP
;                     IN BLKIN MODE (CATCH UP IN
;                     NON-BLKIN MODE HANDLED
;                     BY CNSUMR)
       JP   WAIT      ;IF ASBCNT >= 0, RETURN= WAI
;                     (NO RECEIVE DATA IN QUEUE)
; 
;   HERE TO FETCH CHARACTER FROM BUFFER 
; 
GETCHR:CALL CNSUMR    ;LOOK FOR CHAR IN DQ
       JNZ  CHROK     ;GOT CHAR FROM BUFF = GOOD
       JC   CHRBAD    ;WHOOPS, RECEIVE ERROR
; 
;                     FALL THROUGH, DQ MUST BE
;                     EMPTY OR REACHED BOUNDARY 
GETLST:LDA  ASFLAG    ;IF RCVN SET DOESN'T MATTER 
       ANI  RCVN      ;WHETHER DQ EMPTY OR
       JNZ  RETHDB    ;BOUNDARY SET,
;                     WE SHOULD ALWAYS WAIT 
; 
; 
;   WHEN HERE, CONSUMER HAS CAUGHT UP WITH
;   THE PRODUCER; ITS THE TIME TO TURN OVER THE 
;   BUFFERS TO TRANSMITTER (ENABLE PUTDC) 
; 
; 
       LXI  H,CMFLGS  ;TELL MAINCODE THAT IT IS 
       MOV  A,M       ;NOW OK TO TRANSMIT 
       ANI  377Q-RCVMDE      ;(TURN OFF RCVMDE) 
       ORI  BLKTRG           ;(TURN ON BLKTRG)
       MOV  M,A       ;(ENTER-KEY OK) 
; 
       CALL BUFINI    ;NORMALLY, DATA QUEUE WILL
;             BE EMPTY AT THIS POINT; BUT NEED
;             THIS TO CLEAN UP IN BLKIN MODE
;             (EG, ASYNC PROCESSOR DOES PUTE; 
;             OR DABORT ON FIRST BLOCK) 
; 
       ORI  1         ;SET NZ,NC & A=0
       MVI  A,0       ;TO SIGNAL END-OF-INPUT 
       JMP  RETHDB    ;EI, POPS AND RET 
 
; 
;   ENTRY POINT 
;   HERE TO POP STACK AND RETURN NC & NZ
; 
DCICR  EQU  $         ;DCCTL INVALID CTL REQUEST
RPNCNZ:POP  H         ;POP STACK + SET NC & NZ
; 
;   ENTRY POINT 
;   HERE TO RETURN WAIT CONDITION (NC+NZ) 
;   (A DESTROYED) 
; 
RTNCNZ EQU  $         ;SET NC & NZ
WAIT:  ORI  1         ;SET NZ & NC CONDITION CODES
       JMP  RETHDB
 
;************************************************ 
; 
;   PUTDC 
;        OUTPUT CHARACTER TO DATACOM
; 
;   PUTAID
;        PASS AID CHARACTER TO DATACOM
; 
;   ENTRY     A = CHARACTER TO OUTPUT 
;             NC   NORMAL CHARACTER 
;             C    TERMINATING CHARACTER
; 
;   EXIT      A DESTROYED 
;             NC
;                  Z    CHARACTER ACCEPTED
;                  NZ   WAIT-1 CAN'T ACCEPT CHAR
;                       BECAUSE OUTPUT BUFFS FULL 
;             C 
;                  Z    WAIT-2 CAN'T ACCEPT CHAR
;                       BECAUSE DATACOM IS IN 
;                       RECEIVE MODE
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
PUTAID:PUSH B         ;SAVE CALLER'S REGS 
       MVI  B,PAPFKY
       JMP  PUTINI    ;HAVE ENTER-AID FLAG SET
; 
;   ENTRY POINT 
; 
PUTDC: PUSH B         ;SAVE CALLER'S REGS 
       MVI  B,0       ;NO TRANSPARENT FLAG
; 
; 
;   PUTDC FLAG DEFINITIONS
; 
PAPFKY EQU  200Q      ;"PA" / "PF" KEY
;                     ASSUMED = 001B
 
PUTINI:PUSH D         ;SAVE REST OF CALLER'S REGS 
       PUSH H 
       MOV  D,A       ;SAVE INPUT CHAR IN D 
; 
       LDA  DCFLGS    ;DIAGNOSTIC HOOKS 
       ORA  A         ;DIAGNOSTIC MODE ON ? 
       JNZ  DIA700    ;YES, BRANCH TO DIAGNOSTIC
; 
       LXI  H,FLAG    ;TRANSMIT BUFFER FLAGS
       MOV  C,M       ;SAVE IN C
; 
;   DONE WITH INITIALIZATION
;        A,E  = SCRATCH 
;        B    = INPUT FLAGS (PAPFKY)
;        C    = FLAG BYTE (NEWBUF, BUFF1, BINARY) 
;        D    = INPUT CHARACTER 
;        H,L  = INTERFACE WITH PRDUCR 
; 
       MOV  A,C       ;GET FLAG BYTE
       ADD  A         ;DO WE NEED A NEW BUFFER? 
;                     (NEWBUF FLAG BIT) 
       JP   PUTGO     ;NO, BRANCH 
 
; 
;   HERE TO HANDLE BEGINNING OF BUFFER CONDITION
; 
PUTQUE:DI             ;MUST LOCK OUT INTERRUPT
       LDA  ASBCNT    ;PROCESSOR BEFORE TOUCHING
       ANA  A         ;THE QUEUES 
       JM   WAIT2     ;BRANCH IF BUFFERS RECEIVING
; 
       CALL FQHDQT    ;NEW BUFFER FOR PRODUCER
       JZ   WAIT      ;WHOOPS, XMIT BUFFS FULL
; 
       EI             ;DONE WITH QUEUES FOR NOW 
       MOV  A,C       ;CLEAR THE BEGINNING
       ANI  377Q-BUFF1-NEWBUF 
       MOV  M,A       ;OF BUFFER CONDITION
; 
;   HERE TO DETERMINE HOW TO FLAG THE NEW 
;   TRANSMIT BLOCK (USED BY INTERRUPT PROCESSOR)
;   AS FOLLOWS: 
;        A)   STX - NORMAL NON-BINARY BLOCK 
;        B)   DLE - BINARY BLOCK
;        C)   CHAR > 177B - ENTER-AID #1
;        D)   CHAR < 200B - ENTER-AID #N
; 
       RAR            ;TRANSPARENT ENTRY
;                     (IE, IS BINARY FLAG ON?)
       LXI  H,DLESTX  ;ADDR OF TRANSLATED DLE 
       JC   PUTQ50    ;IF BINARY, FLAG CHAR = DLE 
       INX  H         ;IF NOT BINARY, FLAG = STX
PUTQ50:MOV  E,M       ;E = STX OR DLE (TRANSLATED)
       ADD  B         ;ENTER-AID ENTRY? 
;                     (IE, IS PAPFKY FLAG ON?)
       JP   PUTQ75    ;NO, INITIAL CHAR ALL SET UP
       MOV  E,D       ;YES, FLAG CHAR = INPUT CHAR
; 
;   HERE TO PUT BLOCK TYPE FLAG IN
;   FIRST BUFFER OF A TRANSMIT BLOCK
; 
PUTQ75:MOV  A,C       ;BEGINNING OF BLK CONDITION?
       ANA  A         ;(BUFF1 BIT IN FLAG)
       CM   PUTB1     ;YES, DO BEG OF BLK STUFF 
; 
       MOV  A,B       ;IF ENTER-AID SPECIAL CASE
       ANA  A         ;SUPPRESS PUTTING INPUT 
;                     CHAR IN THE BUFFER
 
; 
;   HERE TO PUT THE INPUT CHARACTER IN THE BUFFER 
;   AND CHECK FOR END-OF-BLOCK CONDITIONS 
; 
;   ENTER     P    TO PUT INPUT CHAR IN BUFFER
;             M    TO BYPASS PUTTING CHAR IN BUFF 
; 
PUTGO: MOV  E,D       ;INPUT CHAR (TO PUT IN BUFF)
       CP   PUTCHR    ;DISABLE INTERRUPTS AND 
;                     PUT THE CHAR IN BUFFER
; 
       INR  L         ;IS THE BUFFER FULL NOW?
       CZ   CHKETB    ;IF YES, GO SEE IF TIME TO
;                     TERMINATE BLOCK WITH AN ETB 
       JMP  CHROK2    ;ALL DONE (SUCCESS) 
; 
; 
;   HERE TO PUT DLE/STX/AID AT BEG OF BLOCK 
; 
PUTB1: LDA  BUFMAX    ;NEW BUFFER COUNT 
       STA  BUFCNT    ;SO WE KNOW WHEN TO PUT ETBS
; 
;   HERE TO PUT A CHARACTER IN THE BUFFER 
; 
PUTCHR:DI             ;NO INTERRUPTS WHILE
       LDA  ASBCNT    ;MESSING WITH QUEUES
       ANA  A 
       MOV  A,E       ;A = CHAR TO PUT IN BUFFER
       JP   PRDUCR    ;IF ASBCNT >= 0, OK TO PUT
;                     ELSE, ABORT 
; 
;    ENTRY POINT
;    HERE TO POP STACK AND RETURN Z & C 
; 
RETPCZ:POP  H         ;POP RETURN OFF THE STACK 
; 
; 
;   ENTRY POINT 
;   HERE TO RETURN WITH Z & C 
; 
WAIT2  EQU  $         ;ABORT CAUSE NOW RECEIVING
CHRBAD EQU  $         ;RECEIVE ERROR
RETCZ  EQU  $ 
       CMP  A         ;SET Z CONDITION CODE 
       STC            ;SET C CONDITION CODE 
       JMP  RETHDB    ;EI, POPS & RET 
 
;************************************************ 
; 
;   STBIN 
;        TERMINATE CURRENT OUTPUT BLOCK WITH ETB
;        TURN ON BINARY OUTPUT FLAG 
; 
;   ENDBIN
;        TERMINATE CURRENT OUTPUT BLOCK WITH ETB
;        TURN OFF BINARY OUTPUT FLAG
;        WARNING: EVERY STBIN (OR FSTBIN) MUST
;        BE FOLLOWED BY AN ENDBIN, AND ENDBIN 
;        MUST PRECEDE ENDBLK
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A DESTROYED, ALWAYS NC & Z
;             CALL IGNORED IF DATACOM RECEIVING 
;             CALL IGNORED IF NO OUTPUT BLOCK 
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
STBIN  EQU  $         ;SAME AS ENDBIN 
ENDBIN:PUSH B         ;MUST SAVE SAME AS DCCTL
       PUSH D 
       PUSH H 
; 
       CALL DCCETB    ;TERMINATE OUTPUT BLOCK 
; 
;   ENTRY POINT 
;   HERE TO RETURN SUCCESSFULLY 
; 
CHROK: ANA  B         ;CLEAR ALL BUT CHAR BITS
; 
;   ENTRY POINT 
; 
RETNCZ EQU  $ 
CHROK2:CMP  A         ;SET Z & NC CONDITION CODES 
; 
;   ENTRY POINT 
;   WARNING: RETHDB MUST = RETNCZ+1 
; 
RETHDB:EI             ;*** ENABLE INTERRUPTS ***
; 
;   ENTRY POINT 
; 
RTHDB2:POP  H 
       POP  D 
       POP  B 
       RET
 
;*************************************************
; 
;   CHKETB
;        CALL WHEN CURRENT OUTPUT BUFFER FULL 
;        CHECKS TO SEE IF SHOULD TERMINATE BLOCK
;        WITH AN ETB
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      AS BELOW
; 
;************************************************ 
; 
;   PUTBLK
;        TERMINATE CURRENT OUTPUT BUFFER WITH 
;        AN ETB OR ETX BLOCK BOUNDARY 
; 
;   ENTRY     C = BUFFER FLAGS (ETB/ETX)
; 
;   EXIT      A,B,C,H,L DESTROYED 
;   WARNING:  CALLER MUST HAVE INTERRUPTS DISABLED
;             AND MUST CHECK ASBCNT TO ENSURE 
;             TRANSMIT MODE 
; 
;*************************************************
; 
;   ENTRY POINT 
; 
CHKETB:LXI  H,BUFCNT  ;TERMINATE OUTPUT BLOCK WITH
       DCR  M         ;AN ETB ONLY WHEN THE BUFFER
;                     COUNT IS DEPLEATED
       LXI  B,NEWBUF*256+BUFBC    ;ASSUME NO ETB
       JP   PUTFLG    ;IF DON'T NEED ETB, SIMPLY
;                     SET UP TO GET NEW BUFFER
; 
;   ENTRY POINT 
; 
PUTBLK:MVI  B,NEWBUF+BUFF1   ;FLAG STARTING NEW 
;                     OUTPUT BLOCK AT NEXT CALL 
;                     TO PUTDC
; 
       LDA  DQT       ;CHECK DATA QUEUE (TAIL)
       ANA  A         ;IF QUEUE EMPTY, ASSUME 
;                     NO OUTPUT BLK TO TERMINATE
       RZ             ;(BLOCK COULD BE IN TQ, 
;                     TERMINATED BY AN ETB) 
; 
;   ALWAYS TERMINATE THE CURRENT OUTPUT BLOCK 
;   AS REQUESTED (IE, WITH ETB/ETX), BUT ONLY 
;   INCREMENT THE OUTPUT BLOCK COUNT (ASBCNT) 
;   IF THE BLOCK WAS NOT ALREADY TERMINATED 
;   (THIS QUALIFICATION ALLOWS SPURIOUS CALLS 
;   WITHOUT ILL EFFECT).
; 
       MOV  H,A       ;ADDR OF PRODUCER'S BUFFER
       MVI  L,BFLG    ;POINTER TO ITS FLAGS 
       MOV  A,M       ;GET CURRENT BUFFER FLAGS 
       MOV  M,C       ;TERMINATE BLK WITH ETB/ETX 
       ANI  BUFBC     ;IS BLK ALREADY TERMINATED? 
       JNZ  PUTFLG    ;YES, DON'T BUMP BLK-CNT
;                     (NOTE THAT SHOULD UPDATE
;                     BUFFER FLAGS EVEN IF BLOCK
;                     ALREADY TERMINATED SO THAT
;                     ENDBLK CAN CHANGE ETB 
;                     TO AN ETX TERMINATOR) 
       LXI  H,ASBCNT  ;INFORM CONSUMER OF NEW BLK 
       INR  M         ;BY BUMPING TRANSMIT BLK CNT
; 
PUTFLG:LXI  H,FLAG    ;START NEW BUFFER; IF BLOCK 
       MOV  A,B       ;TERMINATED, START NEW BLOCK
       ORA  M 
       MOV  M,A 
       RET
 
;*************************************************
; 
;   CONST 
;        SET RAM TO A CONSTANT
; 
;   ENTRY     A=CONSTANT
;             C=# BYTES TO SET TO CONSTANT, LESS 1
;             D,E POINT TO 1ST BYTE TO SET
; 
;   EXIT      A UNMODIFIED
;             B = 0 
;             C DESTROYED 
;             D,E = ADDR+1 OF LAST BYTE SET 
; 
;*************************************************
; 
;   CONSTI
;        SET RAM AREA TO
;        A, A+B, A+2*B, A+3*B,... 
;             ..., A+C*B
; 
;   ENTRY     A=INITIAL VALUE 
;             B=INCREMENT 
;             C = # BYTES TO SET, LESS 1
;             D,E POINT TO 1ST BYTE TO SET
; 
;   EXIT      A,C DESTROYED, B UNMODIFIED 
;             D,E = ADDR+1 OF LAST BYTE TO SET
; 
;*************************************************
; 
;   ENTRY POINT 
; 
CONST: MVI  B,0       ;SET RAM TO CONSTANT
; 
;   ENTRY POINT 
; 
CONSTI:STAX D         ;STORE NEXT CONSTANT
       INX  D         ;POINT TO WHERE TO PUT NEXT 
       ADD  B         ;+ INC, IF NECESSARY
       DCR  C         ;CONTINUE TIL CNT DEPLEATED 
       JP   CONSTI
       RET
 
; 
;   CPYTBL
;        COPY ROM TABLE TO RAM AREA 
; 
;   ENTRY     C=# BYTES TO COPY, LESS 1 
;             D,E POINT TO FIRST RAM BYTE 
;                 (DESTINATION) 
;             H,L POINT TO FIRST TABLE ENTRY
;                 (SOURCE)
; 
;   EXIT      A,C DESTROYED 
;             D,E = ADDR+1 OF LAST BYTE SET 
;             H,L = ADDR+1 OF LAST BYTE COPIED
; 
;*************************************************
; 
;   ENTRY POINT 
; 
CPYTBL:MOV  A,M       ;BYTE TO COPY (FROM SOURCE) 
       STAX D         ;BYTE COPIED (TO DESTINATION
       INX  D         ;ADDR OF NEXT BYTE TO COPY
       INX  H         ;ADDR OF WHERE TO COPY IT 
       DCR  C         ;CONSULT BYTE COPY COUNT
       JP   CPYTBL    ;CONTINUE TIL CNT DEPLEATED 
       RET
 
;************************************************ 
; 
;   HEXPAR
;        TRANSLATE OR COMPUTE PARITY
;        FOR ALL ENTRIES IN RAM TABLE 
; 
;   ENTRY     H,L POINT TO FIRST TABLE ENTRY
;             E=# BYTES TO COPY, LESS 1 
; 
;   EXIT      ALL REGS DESTROYED
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
HEXPAR:MOV  B,M       ;NEXT TABLE ENTRY 
       MOV  A,B 
       ANA  A         ;DON'T MESS WITH STOPERS
       CNZ  PAREBC    ;COMPUTE PARITY OR XLATE
       MOV  M,A       ;TRANSLATED/PARITY'D CHAR 
       INX  H         ;PT TO NEXT ENTRY 
       DCR  E         ;# ITEMS LEFT 
       JP   HEXPAR    ;CONTINUE TIL CNT DEPLEATED 
       RET
 
;************************************************ 
; 
;   INIDS 
;        COMPUTE GROUP/DEVICE ID FROM JUMPERS 
; 
;   ENTRY     A = JUMPER
; 
;   EXIT      A = GROUP/DEVICE ID 
;             E DESTROYED 
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
INIDS: ANI  MASKID    ;CLEAR ALL BUT ID BITS
       CPI  MAXID+1   ;IS ID > Z ?
       MOV  E,A 
       MVI  A,SPACEI  ;YES, CONVERT TO SPACE
       RP             ;AND RETURN 
       MOV  A,E       ;NO,
       ORI  ATSINI    ;CONVERT ID'S TO @-Z
       RET            ;A = TRANSLATE ID 
 
;************************************************ 
; 
;   SHIFT 
;        CALCULATE 1*(2**A) 
;        IE, SHIFT 1 LEFT (A) TIMES 
; 
;   ENTRY     A = # TIMES TO SHIFT (TAKEN MOD 4)
; 
;   EXIT      A = RESULT (1,2,4,8)
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
SHIFT: ANI  3Q        ;TAKE COUNT MODULO 4
       PUSH B         ;SAVE SOME WORKING REG'S
       MOV  B,A       ;B=# TIMES TO SHIFT 
       MVI  A,200Q    ;A = BIT TO SHIFT 
; 
SHIFT5:RLC            ;MULTIPLY A BY 2
       DCR  B         ;DECREMENT SHIFT COUNT
       JP   SHIFT5    ;CONT TILL CNT DEPLEATED
; 
       POP  B         ;RESTORE REG'S
       RET
 
;************************************************ 
; 
;   PRDUCR (ALSO, PUTR) 
;        PUT CHARACTERS IN DATA QUEUE BUFFERS 
; 
;   ENTRY     A = CHARACTER 
;             NEVER CALL WITH DQ EMPTY
; 
;   EXIT      A,D,L,H AS SPECIFIED BELOW
;        NZ   CHARACTER ACCEPTED
;             A = CHARACTER, D SAVED
;             H,L = ADDR OF WHERE CHAR WAS PUT
;        Z    CHARACTER NOT ACCEPTED
;             (CURRENT BUFFER FULL, AND FQ EMPTY) 
;             A = CHARACTER, D = CHARACTER
;             H,L - DESTROYED 
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
PUTR   EQU  $         ;ASYNC CODE USE PUTR
PRDUCR:LHLD BUFPCO    ;H=(DQT) L=(BUFPCO) 
;                     WARNING: ASSUMES THAT THE 
;                     DQ IS NOT EMPTY 
; 
       INR  M         ;INCREMENT PRODUCER COUNT 
;                     FOR NEXT CALL 
       MOV  L,M       ;ADDR OF WHERE TO PUT CHAR
       DCR  L         ;(NOTE THAT PRODUCER COUNT
;                     = ADDR OF LAST CHAR + 1)
; 
       MOV  M,A       ;PRODUCE !!!
; 
       RNZ            ;RETURN (NZ) IF STILL ROOM
;                     IN THE BUFFER 
 
; 
;   WHEN HERE PRODUCER COUNT HAS JUST FALLEN OFF
;   THE TOP OF THE BUFFER, IE WE JUST STUFFED THE 
;   CHARACTER IN BYTE 0 OF THE BUFFER (DESTROYING 
;   APCNT!) 
; 
       MOV  D,A       ;SAVE THE CHARACTER 
       LHLD BUFPCO    ;ADDR OF PRODUCER COUNT 
       SUB  A 
       MOV  M,A       ;SET PRODUCER COUNT TO ZERO 
;                     (NOTE THAT IF WE WERE 
;                     USING PCNT, THEN IT IS OK 
;                     FOR APCNT TO BE DESTROYED)
; 
       CALL FQHDQT    ;APPEND A FREE BUFFER FROM
;                     THE FQ TO TAIL OF DQ
;                     AND INITIALIZE IT 
       MOV  A,D       ;RESTORE THE CHARACTER
       JNZ  PRDUCR    ;GOT NEW BUFF, SO PRODUCE 
       RET            ;WHOOPS, FQ IS EMPTY
 
;************************************************ 
; 
;   GETX
;        SAME AS CNSUMR ACCEPT THAT IT ASSUMES
;        THAT DQ IS NOT EMPTY 
; 
;   CNSUMR
;        TAKE CHARACTERS FROM THE 
;        DATA QUEUE BUFFERS 
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      D,E,L,H ALWAYS DESTROYED
;        NZ   A = CHARACTER (EMPTY BUFFERS DEQ'D) 
;        Z    NO CHARACTER IN BUFFER
;             C    RECEIVE ERROR, A DESTROYED 
;                  TRANSMIT BLOCK BOUNDARY: 
;                       (A)=(XEND+1)= TRANSLATED
;                       ETB/ETX; EOTO SET IF
;                       ETX BLOCK BOUNDARY
;             NC   THE QUEUE IS EMPTY OR
;                  ASBCNT IS NOW = -1 
; 
;************************************************ 
; 
;   HERE TO STICK THE EMPTIED BUFFER ON THE FQ
; 
CNS025:PUSH B         ;DQHYQT DESTROYS ALL REGS 
       LXI  B,FQT     ;TAKE 1ST BUFF IN DQ AND
       CALL DQHYQT    ;LINK TO END OF FQ
       POP  B 
; 
; 
;   ENTRY POINT 
; 
CNSUMR:LDA  DQH       ;A=ADDR OF 1ST BUFF IN DQ 
       ANA  A         ;IS THE DQ EMPTY? 
       RZ             ;YES, RETURN Z + NC 
 
; 
;   ENTRY POINT 
; 
GETX:  LHLD DQH-1     ;H=ADDR OF 1ST BUFF IN DQ 
;                     WARNING: ASSUMES THAT THE 
;                     DQ IS NOT EMPTY 
       MVI  L,CCNT    ;(CCNT=ADDR OF LAST BYTE
;                     THAT WAS CONSUMED)
       INR  M         ;CCNT FOR NEXT CONSUMPTION
       MOV  A,M       ;LO-ADDR OF CHAR TO FETCH 
; 
       DCX  H         ;ADDR OF PCNT 
       CMP  M         ;HAS THE CONSUMER CAUGHT
;                     UP WITH THE PRODUCER? 
;                     - ASSUME NOT FOR NOW
; 
       MOV  L,A       ;ADDR OF WHERE THE CHAR IS
       MOV  A,M       ;CONSUME IT !!! 
; 
       RNZ            ;RETURN (NZ) IF CONSUMER
;                     HASN'T CAUGHT UP YET
;                     (CCNT < PCNT) 
 
; 
;   WHEN HERE, THE CONSUMER HAS CAUGHT UP WITH
;   THE PRODUCER (IE, CCNT+1=PCNT).  THE
;   CONSUMER COUNT IS ALWAYS BACKED UP. THERE ARE 
;   THE FOLLOWING 3 DISTINCT POSSIBILITIES: 
; 
;   1)   THE BUFFER IS SIMPLY EMPTY 
;        A)   TRANSMITTING - DEQUEUE IT 
;        B)   RECEIVING - DEQUEUE UNLESS LAST IN
;                  CHAIN AND SELEC ON, IN WHICH 
;                  CASE RETURN Z & NC 
; 
;   2)   THE BUFFER IS MARKED AS BEING A BLOCK
;        BOUNDARY; THERE ARE 2 SUBCASES:
;        A)   TRANSMITTING (ASBCNT >= 0): 
;             CONSUMER BACKED UP TO BUFIC;
;             THE BUFFER IS DEQUEUED TO TQ; 
;             ASBCNT DECREMENTED; 
;             ETB/ETX (TRANSLATED) PUT IN 
;                  BCC TRANSMIT STRING (XEND+1) 
;             EOTO FLAG SET IF TERMINATOR IS ETX
;             RETURNS Z & C WITH
;                  A = TRANSLATED TERMINATOR
;        B)   RECEIVING (ASBCNT < 0): 
;             PCNT=(APCNT); 
;             IF LAST BUFF IN CHN, BUFPCO=PCNT; 
;             TURN OFF BUFBC FLAG;
;             INCREMENT ASBCNT; 
;             IF ASBCNT IS NOW < -1, THEN BACK
;                  TO CNSUMR
;             IF ASBCNT IS NOW = -1, THEN RETURN
;                  WITH Z & NC
; 
;   3)   THE BUFFER IS MARKED AS HAVING A 
;        RECEIVE ERROR; CAN ONLY HAPPEN WHEN
;        RECEIVING AND NOT IN BLKIN MODE. 
;        PCNT=(APCNT) 
;        IF LAST BUFF IN CHN, BUFPCO=PCNT;
;        TURN OFF BUFRER
;        RETURN WITH Z & C WITH A = BUFRER FLAG 
; 
;   NOTES:
;        A HAS CONTENTS OF APCNT
;        BUFFERS DEQUEUED TO FQ IF RECEIVING, 
;        ELSE TO TQ 
; 
 
       MVI  L,CCNT    ;BACKUP THE CONSUMER COUNT
       DCR  M         ;(MAY KEEP THIS BUFFER) 
; 
       LDA  ASBCNT    ;LOOK AT ASBCNT TO SEE IF 
       ANA  A         ;TRANSMITTING OR RECEIVING
       JM   CNS100    ;BRANCH IF RECEIVING
; 
;   HERE WHEN TRANSMITTING
; 
       MVI  M,BUFIC   ;BACK UP CONSUMER TO BEG OF 
;                     BUFF; SO WHEN REQ TQ TO DQ
;                     TO RETRANSMIT, WILL CONSUME 
; 
       PUSH B         ;DQHYQT DESTROYS ALL REGS 
       PUSH H 
       LXI  B,TQT     ;TAKE 1ST BUFF IN DQ AND
       CALL DQHYQT    ;LINK TO END OF TQ
       POP  H         ;GET REGS BACK
       POP  B 
;                     (ALL TRANSMIT CASES DEQ)
; 
       INX  H         ;H,L POINT TO BUFFER FLAGS
       MOV  A,M       ;A = BUFFER FLAGS 
       ANI  BUFBC+BUFBCT   ;IF BUFFER MARKED WITH 
;                        BOUNDARY CONDITION 
       JZ   CNSUMR    ;NO, CASE #1, BUFF EMPTY
; 
;   HERE FOR CASE 2A (TRANSMIT BOUNDARY)
; 
;                     (ALREADY DEQUEUED)
       LXI  H,ASBCNT  ;ASBCNT=ASBCNT-1
       DCR  M         ;(JUST FINISHED CONSUMING 
;                     TRANSMIT BLOCK) 
       ANI  BUFBCT    ;ETB/ETX BOUNDARY CONDITION 
       MOV  E,A       ;SAVE THE BIT 
; 
       LXI  H,CONFG2  ;TURN ON EOTO IF
       ORA  M         ;BLOCK TERMINATED BY ETX
       MOV  M,A 
; 
       LXI  H,ETB     ;ADDR OF TRANSLATED ETB 
       MVI  D,0       ;D,E = 0/1
       DAD  D         ;POINT TO ETX IF BUFBCT=1 
       MOV  A,M       ;A = TRANSLATED ETB/ETX 
       STA  XEND+1    ;SET UP BCC TRANSMIT STRING 
; 
;   HERE TO RETURN Z & C WITH FLAG IN A 
; 
CNS050:MOV  E,A       ;SAVE FLAG
       SUB  A         ;SET Z & C CONDITION CODES
       STC
       MOV  A,E       ;RETURN FLAGS IN A
       RET
; 
;   HERE WHEN RECEIVING 
; 
CNS100:INX  H         ;H,L POINT TO BUFFER FLAGS
       MOV  A,M       ;A = BUFFER FLAGS 
       ANI  BUFBC+BUFRER  ;BLK BOUNDARY OR
;                         RECEIVE ERROR 
       JNZ  CNS200    ;YES, CASE #2 OR #3 
; 
;   HERE FOR CASE 1B (RECEIVING & BUFF EMPTY) 
; 
       MVI  L,CHN     ;ADDR OF CHN FOR THIS BUFF
       SUB  A         ;IS THIS BUFF LAST IN DQ ?
       CMP  M 
       JNZ  CNS025    ;NO, THEN DEQUEUE IT
       LDA  ASFLAG    ;THIS BUFF IS LAST
       ANI  RCVN      ;IS ASYNC STILL ACTIVE ?
       JZ   CNS025    ;NO, THEN GO DEQUEUE
       SUB  A         ;YES, THEN WE HAVE CAUGHT 
;                     UP IN NON-BLKIN MODE
       RET            ;RETURN Z & NC
; 
; 
;   HERE FOR CASE 2B OR 3 
;   RECEIVE BOUNDARY OR RECEIVE ERROR 
; 
;                     H,L POINT TO BUFFER FLAGS 
CNS200:MOV  E,M       ;SAVE BUFF FLAGS FOR LATER
       XRA  E         ;TURN OFF BUFBC 
       MOV  M,A       ;AND/OR BUFRER
; 
       INX  H         ;H,L POINT TO BUFFER CHAIN
       MOV  A,M       ;LAST BUFFER IN THE CHAIN?
       ANA  A         ;(USE CONDITION CODE LATER) 
; 
       MVI  L,APCNT   ;SET PCNT=(APCNT) 
       MOV  A,M       ;A=AUXILIARY PRDUCR CNT 
       INX  H         ;POINT TO REGULAR PRDUCR CNT
       MOV  M,A       ;PCNT=(APCNT) 
; 
       JNZ  CNS300    ;IF LAST BUFF IN CHAIN
       MVI  A,PCNT    ;THEN SET PUFPCO=PCNT 
       STA  BUFPCO    ;HANDLES SMALL BLK CASE 
;                     (WHEN CONSMR & PRDUCR IN
;                     THE SAME BUFFER)
; 
CNS300:MOV  A,E       ;GET OLD BUFFER FLAGS 
       ANI  BUFRER    ;CASE 3 (RECEIVE ERROR) ? 
       JNZ  CNS050    ;YES, RETURN Z & C WITH 
;                     A = BUFRER
; 
;   HERE FOR CASE 2B (RECEIVE BOUNDARY) 
; 
       LXI  H,ASBCNT  ;H,L POINT TO ASBCNT
;                     JUST CONSUMED A RECEIVE BLK 
       INR  M         ;SO, ASBCNT=ASBCNT+1
       MOV  A,M       ;STILL BUFFS TO CONSUME?
       CPI  -1        ;(IE, IS ASBCNT < -1) 
       RZ             ;NO, RETURN Z & NC
;                     (HAVE JUST CAUGHT UP IN 
;                     BLKIN MODE) 
       JMP  CNSUMR    ;YES, GO CONSUME THEM 
 
;************************************************ 
; 
;   TQDQ
;        RETURNS IMMEDIATELY IF TQ IS EMPTY.
;        (IE, OK TO CALL AT INAPPROPRIATE TIMES)
;        TAKE ENTIRE TQ (EVERYTHING BETWEEN 
;        TQH AND TQT) AND INSERT BEFORE BEGINNING 
;        OF DQ (AT DQH) 
;        INCREMENT ASBCNT (NEW BLK IN DQ) 
; 
;        PURPOSE - RETRANSMIT DATA AFTER NAK
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      ALL REGS DESTROYED
; 
;************************************************ 
; 
;   TQFQ
;        RETURNS IMMEDIATELY IF TQ IS EMPTY.
;        (IE, OK TO CALL AT INAPPROPRIATE TIMERS) 
;        TAKE ENTIRE TQ (IE EVERYTHING
;        BETWEEN TQH AND TQT) AND INSERT BEFORE 
;        BEGINNING OF FQ (AT FQT) 
; 
;        PURPOSE - DISCARD BUFFERS AFTER ACK
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      ALL REGS DESTROYED
; 
;************************************************ 
; 
;   CHNXQ 
;        TAKE SPECIFIED SOURCE CHAIN OF BUFFERS 
;        AND INSERT BEFORE BEGINNING OF 
;        DESTINATION QUEUE
; 
;   ENTRY     MOV  B,ADDR OF 1ST IN CHAIN 
;             MOV  C,ADDR OF LAST IN CHAIN
;             LXI  H,HEAD OF DEST QUEUE 
;             CALL CHNXQ
; 
;   EXIT      A,D,E,H,L DESTROYED 
;             B,C SAME AS AT ENTRY
;             ALWAYS RETURNS NZ CONDITIONS
; 
;************************************************ 
 
; 
;   ENTRY POINT 
; 
TQDQ:  LXI  D,DQH     ;INSERT TQ AT BEG OF DQ 
       CALL TQF100
       RZ             ;CALL IS NO-OP IF TQ EMPTY
       LXI  H,ASBCNT  ;ELSE, INCREMENT ASBCNT 
       INR  M         ;(NEW BLK IN THE DQ; NOTE 
;                     THAT THERE CAN NEVER BE 
;                     MORE THAN 1 BLK IN TQ)
       RET
; 
; 
;   ENTRY POINT 
; 
TQFQ:  LXI  D,FQH     ;INSERT TQ AT BEG OF FQ 
TQF100:LXI  H,TQH 
; 
;   GET HEAD AND TAIL POINTERS FOR TQ 
;   SET TQH AND TQT TO ZERO 
; 
;                     D,E POINT TO DESTINATION Q
;                     H,L POINT TO TQ-HEAD
       MOV  B,M       ;B=HEAD PTR FOR TQ (1ST)
       SUB  A         ;A=0
       CMP  B         ;IS TQ EMPTY? 
       RZ             ;YES, THEN DONE 
       MOV  M,A       ;SET TQH TO 0 
; 
       DCX  H         ;POINT TO TQT 
       MOV  C,M       ;C=TAIL PTR TO TQ (LAST)
       MOV  M,A       ;SET TQT TO 0 
       XCHG           ;H,L POINT TO DESTINATION Q 
 
; 
;   ENTRY POINT 
; 
;   LINK HEAD OF DESTINATION QUEUE TO TAIL OF 
;   SOURCE CHAIN (IE, INSERT SOURCE CHAIN AT
;   BEGINNNING OF DESTINATION QUEUE)
; 
;                     H,L POINT TO DEST Q-HEAD
;                     B=SOURCE CHAIN HEAD 
;                     C=SOURCE CHAIN TAIL 
CHNXQ: MOV  D,C       ;D,E POINT TO CHAIN OF LAST 
       MVI  E,CHN     ;BUFF IN SOURCE CHAIN 
       MOV  A,M       ;A = 1ST BUFF IN DEST Q 
       STAX D         ;LAST BUFF IN SOURCE CHAIN
;                     NOW POINTS TO 1ST BUFF
;                     IN DESTINATION Q
; 
;   SET HEAD OF DEST Q TO HEAD OF SOURCE CHAIN
; 
;                     H,L POINT TO HEAD POINTER 
;                     OF DESTINATION QUEUE
       MOV  M,B       ;SET HEAD POINTER TO HEAD 
;                     OF SOURCE CHAIN 
       ANA  A         ;WAS THE DEST Q EMPTY?
       RNZ            ;NO, THEN DONE
; 
;   SPECIAL CASE WHEN DESTINATION QUEUE WAS 
;   EMPTY; SET TAIL OF DESTINATION QUEUE TO 
;   TAIL OF SOURCE CHAIN
; 
       DCX  H         ;H,L POINT TO TAIL POINTER
;                     OF DESTINATION QUEUE
       MOV  M,C       ;SET TAIL PTR TO TAIL OF
;                     SOURCE CHAIN
       ORA  C         ;(ALWAYS RETURN WITH NZ 
;                     NEEDED BY TQDQ) 
       RET
 
;************************************************ 
; 
;   PUTE
;        SET BLOCK BOUNDARY WHEN RECEIVING
; 
;   ENTER     NEVER CALL WITH DQ EMPTY
; 
;   EXIT      A,D,E,H,L DESTROYED 
;             RETURNS IMMEDIATELY IF NOT BLKIN
;             SETS BUFBC FLAG IN PRODUCER BUFFER
;             IF THERE WAS ALREADY A BLOCK
;                  BOUNDARY IN THE BUFFER, THEN 
;                  WE MERELY SET PCNT TO APCNT
;             IF THERE WAS NOT A BLOCK BOUNDARY,
;                  THEN APCNT SET TO PCNT 
;                  BUFPCO SET TO APCNT
;                  AND ASBCNT DECREMENTED 
; 
;************************************************ 
; 
;   SETBND
;        SET BLOCK BOUNDARY WHEN RECEIVING
;        OR SET RECEIVE ERROR 
; 
;   ENTER     TYPE #1 - RECEIVE BLK BOUNDARY
;                  D = -1 (DECREMENT ASBCNT)
;                  E = BUFBC
;             TYPE #2 - RECEIVE ERROR 
;                  D = 0 (DON'T TOUCH ASBCNT) 
;                  E = BUFRER 
; 
;   EXIT      A,D,E,H,L DESTROYED 
;             TYPE #1 - 
;                  IF BLOCK BOUNDARY NOT ALREADY
;                       SET, THEN SET APCNT=PCNT
;                       AND SET BUFPCO=APCNT
;                       AND INCREMENT ASBCNT
;                  IF BLOCK BOUNDARY IS ALREADY 
;                       SET, THEN SET PCNT=APCNT
;             TYPE #2 - 
;                  IF BUFRER ALREADY SET, RETURNS 
;                       IMMEDIATELY 
;                  OTHERWISE, SETS BUFRER 
;                       APCNT = PCNT
;                       BUFPCO = APCNT
; 
;************************************************ 
 
; 
;   ENTRY POINT 
; 
PUTE:  LDA  FLAG      ;RETURN IMMEDIATELY IF NOT
       ANI  BLKIN     ;BLKIN MODE 
       RZ 
; 
       LXI  D,DCRBBC  ;ANOTHER BLK RECEIVED,
;                     ASBCNT-1, BLK BOUNDARY
;                     (D=-1, E=BUFBC) 
; 
; 
;   ENTRY POINT 
; 
;                     ENTER WITH: 
;                     D=DELTA ASBCNT
;                     E=BUFFER FLAGS TO SET 
SETBND:LDA  DQT       ;H=ADDR OF PRODUCER'S BUFFER
       MOV  H,A 
       STA  BUFBP     ;REMEMBER LAST BLK BOUNDARY 
; 
       MVI  L,BFLG    ;POINT TO PRODUCER'S BUF FLG
       MOV  A,M       ;IF BUFRER ALREADY SET, THEN
       ANI  BUFRER    ;DONE SINCE WANT GETDC TO 
       RNZ            ;RETURN EARLIEST ERROR
; 
       MOV  A,E       ;A=NEW FLAGS TO SET 
       MOV  E,M       ;E=OLD BUFFER FLAGS 
       ORA  E         ;COMBINE THEM 
       MOV  M,A       ;AND STORE IN BUFFER
; 
       MOV  A,E       ;IS THERE ALREADY A 
       ANI  BUFBC     ;BLOCK BOUNDARY SET?
; 
;        IF YES (NZ), LET CONSUMER CATCH UP TO
;        NEW BOUNDARY BY MERGING NEW BLK WITH OLD 
;        (THEREFORE NO NEED TO INFORM CONSUMER
;        OF NEW BLK, IE NO CHANGE TO ASBCNT)
; 
;        IF NO (Z), MARK BOUNDARY AND INFORM
;        CONSUMER (BY DECREMENTING ASBCNT)
 
;                     ENTER NZ TO SET 
;                       PCNT=(APCNT)
;                     ENTER Z TO SET
;                       APCNT=(PCNT)
;                       BUFPCO=APCNT
;                     AND UPDATE ASBCNT 
SETPC: MVI  L,APCNT   ;ASSUME TO SET
       MOV  A,M         ;PCNT=(APCNT), ETC
       INX  H 
       JNZ  SETPCO    ;ASSUMPTION CORRECT, BRANCH 
; 
       LDA  ASBCNT    ;DECREMENT FOR RECEIVE BLK
       ADD  D         ;NO CHANGE FOR RECEIVE ERROR
       STA  ASBCNT
; 
; 
;   ENTRY POINT 
; 
SETPC2:MOV  A,M       ;AND SET APCNT = PCNT 
       DCX  H 
; 
SETPCO:MOV  M,A       ;SET APCNT TO PCNT
;                     OR SET PCNT TO APCNT
       LXI  H,BUFPCO  ;ALWAYS SET BUFPCO=APCNT
       MVI  M,APCNT   ;(IF BUFFER MARKED WITH 
;                     BLOCK BOUNDARY, PRODUCER
;                     MUST ALWAYS USE APCNT)
       RET
; 
DCRBBC EQU  377Q*256+BUFBC   ;LEFT=-1, RIGHT=BUFBC
 
;************************************************ 
; 
;   DEQALL, DEQIT, DEQIT2 
;        SET UP BUFFERS FOR RECEPTION 
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A,D,E,H,L DESTROYED;  B,C SAVED 
;             RETURNS IMMEDIATELY IF DQ STILL 
;                  HAS RECEIVED DATA (ASBCNT<-1)
;             OTHERWISE SET ASBCNT=-1 (BLKIN) 
;                  OR ASBCNT=-2 (NOT BLKIN) 
;             PUTS 1 EMPTY BUFFER IN DQ,
;                  AND ALL OTHERS IN FQ 
;             BUFPCO = 0
;             BUFF1 & NEWBUF FLAGS SET
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
DEQALL:LDA  ASBCNT    ;RETURN IMMEDIATELY IF
       INR  A         ;ASBCNT < -1
;                     (DQ STILL HAS RECEIVED DATA)
       RM 
; 
; 
;   ENTRY POINT 
;   (SAME AS DEQALL, BUT UNCONDITIONAL) 
; 
DEQIT: LXI  H,CMFLGS  ;TELL MAINCODE THAT DATACOM 
       MOV  A,M       ;IS IN RECEIVE MODE 
       ORI  RCVMDE    ;(ENTER-KEY NOT OK) 
       ANI  377Q-BLKTRG      ;(TURN OFF BLKTRG) 
       MOV  M,A 
; 
;   ENTRY POINT 
;   (SAME AS DEQIT, BUT DOESN'T TURN ON RCVMDE) 
; 
DEQIT2:CALL BUFINI    ;REFRESH BUFFERS (ALL TO FQ)
; 
       LXI  H,ASBCNT  ;H,L POINT TO ASBCNT
       DCR  M         ;ASBCNT=-1 IF BLKIN 
       LDA  FLAG
       ANI  BLKIN 
       JNZ  FQHDQT    ;PUT EMPTY BUFF IN DQ, RET
       DCR  M         ;ASBCNT=-2 IF NOT BLKIN 
       JMP  FQHDQT    ;PUT EMPTY BUFF IN DQ, RET
 
;************************************************ 
; 
;   BUFINI
;        INITIALIZE BUFFERS, RECONSTRUCTS FQ FROM 
;        BUFBEG AND BEFEND
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A,D,E,H,L DESTROYED;  B,C SAVED 
;             BUFBP = 0 
;             ASBCNT = 0
;             TQ, DQ EMPTY
;             BUFF1 AND NEWBUF FLAGS SET
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
BUFINI:PUSH B         ;SAVE CALLER'S REGS 
       LHLD BUFEND    ;H=ADDR OF 1ST BUFF 
;                     L=ADDR OF LAST BUFF 
       SHLD FQT       ;FQH=FIRST, FQT=LAST
; 
       MOV  A,L       ;A=ADDR OF LAST BUFF
       MVI  L,CHN     ;H,L POINT TO CHN OF 1ST BUF
       MOV  C,H 
; 
;   LOOP TO LINK ALL THE BUFFS TOGETHER 
; 
DEQA50:INR  C         ;C=ADDR OF NEXT BUFF
       MOV  M,C       ;LINK BUFF H TO BUFF H+1
       MOV  H,C       ;NEXT BUFF TO PUT LINK IN 
       CMP  H         ;NOW ON LAST BUFF?
       JNZ  DEQA50    ;NO, CONTINUE 
; 
       SUB  A         ;YES, SET CHN OF LAST TO 0
       MOV  M,A 
; 
;   SET DQT,DQH,TQT,TQH,BUFBP,ASBCNT TO ZERO
; 
;                     A = 0 
       LXI  D,DQT     ;D,E POINT TO THINGS TO 0 
       MVI  C,ASBCNT-DQT  ;# THINGS, LESS 1 
       CALL CONST     ;DQT --> ASBCNT SET TO 0
; 
       LXI  H,FLAG    ;INIT FLAG FOR PUTADC 
       MOV  A,M       ;TURN OFF BINARY FLAG 
       ANI  377Q-BINARY      ;(IN CASE
;                     SOMEONE GOT CONFUSED) 
       ORI  BUFF1+NEWBUF     ;NEW OUTPUT BLOCK
       MOV  M,A              ;AND NEW BUFFER
; 
       POP  B 
       RET
 
;************************************************ 
; 
;   DABORT
;        USED BY PRODUCER TO ABORT BAD DATA WHEN
;        RECEIVING
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      ALL REGS DESTROYED
;             NON-BLKIN MODE: 
;                  RETURNS IMMEDIATELY IF BUFRER
;                       ALREADY SET, OTHERWISE
;                  SET BUFRER 
;                  APCNT = PCNT 
;                  BUFPCO = APCNT 
;             BLKIN MODE: 
;                  DEQUEUES ANY BUFFERS 
;                       CHAINED FROM LAST BUFFER
;                       WITH BLOCK BOUNDARY 
;                  STARTS PRODUCER AT POINT 
;                       WHERE BOUNDARY WAS, IE, 
;                       APCNT = PCNT
;                       BUFPCO = APCNT
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
DABORT:LDA  FLAG      ;BLKIN MODE?
       ANI  BLKIN 
       LXI  D,BUFRER  ;(ASSUME NOT, D=0 E=BUFRER) 
       JZ   SETBND    ;NO, MARK CURRENT PRODUCER
;                     POSITION AS HAVING RECEIVE
;                     ERROR AND RETURN
 
; 
;   HERE TO ABORT IN BLKIN MODE 
; 
       LDA  BUFBP     ;H=ADDR OF LAST BUFF WITH 
       MOV  H,A       ;BLOCK BOUNDARY 
       ANA  A         ;IF STILL ON FIRST MSG BLK
       JZ   DEQALL    ;THEN START FROM SCRATCH
       MVI  L,PCNT    ;SET APCNT=PCNT 
       CALL SETPC2    ;AND BUFPCO=APCNT 
; 
       MVI  L,CHN     ;GET CHAIN PTR OF THE 
       MOV  B,M       ;BUFF THAT HAD THE BARRIER
; 
       SUB  A         ;IF THERE AREN'T ANY BUFFS
       CMP  B         ;PAST THE BLK BOUNDARY
       RZ             ;THEN ALL DONE
; 
;   HERE TO DEQUEUE BUFFERS LINKED TO 
;   THE BUFFER THAT HAS THE BLOCK BOUNDARY
; 
       MOV  A,H       ;SAVE ADDR OF BUFF
       LXI  H,DQT     ;H,L POINT TO DQ-TAIL 
       MOV  C,M       ;B=1ST BUFF IN CHAIN TO DEQ 
;                     C=LAST BUFF IN CHAIN TO DEQ 
       MOV  M,A       ;DQ-TAIL MUST NOW BE THE
;                     BUFFER WITH BLK BOUNDARY
       DCX  H         ;H,L POINT TO FQH 
       DCX  H 
       JMP  CHNXQ     ;INSERT CHAIN AT BEG OF FQ
;                     AND RETURN
 
;************************************************ 
; 
;   FQHDQT
;        TAKE A FREE BUFFER FROM FQH AND APPEND 
;        TO END OF DQ (IE, AT DQT)
; 
;        INITIALIZES THE NEW BUFFER, AND CAUSES 
;        PRODUCER TO USE PCNT 
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A DESTROYED 
;             Z    FQ IS EMPTY
;             NZ   APCNT = BUFIP (5)
;                  PCNT = BUFIP (5) 
;                  CCNT = BUFIC (4) 
;                  BFLG = BUFIF (0) 
;                  CHN = BUFICH (0) 
; 
;                  BUFPCO = PCNT
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
FQHDQT:PUSH B 
       PUSH D 
       PUSH H 
; 
       LXI  B,DQT     ;DESTINATION = DQ-TAIL
       LXI  H,FQH     ;SOURCE = FQ-HEAD 
       CALL XQHYQT    ;APPEND BUFF FROM FQ TO DQ
       JZ   RTHDB2    ;WHOOPS, FQ EMPTY 
 
; 
;   INITIALIZE BUFFER HEADER OF NEW BUFFER
; 
       MOV  H,A       ;H = ADDR OF NEW BUFFER 
       MVI  L,APCNT   ;H,L PT TO APCNT OF NEW BUFF
; 
       MVI  M,BUFIP   ;APCNT = BUFIP
       INX  H 
       MVI  M,BUFIP   ;PCNT = BUFIP 
       INX  H 
       MVI  M,BUFIC   ;CCNT = BUFIC 
       INX  H 
       SUB  A 
       MOV  M,A       ;BFLG = 0 
       INX  H 
       MOV  M,A       ;CHN = 0
; 
       INR  A         ;PRODUCER USES PCNT 
       STA  BUFPCO    ;(IE, BUFPCO=1) 
; 
       ANA  A         ;SET NZ CONDITION CODE
       POP  H         ;AND RETURN 
       POP  D 
       POP  B 
       RET
 
;************************************************ 
; 
;   XQHYQT
;        GENERALIZED ROUTINE TO DEQUEUE A BUFFER
;        FROM HEAD OF SPECIFIED SOURCE QUEUE TO 
;        TAIL OF SPECIFIED DESTINATION QUEUE
; 
;   ENTRY     LXI  B,YQT     YQT=TAIL OF DEST Q 
;             LXI  H,XQH     XQH=HEAD OF SOURCE Q 
;             CALL XQHYQT 
; 
;   DQHYQT
;        DEQUEUE BUFFER FROM HEAD OF DATA QUEUE 
;        (SOURCE) TO TAIL OF SPECIFIED
;        DESTINATION QUEUE
; 
;   ENTRY     LXI  B,YQT     YQT=TAIL OF DEST Q 
;             CALL DQHYQT 
; 
;   EXIT      ALL REGISTERS DESTROYED 
;             Z    SOURCE QUEUE IS EMPTY
;             NZ   BUFFER MOVED SUCCESSFULLY
;                  A = ADDR OF BUFFER THAT WAS
;                       MOVED (BUFF DEQUEUED FROM 
;                       SOURCE AND ENQUEUED TO
;                       DESTINATION)
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
DQHYQT:LXI  H,DQH 
 
; 
;   ENTRY POINT 
; 
;                     B,C POINT TO TAIL OF DEST Q 
;                     H,L POINT TO SOURCE Q HEAD
XQHYQT:MOV  D,M       ;ADDR OF 1ST BUFF IN SOURCE 
       SUB  A         ;IS SOURCE Q EMPTY? 
       CMP  D 
       RZ             ;YES, THEN NOTHING TO DO
       MVI  E,CHN     ;D,E POINT TO CHN OF 1ST BUF
       XCHG 
; 
       MOV  A,M       ;ADDR OF 2ND BUFF IN SOURCE 
       STAX D         ;SOURCE HEAD = ADDR OF
       ANA  A         ;2ND BUFF IN ITS CHAIN
       JNZ  XQH200    ;BRANCH IF THERE IS 2ND BUFF
; 
;   SPECIAL CASE WHEN SOURCE Q HAS ONLY 1 BUFF
; 
       DCX  D         ;D,E POINT TO TAIL POINTER
       STAX D         ;TAIL=0 (HEAD ALREADY=0)
; 
;   SET CHAIN POINTER OF 1ST BUFF TO 0
; 
XQH200:MVI  M,0       ;TERMINATE THE CHAIN
; 
;   ENQUEUE 1ST BUFF IN SOURCE Q TO TAIL
;   OF DESTINATION Q
; 
       LDAX B         ;ADDR OF LAST BUFF IN DEST Q
       ANA  A         ;(IS DEST Q EMPTY?) 
       MOV  D,A       ;SAVE ADDR OF LAST IN D 
       MOV  A,H       ;ADDR OF 1ST BUFF IN SOURCE 
       STAX B         ;TAIL=ADDR OF 1ST SOURCE BUF
; 
       MOV  H,D       ;H,L POINT TO CHN OF LAST 
;                     BUFF IN DESTINATION Q 
       JNZ  XQH300    ;BRANCH IF DEST Q NOT EMPTY 
; 
;   SPECIAL CASE WHEN DESTINATION QUEUE EMPTY 
; 
       INX  B         ;SET DEST Q HEAD TO 1ST BUFF
       MOV  H,B       ;H,L POINT TO DEST Q HEAD 
       MOV  L,C       ;A=ADDR OF 1ST SOURCE Q BUFF
       ANA  A         ;SET NZ CODE FOR RET
; 
;   HERE TO LINK 1ST BUFF IN SOURCE QUEUE TO
;   LAST BUFF IN DESTINATION QUEUE OR SET HEAD OF 
;   DESTINATION QUEUE TO 1ST BUFF OF SOURCE QUEUE 
; 
XQH300:MOV  M,A 
       RET            ;(CAUTION: MUST RETURN NZ)
 
;************************************************ 
; 
;   DCSTOP
;        WAITS FOR CURRENT DATACOM OPERATIONS 
;        TO FINISH
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A DESTROYED 
;             INTERRUPTS DISABLED, DATACOM CEASED 
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
DCSTOP:DI             ;INTERRUPTS OFF WHILE CHECK 
       LDA  ASFLAG    ;AND CHECK TO SEE IF
       ANA  A         ;DATACOM TRANSMITTING OR
;                     RECEIVING 
       RZ             ;CAUGHT HIM! RETURN WITH DI 
       EI             ;LET INTERUPTS HAPPEN HERE
       JMP  DCSTOP    ;STILL BUSY, KEEP TRYING
 
;************************************************ 
; 
;   PAREBC
;        TRANSLATE ASCII TO EBCDIC
;        OR ADD PARITY
; 
;   ENTRY     B = CHARACTER TO TRANSLATE
; 
;   EXIT      IF HCODE=0 AND PMASK=0 THEN A=B 
;             ELSE IF B=177 & HCODE=1 THEN A=377
;             ELSE IF B=177 & PMASK=1 & KB2SMN=1
;                  THEN A=377 
;             ELSE IF HCODE=1, A=TRANSLATED B 
;             ELSE IF PMASK=1, A=PARITY'D B 
;             B NEVER MODIFIED; C,D DESTROYED 
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
PAREBC:LDA  CONFIG    ;IF NEITHER EBCDIC NOR 8-BIT
       ANI  HCODE+PMASK      ;MODE, THEN DO NOTHIN
       MOV  C,A       ;SAVE CONFIG BITS 
       MOV  A,B       ;CHARACTER TO XLATE OR PARIT
       RZ             ;RET IF HCODE=0 & PMASK=0 
; 
       CPI  TPADI     ;CHECK FOR ASCII TPAD 
       JNZ  PARCHK    ;BRANCH IF NOT TPAD 
; 
       LDA  KBJMP2    ;IF KB2SMN=1 (AND PMASK=1)
;                     THEN WANT TPADIO=377
;                     REGARDLESS OF PARITY
       ORA  C         ;ALSO WANT TPADIO=377 
       ORI  TPADI     ;IN EBCDIC MODE 
       RM             ;RET IF FORCED TPADIO=377 
; 
PARCHK:MOV  A,C       ;HCODE & PMASK BITS 
       ANA  A         ;(KNOW ONE OF THEM IS ON) 
       JP   PARITY    ;IF PMASK, GO ADD PARITY
; 
;   HERE TO TRANSLATE FROM ASCII TO EBCDIC
;   (EXCEPT FOR TPAD'S) 
; 
       PUSH H         ;(SAVE FOR CALLER)
       LHLD HEXOUT    ;ADDR OF TRANSLATE TABLE
       MOV  A,B       ;CHARACTER TO TRANSLATE 
       ANI  177Q      ;LOW ORDER 7 BITS ONLY
       ADD  L         ;COMPUTE LOW-ORDER ADDR 
       MOV  L,A       ;(ASSUMES 128 ALIGNMENT)
       MOV  A,M       ;TRANSLATED CHARACTER 
; 
       POP  H 
       RET
 
;************************************************ 
; 
;   CTL2ON    ENTER WITH A = BITS TO TURN ON
;             (IN IODC+OCTL2) 
; 
;   CTL2OF    ENTER WITH A = BITS TO TURN OFF 
; 
;   CAON      TURN ON "CA"
; 
;   CAOND1    TURN ON "CA" ONLY IF DEV1 IS NOT ON 
; 
;   CAOFF     TURN OFF "CA" 
; 
;   ALL EXITS 
;             A = RESULT OUTPUT TO BOARD
;             H,L DESTROYED 
; 
;************************************************ 
;   ENTRY POINT 
; 
CAOND1:LDA  IODC+ST2  ;TURN ON "CA" 
       ANI  ST2CCZ    ;ONLY IF NOT DEV1 
       RZ 
; 
;   ENTRY POINT 
; 
CAON:  MVI  A,CT2CAZ  ;TURN ON "CA" 
; 
;   ENTRY POINT 
; 
CTL2OF:LXI  H,CTL2    ;CTL2 ALWAYS = IODC+OCTL2 
       CMA            ;MASK OF BITS TO LEAVE ON 
       ANA  M         ;TURN OFF SPECIFIED BITS
       JMP  CTL2ST    ;AND UPDATE OCTL2 
; 
;   ENTRY POINT 
; 
CAOFF: MVI  A,CT2CAZ  ;TURN OFF "CA"
; 
;   ENTRY POINT 
; 
CTL2ON:LXI  H,CTL2    ;CTL2 ALWAYS = IODC+OCTL2 
       ORA  M         ;TURN ON SPECIFIED BITS 
CTL2ST:MOV  M,A       ;UPDATE CTL2
       STA  IODC+OCTL2  ;AND THE DC BOARD 
       RET
 
;************************************************ 
; 
;   STRBCC
;        COMPUTE BCC FOR CHARACTER STRING 
;        TERMINATED BY A STOPER 
; 
;   ENTRY     H,L POINT TO STRING 
;             ASCRC,ASLRC INITIALIZED 
;                  TO THE APPROPRIATE VALUE 
; 
;   HDRBCC
;        COMPUTE BCC FOR HEADER 
; 
;   ENTRY     ASBCC = 0 
; 
;   EXIT      ALL REGS DESTROYED
;             BCC IN ASCRC,ASLRC
; 
;************************************************ 
; 
;   ENTRY POINT 
; 
HDRBCC:LXI  H,ID1     ;COMPUTE BCC FOR HEADER 
; 
;   ENTRY POINT 
; 
STRBCC:MOV  B,M       ;1ST CHAR IN STRING 
; 
STRB10:PUSH H         ;(BCC DESTROYS H,L) 
       CALL BCC       ;ACCUMULATE NXT CHAR IN BCC 
       POP  H 
       INX  H         ;POINT TO NXT CHAR
       MOV  B,M       ;NEXT CHAR IN STRING
       MOV  A,B 
       ANA  A         ;IS IT A STOPER?
       JNZ  STRB10    ;NO, CONTINUE 
       RET            ;YES, DONE
 
;************************************************ 
; 
;   WRUS3P
;        SET UP WRU STATUS BYTE #3
;        AND ADD PARITY TO TRANSMIT STRING
;        AND ADD STOPER TO TRANSMIT STRING
; 
;   WRUST3
;        AS ABOVE, EXCEPT FORCE 0 PARITY
; 
;   ENTRY     DON'T CARE
; 
;   EXIT      A,B,C,D,E DESTROYED 
;             H,L POINT TO BEGINNING OF WRUSTS
; 
;************************************************ 
; 
;   WHO-ARE-YOU STATUS BYTE #3: 
;        BITS 3-0 = TRMTYP
;        BIT  4   = REMSET
;        BIT  5   = 1 ONLY IF ASBCNT > 0
;        BIT  6   = 1 
; 
;   ENTRY POINT 
; 
WRUST3:MVI  C,PMASK+VRCFC0   ;CLEAR PARITY BITS 
       JMP  WRUS25
; 
;   ENTRY POINT 
; 
WRUS3P:LDA  CONFIG    ;ADD CORRECT PARITY 
       MOV  C,A 
; 
WRUS25:LDA  TRMTYP    ;LOW ORDER 4 BITS=TERM TYPE 
       ANI  17Q       ;CLEAR OTHER JUNK 
       MOV  B,A       ;SAVE FOR LATER 
       LDA  CMFLGS    ;WANT LOCAL/REMOTE BIT
       ANI  REMSET    ;CLEAR OTHER JUNK 
       ORA  B         ;COLLECT STATUS BITS
       MOV  B,A       ;SAVE FOR LATER 
       LDA  ASBCNT    ;WANT BIT TO SAY THAT TERM
;                     WANTS TO TRANSMIT 
       DCR  A         ;IF ASBCNT > 0, THEN TERM 
       MOV  A,B       ;WANTS TO TRANSMIT
       JM   WRUS50    ;BRANCH IF NOTHING TO SEND
       ORI  40Q       ;BIT TO SAY WANT TO SEND
WRUS50:ORI  ATSINI    ;MAKE BYTE BE ALPHA 
; 
       MOV  B,A       ;SET UP FOR LOOP
       LXI  H,WRUSTS+3  ;ADDR OF XMIT STOPER
       MVI  M,0       ;APPEND STOPER TO STRING
       DCX  H         ;ADDR OF 3RD STATUS BYTE
       MVI  E,2       ;# OF STATUS BYTES, LESS 1
; 
;   LOOP TO ADD PARITY TO WRU STATUS BYTES
; 
WRUS75:MOV  A,C       ;C DETERMINES PARITY TO ADD 
       CALL PARITC    ;(0 OR CORRECT) 
       MOV  M,A       ;STORE IN STATUS STRING 
       DCR  E         ;COUNT OF # OF BYTES
       RM             ;RETURN IF CNT DEPLEATED
       DCX  H         ;PT TO NEXT STATUS BYTE 
       MOV  B,M       ;FETCH NEXT BYTE
       JMP  WRUS75    ;CONTINUE 
 
DIAGDC EQU  $ 
       LDA  DCSPTR
       STA   DCBPTR   ;SET GET BUFFER ADDR
       LDA  KBDCSW    ;READ KB DC SWITCHES
       STA  IODC0+IODCCT  ;SET DC CONTROLS BAUD RA
       LXI  H,DIA900  ;SET DIAGNOSTIC DC INTERRUPT
       SHLD  ASVCT1   ;SET VCT1 
       JMP  RTNCZ2    ;RETURN WITH NC & Z FLAGS 
;                     AND DON'T ENABLE INTERRUPTS 
DIA500 EQU  $ 
       LHLD DCSPTR    ;GET BUFFER ADDR
       LDA  DCBPTR    ;GET STORE BUFFER ADDR
       CMP  L         ;ARE THEY THE SAME? 
       JZ  WAIT 
DIA507 EQU  $ 
       MOV  L,A       ;BUMP GET BUFFER ADDR 
       INR  A          ;INTO A
       STA  DCBPTR    ;AND STORE INTO DCBPTR
       MOV  A,M       ;GET CHAR FROM BUFFER 
       CPI  ENQI      ;IS CHAR ENQ? 
       JNZ  RETNCZ
DIA600 EQU  $ 
       LXI  H,WAIT    ;LOAD WAIT RETURN ADDR
       MVI  D,ACK     ;SET FOR ACK RESPONSE 
       JMP  DIA800    ;GO TO OUTPUT ACK 
DIA700 EQU  $ 
       LXI  H,RETNCZ  ;LOAD RETURN ADDR 
DIA800 EQU  $ 
       LDA  IODC0+IODCST ;READ DC STATUS
       ANI  DCTBE     ;IS XMIT BUFFER EMPTY 
       JZ   DIA800    ;NO LOOP TILL YES 
       MOV  A,D       ;RESTORE CHAR 
       STA  IODC0+IODCDO ;OUTPUT CHAR 
       PCHL 
DIA900 EQU  $ 
       LXI  H,EXIT    ;LOAD EXIT ADDR 
       PUSH H         ;SET RETURN 
       LDA  IODC0+IODCST  ;READ STATUS DC 
       LDA  IODC0+IODCDI  ;GET THE CHAR 
       ANI  177Q      ;REMOVE PARITY BIT
       RZ             ;RETURN IF NULL 
       CPI  ADEL      ;CHECK FOR RUBOUT 
       RZ             ;RETURN IF RUBOUT 
DIA910:LHLD DCSPTR    ;GET STORE BUFFER PTR 
       MOV  M,A       ;STORE THE CHAR 
       INR  L         ;BUMP THE PTR 
       SHLD DCSPTR    ;STORE THE NEW PTR
       RET
 
;*************************************************
; 
;  BCC -  BLOCK CHECK CHARACTER 
;           ENTRY:    B=CHAR TO BE BLOCK CHECKED
;           EXIT:     B+C=ORIGINAL CHARACTERS 
;                     D,E,H,L ARE DISTROYED 
; 
;         THIS ROUTINE DOES A LRC OR CRC16
;             DEPENDING ON WHETHER THE XMIT CODE
;             IS EBCDIC OR THE BCC IS A CRC16 OR
;             THE TERM IS IN TRANPARENCY MODE 
; 
;*************************************************
BCC    EQU  $         ;ENTRY  B = CHAR  ASBCC =BCX
       LHLD ASBCC     ;GET BCC
       LDA  CONFIG    ;GET CONFIGURATION BYTE 
       ANI  CRC16     ;CRC16 CK REQUIRED??
       JNZ  CRCOUT    ;GO DO CRC16
       MOV  A,B       ;A=CHAR 
       XRA  L         ;BUMP LRC 
       STA  ASBCC     ;SAVE LRC 
       RET            ;RETURN TO CALLER 
CRCOUT EQU  $ 
       MOV  A,B       ;RESTORE A
; 
;      NXCRC  ADD BYTE TO CRC16 
; 
;           ENTRY:  A = BYTE TO BE ADDED
; 
;           EXIT:  D,E  DISTROYED 
;                  H,L = CRC (LSB,MSB)
NXCRC: XRA  L         ;COMPUTE R(I,H) + M(I)
       MVI  E,0       ;SET C-REG FOR EVEN PARITY
       JPE  NXCL1     ;SET PARITY TRRM
       INR  E         ;SET E TO 1 FOR ODD PARITY
NXCL1: RAR            ;COMPUTE (R+7) * X
       JC   NXCL3     ;SET CARRY BYTE 
       MVI  L,0       ;NO CARRY   SET TO ZERO 
       JMP  NXCL4 
NXCL3: MVI  L,200Q    ;SET CARRY TO X**9
       ANA  A         ;CLEAR THE CARRY FLAG 
NXCL4: MOV  D,A       ;SAVE INTERMEDIATE RESULT 
       RAR            ;COMPUTE (R+M) * X**2 
       JNC  NXCL5     ;SKIP IF NO CARRY 
       INR  L         ;SET CARRY TO X**8
NXCL5: XRA  D         ;COMBINE PARITY TERM WITH LS
       MOV  D,A       ;OF NEWCRC AND SAVE IT
       MOV  A,E       ;FETCH PARITY FLAG
       RRC            ;SET UP PARITY ADJUSTMENT 
       RAR            ;WORD = (1+X) * PARITY
       XRA  D         ;COMBINE WITH (M+R)*(X+X**2)
       MOV  D,A       ;SAVE RESULTS 
       MOV  A,L       ;FETCH CARRY BYTE 
       RRC            ;ROTATE BITS TO PROPER PLACE
       XRA  L         ;COMBINE M(0) AND M(1)
       ANI  300Q      ;CONSIDER UPPER 2 BITS ONL
       XRA  H         ;ADD TO LSB OF PREVIOUS CRC 
       XRA  E         ;ADD IN PARITY TERM 
       MOV  L,A       ;SET NEW CRC BYTES
       MOV  H,D 
       SHLD ASBCC     ;RESTORE BCC
       RET            ;RETURN TO SENDER 
;************************************************ 
; 
;      PARITY   IF FORCED PARITY IS ON
;              THIS ROUTINE ADDS PARITY TO THE
;              CHARACTER
; 
;           ENTRY:    B=CHARACTER TO CALC 
;                     PARITY AGAINST
; 
;           EXIT:     A=CHARACTER + PARITY
;                     B=ORIGINAL CHAR 
;                     C=CONFIG
;                     D=DISTROYED 
; 
PARITY EQU  $ 
       LDA  CONFIG    ;GET CONFIG BYTE
       MOV  C,A       ;C=CONFIG 
PARITC EQU  $ 
       ANI  TPAR      ;XPARENT??
       MOV  A,B       ;A = CHAR 
       RNZ            ;YES SKIP PARITY
PARITP EQU  $ 
       MOV  A,C       ;A = CONFIG 
       ANI  PMASK     ;PARITY MASK??
       MOV  A,B       ;A = CHAR 
       RZ             ;NO RETURN TO CALLER
PARIT  EQU  $ 
       MOV  A,B       ;A=CHAR 
       ANI  177Q      ;USE ONLY 7 LOWER BITS
       MOV  D,A       ;SAVE 7 LO BITS 
       ANA  A         ;SET PARITY CONDITION CODE
       MOV  A,C       ;GET CONFIG 
       RRC  ;PUT VRC1 IN HI ORDER BIT 
       JPE  PAR010    ;JUMP IF PARITY IS EVEN 
       RRC            ;PUT VRC2 IN HI ORDER BIT 
PAR010 EQU  $ 
       ANI  200Q      ;MASK ALL BUT PARITY BIT
       ORA  D         ;OR IN 7ORIG BITS 
       RET            ;RETURN TO CALLER 
; 
;    CHECK TIME ROUTINE 
;             ENTRY: ASTCNT CONTAINS TIMER CNT
;             EXIT: ASTCNT CONTAINS ADJUSTED TCNT 
;                   CC = Z IF TCNT = O
;                   CC = NOT Z IF TCNT = NOT ZERO 
; 
;              THIS ROUTINE DECREMENTS THE TIMER
;                CNT AND RESETS THE TIMER IF THE
;                CNT IS NOT ZERO. 
; 
CKTIME EQU  $ 
       STA  IODC+RTIME  ;RESET TIME 
       LDA  ASTCNT    ;GET TIMER COUNT
       DCR  A         ;TCNT=TCNT-1
       RZ             ;RETURN IF ZERO 
       STA  ASTCNT    ;RESTORE TCNT 
       STA  IODC+STIME  ;GO SET TIMER 
       RET            ;RETURN 
 
       ORG  ZDCBAS+4000Q     ;BEG OF NEXT ROM 
; 
REV1A: DB   'S'       ;ROM IDENTIFIER BYTE PAIR 
;                     (DATACOM VERSION #3)
       DB   (ZDCBAS+4000Q)/256
; 
;    TABLE OF CONTROL SEQUENCE FLAGS FOR
;    "SHORT POLL/SELECT" (WHEN 1ST 2 CHARS
;    MATCH GID AND 3RD CHAR IS "ENQ", THEN
;    CTLIN USES THIS TABLE TO DETERMINE 
;    WHETHER CTL SEQ IS A POL OR SELEC
; 
;   WARNING: TABLE MUST BEGIN ON 256+2 BOUNDARY 
; 
MATABL EQU  $ 
MATBLH EQU  MATABL/256       ;HI ORDER ADDR 
;                            OF CTL SEQ TBL 
; 
       DB   0         ;1ST CHAR="OTHERS", NO MATCH
       DB   POL       ;1ST CHAR=GROUP ID
       DB   SELEC     ;1ST CHAR=SELECT ID 
       DB   0         ;1ST CHAR=TILDA, NO MATCH 
 
;*************************************************
; 
;  EOTIN - PUTS TERMINAL IN CONTROL MODE
;            WAITING FOR CONTROL SEQUENCE 
; 
;************************************************ 
RPADIN:CALL ETV1P     ;WAIT FOR TPAD & RESET
EOTIN  EQU  $         ;CLR DATA COMM CARD FOR EOT 
       MVI  A,CT2CBD+CT2CMM+CT2CDZ
       CALL CTL2OF    ;GO SET CTL2 BIT OFF
EOTIN1 EQU  $ 
       CALL RESEXT    ;GO RESET + SET EXIT
       JMP  EXIT      ;GO WAIT FOR INTERRUPT
EOTSRH EQU  $         ;SEARCH FOR EOT CHAR
       CPI  ST1IBF    ;INPUT BUFF FULL ONLY?? 
REV1B: JNZ  EOTIN1    ;NO, GO RESET THE RECEIVER
;                     (DON'T DROP CB INHIBIT) 
EOT010 EQU  $ 
       LDA  TPADIO    ;CHECK TO SEE IF CHAR=TPAD
       CMP  B 
       JZ   RTIMER    ;CHAR=TPAD, GO IGNORE IT
EOT012 EQU  $ 
       LDA  SYNC      ;A=SYNC ??
       CMP  B 
       JZ   RTIMER    ;YES  IGNORE
       CALL CKDLE     ;GO CK FOR DLE??
       JZ   RTIMER    ;DLE IN  GO WAIT
EOT015 EQU  $ 
       LDA  EOT      ;GET EOT CHAR
       CMP  B         ;CHAR = EOT???
       JNZ  ASJMP2    ;NO  EXIT THRU VECTOR 2 
       MOV  A,C       ;A=CONFIG 
       PUSH PSW       ;SAVE PSW 
       CALL TQDQ      ;GO DEQ BUFFERS 
       POP  PSW       ;RESTORE PSW
       ANI  DLC       ;DLE IN ??
       JZ   EOT020    ;NO GO TO CTLIN 
DISCON EQU  $ 
       MVI  A,CT2CAZ+CT2CBD+CT2CDZ  ;ZERO CA AND C
       CALL RESCT2    ;RESET DC + SET CTL2
       MVI  A,300Q    ;SET TIMER TO 10 SECS 
       CALL ETV1P     ;SET VECTOR1 + TIMER
DIS010 EQU  $ 
       CALL CKTIME    ;GO CK TIMER
       JZ   EOTIN     ;TIME UP GO TO CTL MODE 
       JMP  EXIT      ;TIME NOT UP GO WAIT
;************************************************ 
; 
;  EOTSRH - TERMINAL IS WAITING FOR EOT CHAR
;             AT BEGINNING OF CONTROL SEQUENCE
; 
;************************************************ 
EOT020 EQU  $ 
       CALL RESET 
       LXI  H,CTLIN   ;SET VECTOR 2 TO CTLIN
       JMP  ETV2      ;GO SET TIMER + VECTOR2 
;*************************************************
ETV1P: POP  H         ;NEXT INTERRUPT HANDLER 
ETV1   EQU  $         ;EXIT-SET TIMER,ASVCT1
       SHLD ASVCT1    ;PUT H&L IN VECTOR 1
       JMP  RTIME1    ;GO SET TIME
ETV1V2 EQU  $         ;EXIT-SET TIMER,ASVCT1,ASVCT
;                     ASVCT1=H&L ASVCT2=D&E 
       SHLD ASVCT1    ;PUT H&L IN VECTOR 1
ETV2X  EQU  $ 
       XCHG           ;H+L=D&E
ETV2   EQU  $         ;HXIT SET TIMER,ASVCT2
       SHLD ASVCT2    ;PUT H&L IN VECTOR 2
RTIME1 EQU  $         ;SET TIMER CNT TO 1 
       STA  ASTCNT    ;STORE TIMER CNT
RTIMER EQU  $         ;RESET & SET TIMER
       STA  IODC+RTIME  ;RESET TIMER
       STA  IODC+STIME  ;SET TIMER
;************************************************ 
; 
;  STANDARD EXIT ROUTINE  RESTORES ALL STATUS 
;      ENABLE INTERRUPTS
; 
;************************************************ 
EXIT   EQU  $         ;EXIT ROUTINE 
       POP  PSW       ;*
       POP  H         ;*
       POP  D         ;* RESTORE ALL STATUS 
       POP  B         ;*
       EI             ;ENABLE INTERRUPTS
       RET            ;EXIT INTERRUPT PROCESSOR 
; 
CKSTX  EQU  $ 
       CALL CKTDLC    ;TPAR OR DLC ON ??
REV1C: JZ   EOTIN1    ;NO, GO RESET THE RECEIVER
;                     (CHAR INPUT IS INVALID
;                     IN CONTROL MODE)
       LDA  STX 
       CMP  B         ;CHAR = STX?? 
REV1D: JNZ  EOTIN1    ;NO, GO RESET THE RECEIVER
;                     (CHAR INPUT IS INVALID
;                     IN CONTROL MODE)
REV1E: JMP  ABORT1    ;YES, WAIT FOR END OF BLK 
;                     (DON'T CALL DABORT) 
 
;*************************************************
; 
;   CTLIN 
;        PARSES CONTROL SEQUENCE
; 
;   ENTRY     B=INPUT CHARACTER 
;             INPUT STATUS OK 
;             PADS & SYNCS ALREADY CHECKED FOR
; 
;   EXIT      ASFLAG = CONTROL SEQUENCE FLAG
;             DISPATCHED TO APPROPRIATE HANDLER 
; 
;*************************************************
; 
;   HANDLING ROUTINES:
;        CKDATA    DEVICE OR GROUP POLL 
;        SELIN     DEVICE SELECT
;        BCSTIN    GROUP OR LINE BROADCAST
;        WRU000    WHO-ARE-YOU
; 
;        CONTROL PASSES TO CKDATA, SELIN OR WRU000
;        AFTER THE "ENQ" INTERRUPT; THE ROUTINES
;        ARE EXPECTED TO WAIT FOR THE "TPAD". 
;        CONTROL PASSES TO BCSTIN AFTER THE 1ST 
;        DATA CHARACTER INTERUPT. 
; 
;   OPERATION OF MODEM SIGNALS: 
;        DOWNLINE CB INHIBITED AFTER RECEIVING THE
;        2ND CHARACTER OF THE CONTROL SEQUENCE, 
;        BUT ONLY IF IT MATCHES THE 1ST CHARACTER 
;        OF THE SEQUENCE (EG AFTER THE 2ND GROUP
;        ID CHARACTER OF A GENERAL POLL); NOTE
;        THAT INHIBIT REQUIRED AFTER 2ND CHAR 
;        MATCH BECAUSE OF SELF-TEST; ALSO NOTE
;        THAT REQUIRED TO BE AT LEAST 1 CHAR
;        TIME BEFORE RAISING CA TO ENSURE 
;        THAT CA DOESN'T GET TO MODEM TOO 
;        EARLY (IE, BEFORE TPAD COMES IN); NOTE 
;        THAT CB IS INHIBITED FOR ALL CONTROL 
;        SEQUENCES. 
; 
;        IF THE CONTROL SEQUENCE IS A GPOLL OR
;        WRU, THEN CA IS RAISED AFTER THE 3RD CHAR
;        OF THE CONTROL SEQUENCE, REGARDLESS OF 
;        WHETHER OR NOT THERE IS DATA (EG AFTER 
;        FIRST QUOTE OF GENERAL POLL).  NOTE THAT 
;        IN THE SPECIAL CASE WHEN THE TERMINAL IS 
;        1ST IN THE CHAIN, RAISING CA IS DELAYED
;        UNTIL AFTER THE TPAD IS INPUT. 
; 
;        IF THE CONTROL SEQUENCE IS NOT FOR THE 
;        PARTICULAR TERMINAL, DOWNLINE CB INHIBIT 
;        IS DROPPED AFTER THE TPAD IS INPUT.
;        NOTE THAT MULTIPLE GROUPS/DROP ARE 
;        ALLOWED BECAUSE 1ST TERM IN CHAIN WAITS
;        TILL AFTER TPAD BEFORE DROPPING DOWN-
;        LINE CB INHIBIT. 
; 
;   PARSING ALGORITHM:
;        1ST CHAR:
;             THE INPUT CHARACTER IS COMPARED 
;             AGAINST THE 1ST 3 ENTRIES IN CTLTBL;
;             A MATCH # IS RECORDED IN ASWK2 AS 
;             GIVEN BY THE FOLLOWING TABLE
; 
;                  INPUT          RESULTING 
;                  CHAR           MATCH # 
;             ------------------------------------
;                  TILDA               3
;                  SELECT ID           2
;                  GROUP ID            1
;                  "OTHERS"            0
; 
;        2ND CHAR:
;             INPUT CHAR COMPARED AGAINST IDIN
;             (WHERE 1ST CHAR RECORDED); IF THEY
;             ARE NOT IDENTICAL, THE MATCH # IN 
;             ASWK2 IS FORCED TO 0. 
; 
;        3RD CHAR:
;             THE CONTROL SEQUENCE FLAG STORED IN 
;             ASWK2 IS A FUNCTION OF THE INPUT
;             CHAR, THE ENTRIES IN CTLTBL, AND THE
;             MATCH # RECORDED IN ASWK2, AS GIVEN 
;             BY THE FOLLOWING TABLE
; 
;             INPUT     MATCH #        RESULTING
;             CHAR      IN ASWK2      CTL SEQ FLG 
;             ------------------------------------
;             TILDA     3              LBCAST =010
;             TILDA     2              GBCAST =020
;             DEV ID    2              SELEC  =040
;             DEV ID    1              POL    =100
;             QUOTE     1              GPOLL  =200
;             BRACE     1              WRU    =001
; 
;        4TH CHAR:
;             MUST MATCH 3RD, ANALAGOUS TO 2ND
; 
;        5TH CHAR:
;             MUST BE ENQ IF SELEC, POL, GPOLL
;             OR WHO-ARE-YOU
 
CTLIN: MVI  E,3       ;# OF LEGAL 1ST CHARS 
       LXI  H,CTLTBL+2  ;ADDR OF LAST CHAR IN TBL 
       MOV  A,B       ;INPUT CHAR (1ST IN SEQ)
; 
;   LOOP TO FIND 1ST CTL CHAR IN TABLE
; 
CTL100:CMP  M         ;INPUT MATCH ENTRY IN TBL?
       JZ   CTL120    ;YES, BRANCH
       DCX  H         ;POINT TO NEXT TBL ENTRY
       DCR  E         ;COUNT & CHAR-MATCH-# 
       JNZ  CTL100    ;CONTINUE TIL CNT DEPLEATED 
; 
;   WHEN HERE, C HAS MATCH # (0 = NO MATCH) 
; 
CTL120:MOV  D,B       ;SAVE 1ST CHAR (CMP TO 2ND) 
       XCHG           ;SAVE CHAR-MATCH-#
       SHLD ASWK2     ;ASWK2=MATCH#, ASWK2+1=CHAR 
; 
       LXI  H,CTL300  ;WHERE TO GO AFTER 2ND CHAR 
; 
CTL130:LXI  D,CTL200  ;CTL200 HANDLES NXT CHAR
CTL140:SHLD ASWK3     ;WHERE TO GO AFTER THAT CHAR
       JMP  ETV2X     ;SET VCT2=D,E & EXIT
; 
;   HERE TO ENSURE 2ND CHAR MATCHES 1ST 
;   AND 4TH MATCHES 3RD 
; 
CTL200:LDA  ASWK2+1   ;LAST CHAR (1ST OR 3RD) 
       CMP  B         ;DOES 2ND=1ST OR 4TH=3RD ?
       MVI  A,CT2CBD
       JZ   CTL250    ;YES, INHIBIT DOWNLINE CB 
; 
       SUB  A         ;NO, THEN ILLEGAL SEQUENCE
       STA  ASWK2     ;SO SET MATCH # TO 0
;                     AND DON'T 
CTL250:CALL CTL2ON    ;INHIBIT CB 
       LHLD ASWK3     ;GET RETURN ADDR
       JMP  ETV2      ;SET VCT2 & EXIT ANYWAY 
; 
;   HERE TO HANDLE 3RD CHAR OF SEQUENCE 
; 
CTL300:LXI  H,CTLTBL+2  ;TBL OF POSSIBLE 3RD CHARS
       LXI  D,3*256+LBCAST   ;D=3 (LARGEST MATCH #
;                            E=LBCAST (1ST FLAG)
       LDA  ASWK2     ;C=MATCH # OF 1ST CHAR
       MOV  C,A 
; 
;   LOOP TO FIND A MATCH BETWEEN THE 3RD CHAR 
;   AND AN ENTRY IN CTLTBL AND A MATCH WITH THE 
;   MATCH# FOUND FOR 1ST CHAR OF CONTROL SEQUENCE 
; 
CTL320:MOV  A,B       ;INPUT CHAR (3RD IN SEQ)
       CMP  M         ;DOES IT MATCH TBL ENTRY? 
       JNZ  CTL330    ;NO MATCH, GO TO NXT ENTRY
; 
;   HERE WHEN 3RD CHAR MATCHES ENTRY IN TBL 
; 
       MOV  A,C       ;DOES 1ST CHAR MATCH # FIT? 
       CMP  D         ;D HOLDS APPROPRIATE MATCH #
       JZ   CTL340    ;HEY, IT MATCHES! 
; 
CTL330:INX  H         ;ADDR OF NEXT ENTRY IN TBL
       MOV  A,E       ;COMPUTE NEXT FLAG BIT
       RLC            ;(AS-FLAGS MUST BE IN ORDER)
       MOV  E,A       ;(FLAG OF 0 MEANS NO MATCH) 
       ANI  (LBCAST+SELEC+WRU)*2  ;IF WERE AT 
;                     ONE OF THESE FLAGS, TIME TO 
;                     UPDATE CORRECT MATCH #
       JZ   CTL320    ;MATCH# OK, CNT SEARCH
       DCR  D         ;UPDATE MATCH # 
       JNZ  CTL320    ;CONTINUE TIL TBL DEPLEATED 
       MOV  E,D       ;HERE, SEQUENCE IS ILLEGAL
;                     SO SET FLAGS TO 0 
; 
;   HERE WHEN HAVE RESOLVED WHAT THE CONTROL
;   SEQUENCE IS;  E HAS FLAG FOR CTL SEQ
;   (OR 0 IF ILLEGAL) 
; 
CTL340:MOV  D,B       ;3RD CHAR OF SEQUENCE 
       XCHG           ;ASWK2=CTL SEQ FLAGS
       SHLD ASWK2     ;ASWK2+1=3RD CHAR OF SEQ
; 
       MOV  A,L       ;CTL SEQ FLAGS
       ANA  A         ;0=INVALID SEQ
       JZ   CTL360    ;IF INVALID, GO CHECK ENQ 
; 
       ANI  GPOLL+WRU  ;CONDITIONS UNDER WHICH
       CNZ  CAOND1    ;WE SHOULD TURN ON "CA" 
; 
CTL350:LXI  H,CTL500  ;WHERE TO GO FOR 5TH CHAR 
       JMP  CTL130    ;SET UP TO CHECK 4TH CHAR 
; 
;   HERE WHEN 3RD CHAR OF SEQUENCE DOESN'T MATCH
;   CHECK FOR ENQ 
;   (WILL ACCEPT GID-GID AS VALID POLL SEQ
;   OR SID-SID AS VALID SELECT SEQ) 
; 
CTL360:LDA  ENQ       ;CHECK 3RD CHAR FOR ENQ 
       CMP  B         ;IF NOT AN ENQ, THEN
REV1F: JNZ  REV1O     ;MUST BE LONG CTL SEQ 
;                     (ADD CODE TO LOWER
;                     INHIBIT IF NOT 1ST) 
;                     IF IT IS ENQ, THEN
;                     ASSUME SHORT SEQ
; 
       MVI  B,MATBLH  ;B,C=ADDR OF CTL SEQ FLGS 
       INX  B         ;(TBL BEGINS ON 256 BOUNDARY
       INX  B         ;PLUS OFFSET OF 2)
       LDAX B         ;A=SELEC IF 1ST CHAR = SID
;                     A=POL IF 1ST CHAR = GID 
       STA  ASFLAG    ;SET CONTROL SEQUENCE FLAG
       JMP  CTL520    ;GO DISPATCH TO HANDLER 
; 
;   WHEN HERE, HAVE 1ST FOUR CHARS OF CTL SEQ 
; 
CTL500:LDA  ASWK2     ;CTL SEQUENCE FLAGS 
       CPI  POL       ;IF GPOLL OR POL AND 4-CHAR 
       JC   CTL510    ;CTL SEQ, THEN WANT TO
       ORI  HDRSW     ;TURN ON THE HDR SWITCH 
CTL510:MOV  C,A       ;CTL SEQUENCE FLAGS 
       STA  ASFLAG    ;SET CONTROL SEQUENCE FLAG
; 
       ANI  BCAST     ;IF BROADCAST SEQ, INPUT DAT
       JNZ  BCSTIN    ;(NO ENQ FOR BROADCAST) 
;                     (NOTE THAT LIGHT WILL NOT 
;                     FLASH WHEN GET BROADCAST) 
; 
       LDA  ENQ       ;ENQ (XLATED & PARITY'D)
       CMP  B         ;IS THE INPUT AN ENQ? 
       JNZ  RPADIN    ;NO, GO BAIL OUT, ILLEGAL 
; 
       MOV  A,C       ;CTL SEQUENCE FLAGS 
; 
CTL520:LXI  H,ASACK   ;MUST INITIALIZE ACK FLAG 
       MVI  M,ACKDC   ;GPOLL & WRU USE ACKDC
; 
       CPI  POL       ;CTL SEQ = GPOLL OR POL ? 
       JC   CTL530    ;JMP IF NOT A GPOLL OR POL
       ANA  A         ;TEST FOR GPOLL BIT 
;                     (WARNING: HDRSW MAY BE ON)
       JM   CKDATA    ;BRANCH IF GPOLL CTL SEQ
       MVI  M,ACK1F   ;IF POL, NEED ACK FLAG = 1
       JMP  CKDATA    ;GPOLL&POL GO TO CKDATA 
; 
CTL530:RRC            ;WRU CTL SEQ? 
       JC   WRU000    ;YES
; 
       MVI  M,ACK0F   ;SELEC NEEDS ACK FLAG = 0 
       ANI  SELEC/2   ;SELECT CTL SEQ?
       JNZ  SELIN     ;YES
       JMP  RPADIN    ;FLAG BYTE = 0; GO BAIL OUT 
 
;************************************************ 
; 
;   WRU000
;        ROUTINE TO TRANSMIT WHO-ARE-YOU STATUS 
;        SEQUENCE CONSISTS OF OPTIONAL LDR, HDR 
;             FOLLOWED BY 3 STATUS BYTES, 
;             ETX AND BCC 
; 
;************************************************ 
WRUNAK EQU  $         ;HERE TO RETRANSMIT STATUS
WRU000:LXI  H,WRU200  ;WHERE TO COME BACK TO
       JMP  PADIN     ;AFTER WAITING FOR TPAD 
; 
;   HERE WHEN WANT TO TRANSMIT WRUSTS 
; 
WRU200:LXI  H,HDR     ;ALWAYS TACK ON HEADER
       LXI  D,WRU300  ;WHERE TO COME BACK TO AFTER
       JMP  SDDXMT    ;TRANSMITTING THE HEADER
; 
;   HERE TO TRANSMIT THE WRU STATUS STRING
;   AND SET UP TO FOLLOW IT WITH BCC STRING 
; 
WRU300:LHLD ASBCC0    ;INITIALIZE BCC TO ZERO 
       SHLD ASBCC 
       CALL HDRBCC    ;CALCULATE BCC FOR HEADER 
       CALL WRUS3P    ;SET UP WRU STATUS STRING 
       CALL STRBCC    ;ADD IN BCC FOR STATUS STRIN
       LXI  H,WRUSTS  ;TRANSMIT WRU STATUS STRING 
       LXI  D,WRUBCC  ;RETURN TO XMIT BCC STRING
       JMP  SDDXMT    ;SET VECTORS & EXIT 
 
;************************************************ 
; 
;  CKDATA - CHECK TRANSMIT QUE FOR OUTPUT DATA
;             IF NO DATA PREPARE TO SEND EOT
; 
;************************************************ 
CKEOTO EQU  $ 
       LDA  CONFG2
       ANI  EOTO      ;SEND EOT FLAG ON?? 
       JNZ  WRUACK    ;DONE SENDING DATA
;                     GO SEE IF WE SHOULD SEND EOT
       STC            ;SET CARRY FLAG = NO EOTO 
CKDATA EQU  $ 
       LDA  ASBCNT    ;GET OUTPUT BLOCK COUNT 
       DCR  A         ;ANY BLKS TO XMIT ? 
       JP   PADATA    ;YES GO SET RETURN & WAIT 
       JC   SDEOT     ;NO DATA+NO EOTO GO SEND EOT
WRUACK EQU  $ 
       LDA  IODC+ST2  ;GET STATUS 2 
       ANI  ST2CAZ    ;CA=ZERO DOWNLINE?? 
       JNZ  SDEOT     ;YES GO SEND EOT
       JMP  RPADIN    ;WAIT FOR PAD THEN GO TO CTL
 
;************************************************ 
; 
;  SDDATA - SEND DATA PREPARE DATA BLOCK FOR
;             XMISSION AND SENT 1ST CHAR (STX)
; 
;************************************************ 
SDDATA EQU  $ 
       LHLD ASBCC0
       SHLD ASBCC     ;CVLEAR ASBCC 
       CALL GETX      ;GEYT CHAR
       MOV  B,A       ;B=CHAR 
       CALL CKDLE     ;DLE CHAR?? 
       LHLD ENTAID    ;GET ENTER AID
       JZ   SDD010    ;YES
       INX  D         ;D+E = STX
       LDAX D 
       CMP  B         ;CHAR = STX?? 
       JNZ  SDD084    ;NO MUST BE AID 
SDD010 EQU  $ 
       LDA  ASFLAG    ;GET ASFLAG 
       ANI  HDRSW     ;HDR SW ON ?? 
       JZ   SDD080    ;NO GO SET NO HDR 
SDD020 EQU  $ 
       SHLD HDR+3     ;PUT AID IN HDR 
       CALL HDRBCC    ;GO DO HDR BCC
       LXI  D,HDR     ;D+E=(HDR-STRING) 
SDD040 EQU  $ 
       CALL CKTDLC    ;TPAR OR DLC ON ??
       JZ   SDD050    ;NO 
       DCX  D         ;PUSH HDR BACK TO DLE 
SDD050 EQU  $ 
       XCHG           ;H+L=STRING ADDR
       LXI  D,STSYNC  ;D+E=RETURN 
SDDXMT:SHLD ASWK1     ;ADDR OF TRANSMIT STRING
       XCHG 
SDD070:SHLD ASVCT2    ;SET VECTOR2 TO SEND BUFF 
       LXI  H,XIT030
       SHLD ASVCT1    ;SET VECTOR 1 TO XMIT 
       JMP  XIT035    ;GO XMIT STRING 
SDD080 EQU  $ 
       LXI  D,DLESTX+1  ;D+E=HDR ADDR 
       JMP  SDD040    ;GO CK DLC
SDD084 EQU  $ 
       CALL PAREBC    ;GO ADD PARITY + XLATE
       MOV  L,A       ;L=CHAR 
       MOV  A,B       ;GET ORIG CHAR
       ANA  A         ;SHORT AID ?? 
       JP   SDD020    ;NO GO SET HDR
       SUB  A 
       MOV  H,A       ;SET H TO ZERO
       JMP  SDD020    ;GO SET HDR 
 
;************************************************ 
; 
;  SDBUFF - SEND BUFFER  XMIT ALL CHARS IN BUFFER 
;             XLATE CHAR AND COMPUTE BCC
; 
;************************************************ 
SDBUFF EQU  $ 
       ANI  ST1XMT    ;XMIT INTERRUPT ??
       JZ   XERROR    ;NO  GO CK STATUS 
SDB002 EQU  $ 
       CALL CKTDLC    ;TPAR OR DLC ON ??
       LDA  DLE       ;A = DLE CHAR 
       JNZ  SDB055    ;GO SEND DLE IF TPAR+DLC
SDB010 EQU  $ 
       CALL GETX      ;GET CHAR FROM BUFFER 
       MOV  B,A       ;B=CHAR 
       JZ   SDBCC     ;BUFFER MT GO SEND BCC
       MOV  A,C       ;A=CONFIG 
SDB020 EQU  $ 
       ANI  HCODE+TPAR+PMASK  ;EBCDIC/TPAR/PARITY 
       JNZ  SDB060    ;NOT VANILA ASCII GO PROCESS
SDB040 EQU  $         ;DO BCC 
       CALL BCC 
SDB050 EQU  $ 
       MOV  A,B       ;A=CHAR 
SDB055 EQU  $ 
       STA  IODC+TMIT  ;OUTPUT CHAR 
       JMP  EXIT      ;GO EXIT
SDB060 EQU  $ 
       ANI  TPAR      ;XPARENT ?? 
       JZ   SDB066    ;NO GO CK HEX 
       CALL CKDLE     ;CHAR = DLE ??
       JMP  SDB040    ;GO DO BCC
SDB066 EQU  $         ;CK EBCDIC
       MOV  A,C       ;A=CONFIG 
       ANI  HCODE     ;EBCDIC CODE ?
       JZ   SDB070    ;NO  MUST BE FORCED PARITY
       LHLD HEXOUT    ;YES, H,L = ADDR OF TABLE 
       MOV  A,B       ;A = CHAR TO TRANSLATE
       ADD  L         ;OFFSET INTO TABLE
       MOV  L,A       ;(ASSUME 128 ALIGNMENT) 
       MOV  B,M       ;B=XLATED CHAR
       JMP  SDB040    ;GO BCC 
SDB070 EQU  $         ;ADD PARITY TO  OUTPUT
       CALL PARIT     ;GO ADD PARITY
       MOV  B,A       ;B = CHAR + PARITY
       JMP  SDB040    ;GO BCC 
WRUBCC:LDA  ETX       ;WRU ALWAYS USES ETX
       STA  XEND+1    ;STUFF IT INTO BCC STRING 
       MOV  B,A       ;SET UP FOR CALL TO BCC 
SDBCC  EQU  $ 
       CALL BCC       ;DO BCC ON TERMINATOR 
       STA  IODC+RTIME  ;RESET TIMER
       LXI  H,XEND+1  ;H+L= TERMINATOR STRING 
       MOV  A,C       ;A=CONFIG 
       ANI  TPAR      ;XPARENT ?? 
       JZ   SDBC10    ;NO 
       DCX  H         ;YES  BUMP BACK TO DLE
SDBC10 EQU  $ 
       SHLD ASWK1     ;ASWK1 DATA STRING
       LXI  H,STENQ   ;SET RETURN TO SENT ENQ 
       MOV  A,C       ;A=CONFIG 
       ANI  CRC16     ;CRC16??
       JNZ  SDD070    ;YES GO SEND STRING 
       LDA  ASBCC     ;A=LRC CHAR 
       MOV  B,A       ;B=LRC CHAR 
       CALL PARITP    ;CK PMASK + ADD PARITY
       STA  ASBCC     ;ASBCC = LRC + PARITY 
       JMP  SDD070    ;GO SEND  STRING
 
SDEOT  EQU  $ 
       LXI  D,EOTIN1  ;SET RETURN TO EOTIN1 
SDE005 EQU  $ 
       LDA  EOT       ;GET EOT CHAR 
SDE010 EQU  $ 
       LXI  H,TLR+1   ;H&L=A(OUTPUT STRING) 
SDE020 EQU  $ 
       MOV  M,A       ;PUT CHAR IN STRING 
SDE030:SHLD ASWK2     ;ASWK2 = A(OUTPUT STRING) 
       XCHG           ;H&L=D&E
       SHLD ASWK3     ;ASWK3=RETURN 
REACK  EQU  $ 
       LXI  H,SDRESP
       SHLD ASVCT2    ;VECTOR 2 = SEND RESPONSE 
       LDA  ASFLAG    ;GET FLAG 
       ANI  BCAST     ;BROADCAST ON ??
       JNZ  EOTIN     ;YES  GO BACK TO EOT SRH
       JMP  TPADIN    ;NO  GO WAIT FOR TRAILING PA
SDENQ  EQU  $ 
       LDA  ENQ       ;GET ENQ CHAR 
       LXI  D,STENQ   ;D&E=RETURN 
       JMP  SDE010    ;GO BUILD TLR 
SDABRT EQU  $         ;ABORT LAST BLOCK & SEND NAK
       CALL DABORT    ;DELETE LAST RECEIVED BLOCK 
SDNAK  EQU  $ 
       LDA  NAK       ;GET NAK CHAR 
       LXI  D,STACK   ;D&E=RETURN 
       JMP  SDE010    ;GO BUILD TLR 
SELIN  EQU  $ 
       CALL DEQALL    ;GO SET UP TO RECV
SDACK  EQU  $ 
       LDA  FQO       ;GET FREE QUE OUT PTR 
       ANA  A         ;IS FREE-Q MT ? 
       JZ   SDWACK    ;GO SEND WACK 
SDA010 EQU  $ 
       LXI  H,ACK0    ;H+L=A(ACK0)
       LDA  ASACK     ;GET ACK FLAG 
       ANA  A         ;SET CONDITION CODE 
       JZ   SDA020
       INX  H         ;BUMP POINTER TO ACK1 
SDA020 EQU  $ 
       MOV  A,M       ;A=RESP CHAR
       LXI  D,STACK   ;D&E=RETURN ROUTINE 
       LXI  H,TLR+1   ;H&L=A(TLR) 
       MOV  M,A       ;PUT CHAR IN TLR1 
       DCX  H         ;H&L=A(TLR) 
       JMP  SDE030    ;GO BUILD TLR 
SDWACK EQU  $ 
       LXI  H,CONFG2  ;GET CONFG2 
       MOV  A,M       ;A=CONFG2 
       ANI  EOTO      ;ETX IN ??
       JZ   SDW010    ;NO GO WACK 
       XRA  M         ;YES TURN OFF ETX IN
       MOV  M,A       ;RESTORE CONFG2 
       JMP  SDA010    ;GO SEND ACK
SDW010 EQU  $ 
       LXI  H,WACK    ;M=WACK 
       JMP  SDA020    ;GO STORE IN TLR
SDRESP EQU  $ 
       LHLD ASWK3     ;RETURN ADDR
       XCHG 
       LHLD ASWK2     ;ADDR OF STRING TO XMIT 
       JMP  SDDXMT
;************************************************ 
; 
;  XERROR - XMIT ERROR  THIS ROUTINE HANDLES
;             INTERRUPTS THAT ARE NOT XMIT  INTR'S
;             IF TIMER INTR  TIME COUNTER IS CKED 
;             IF INPUT CHAR CK FOR EOT IF SO GO T 
;             CTL MODE
; 
;************************************************ 
XERROR EQU  $ 
       MOV  A,D       ;A=STATUS 
       ANI  ST1TIM    ;TIMER INTR 
       JZ   EXIT      ;NO GO EXIT 
       CALL CKTIME    ;YES  GO CK TIMER 
       JNZ  EXIT      ;TIME NOT UP GO EXIT
SDSYNC EQU  $         ;TIME UP SEND SYNC'S
       LXI  H,STSYNC
       SHLD ASVCT2    ;ASVCT2= RETURN AFTER SYNCS 
       JMP  XIT010    ;GO SEND SYNCS
 
;************************************************ 
; 
;  TPADIN - WAIT HERE FOR TRAILING PAD CHARACTER
;             OR 1 TIMER UNIT  (40MS) 
; 
;************************************************ 
NAKIN  EQU  $ 
       LDA  ASFLAG    ;HERE WHEN RESPONSE = NAK 
       ANI  WRU       ;NAK TO WRU SEQUENCE? 
       JNZ  WRUNAK    ;YES, RETURN TO WRU CODE
       CALL TQDQ      ;NO, PUT BLOCK BACK IN DQ 
;                     AND FALL INTO PADATA
PADATA EQU  $ 
       LXI  H,SDDATA  ;SET RETURN TO SDDATA 
PADIN  EQU  $ 
       SHLD ASVCT2    ;ASVCT2=RETURN
TPADIN EQU  $         ;WAIT FOR TRAILING PAD THEN 
;                       GO TRANSMIT DATA
       CALL ETV1P     ;SET TIMER + VECTOR1=XMIT 
;************************************************ 
; 
;  XMIT - TRANSMIT ROUTINE  THIS ROUTINE TURNS (C 
;             REQUEST TO SEND ON AND THEN WAITS 
;             FOR (CB) CLEAR TO SEND
; 
;************************************************ 
XMIT   EQU  $         ;INTERRUPT WAS CAUSE BY PAD 
;                       CHAR OR TIMER 
       CALL RESDC     ;GO RESET DC COMMANDS 
       CALL CAON      ;GO TURN CA ON !
XIT010 EQU  $ 
       LXI  H,XIT020  ;SET RETURN TO XIT020 
       SHLD ASVCT1    ;SET VECTOR 1 
       JMP  EXIT      ;GO WAIT FOR CLEAR TO SEND
XIT020 EQU  $            ;CK FOR CLEAR TO SEND
       ANI  ST1XMT    ;XMIT BUFF MT?? 
       JNZ  XIT025    ;GO SET UP LDR
XIT022 EQU  $ 
       LDA  EOT 
       CMP  B         ;CHAR = EOT 
       JZ   EOT020    ;GO SET CTL MODE
REV1G: JMP  REV1M     ;ADD RESET RECEIVER CODE
XIT025 EQU  $ 
       LXI  H,XIT030
       SHLD ASVCT1       ;SET VECTOR 1 TO XIT030
       LXI  H,LDR     ;GET LEADER ADDR
       MOV  A,M       ;GET 1ST CHAR 
       CPI  STOPER    ;STOP CHAR
       JZ   ASJMP2    ;YES GO THRU VECTOR 2 
       MOV  A,C       ;A=C/NFIG 
       ANI  TPAR      ;IF XPARENCY ADD TPAR 
       ADD  L         ;FLAG TO LDR ADDR 
       MOV  L,A 
       MOV  A,C       ;A=CONFIG 
       ANI  DLC       ;DLC ON ??
       JZ   XIT028    ;NO 
       DCX  H         ;YES  ADD DLE TO STRING 
       MOV  A,C 
       ANI  377Q-DLC  ;TURN OFF DLC 
       STA  CONFIG    ;SAVE CONFIG
XIT028 EQU  $ 
       SHLD ASWK1     ;WK1=LDR ADDR 
       MVI  A,ONESEC  ;NO 
       STA  ASTCNT    ;SET TIMER CNT TO 1 SECOND
       STA  IODC+STIME ;SET TIMER 
       MOV  A,M       ;PUT OUTPUT IN RA 
       JMP  XIT040
XIT030 EQU  $         ;CK FOR XMIT INTERRUPT
       ANI  ST1XMT    ;XMIT INTERRUPT ??? 
       JZ   XERROR    ;NO GO CK ERROR 
XIT035 EQU  $ 
       LDA  BCSTOP    ;GET BCC STOP ADDR
       MOV  B,A       ;SAVE IN B
       LHLD ASWK1     ;H&L=OUTPUT CHAR ADDR 
       MOV  A,M       ;GET NEXT CHAR
       CPI  STOPER    ;LAST CHAR ?
       JNZ  XIT040    ;NO GO XMIT 
       MOV  A,B       ;A=BCC STAP ADDR
       CMP  L         ;PAST BCC STRING
       JC   ASJMP2    ;YES GO END STRING
       SUB  A         ;A=0
XIT040 EQU  $         ;NO   OUTPUT CHARACTER
       STA  IODC+TMIT  ;TRANSMIT CHARACTER
       INX  H         ;BUMP ADDR
       SHLD ASWK1     ;SAVE NEXT ADDR 
       MOV  C,A       ;C=XMIT CHAR
       LDA  TPADIO    ;GET TPAD 
       CMP  C         ;CHAR=TPAD? 
       JNZ  EXIT      ;NO GO EXIT 
       DCX  H         ;BUMP BACK TO TPAD ADDR 
       MOV  A,B       ;A=BCC END ADDR 
       CMP  L         ;PAST BCC STRING
       JNC  EXIT      ;NO GO EXIT 
       STA  IODC+XCOMP  ;SET XMIT CONPLETE
       JMP  EXIT
 
;************************************************ 
; 
;  STSYN - SENT SYNC CHARS    RETURN FROM SENDING 
;             SYNC CHARS AND RESET TIMER TO ONE S 
; 
;************************************************ 
STSYNC EQU  $ 
       LXI  H,SDBUFF
       SHLD ASVCT1    ;SET VECTOR TO SEND BUFFER
       JMP  SDB002    ;GO CONTINUE SENDING BUFFER 
;************************************************ 
; 
;  STACK - SENT ACK   RETURN FROM SENDING ACK  AN 
;             SET VECTORS TO RECEIVE DATA BLOCK 
; 
;************************************************ 
STACK  EQU  $         ;SENT ACKNOWLEDGEMENT 
       LXI  D,HDRIN   ;GO WAIT FOR RESPONSE 
       JMP  RECVIN
;*************************************************
; 
;  STENQ - SENT ENQ   SET VECTORS TO RECEIVE  A 
;             RESPONSE MSG
; 
;*************************************************
STENQ  EQU  $         ;SENT ENQ WAIT FOR ACK
       LXI  D,DLEIN 
;*************************************************
; 
;  RECVIN - RECEIVE INPUT  THIS ROUTINE TERMINATE 
;             XMISSION AND PREPARES TERMINAL TO 
;             RECEIVE DATA OR A RESPONSE
; 
;*************************************************
RECVIN EQU  $          ;PREPARE TO RECEIVE
       CALL CAOFF     ;GO TURN CA OFF !!
       CALL RESDC     ;GO RESET DC COMMANDS 
       LXI  H,RESPIN  ;H+L=VECTOR 1 
       MVI  A,TRISEC  ;SET 3 SECOND CNT 
       JMP  ETV1V2    ;GO EXIT SET TIMER,ASVCT1&2 
;*************************************************
; 
;  RESP - RESPONSE  WAIT HERE FOR RESPONSE INTR 
;             THEN GO TO HDRIN OR RESPIN
; 
;*************************************************
RESPIN EQU  $ 
       ANI  ST1IBF    ;INPUT BUFF FULL??
       JNZ  EOT012    ;YES GO CK SYNC 
       CALL CKTIME    ;NO GO CK TIME
REV1H: JNZ  REV1N     ;RESET RECV AND EXIT
       CALL TQDQ      ;DEQ BUFFERS
       JMP  EOTIN1    ;GO BACK TO CTL MODE
DLEIN  EQU  $ 
       LXI  H,NAK     ;GET NAK-RVI-ACK0-ACK1 STRG 
       MOV  A,B       ;A=CHAR 
       CMP  M         ;CHAR = NAK?? 
       JZ   NAKIN     ;YES
       INX  H 
       CMP  M         ;CHAR = RVI ??
       JZ   RVIIN     ;YES GO TO RVI
       INX  H 
       CMP  M         ;CHAR = ACK0??
       JZ   ACKIN     ;YES GO PROCESS 
       INX  H 
       CMP  M         ;CHAR=ACK1 ?? 
       JZ   ACKIN     ;YES GO CK ACK
       INX  H 
       CMP  M         ;CHAR = WACK
REV1I: JZ   REV1K     ;INPUT CHAR = WACK
       JMP  EXIT      ;GO IGNORE CHAR 
ACKIN  EQU  $ 
       ANI  001Q      ;TURN OFF HI BITS 
       MOV  B,A       ;SAVE 
       LXI  H,ASACK   ;GET ASACK
       MOV  A,M 
       ANA  A         ;SET CC 
       MOV  A,B       ;A=ACK
       JM   AKI010    ;ACK = DONT CARE  GO FLIP 
       CMP  M         ;ACK CHAR=ACK FLAG??
       JNZ  SDENQ     ;NO GO SEND ENQ 
AKI010 EQU  $ 
       XRI  001Q      ;FLIP ACK FLAGP 
       MOV  M,A       ;SAVE IN ASACK
       LDA  ASFLAG    ;GET ASFLAG 
       ANI  377Q-HDRSW  ;TURN OFF HDR SW
       STA  ASFLAG    ;SAVE FLAG
       ANI  WRU       ;WRU ???
       JNZ  WRUACK    ;YES GO ACK 
       CALL TQFQ      ;GO RELEASE BUFFERS 
       JMP  CKEOTO    ;GO CK DATA 
RVIIN  EQU  $ 
       CALL TQFQ      ;RELEASE BUFFERS
       JMP  SDEOT     ;GO SEND EOT
 
BCSTIN EQU  $         ;CLEAR BUFFERS FOR INPUT
       CALL DEQALL    ;GO REFRESH BUFFERS 
;*************************************************
; 
;  HDRIN - HEADER IN  CHECK FOR STX CHAR TO START 
;             TEXT INPUT
; 
;*************************************************
HDRIN  EQU  $ 
       CALL CKTDLC    ;CK DLC FLAG + TURN OFF 
       LDA  STX 
       CMP  B         ;CHAR =STX ?? 
       JNZ  HIN030    ;NO  GO CK OTHER CTL CHARS
       LHLD ASBCC0    ;YES
       SHLD ASBCC     ;ZERO BCC 
       MOV  A,C       ;GET CONFIG 
       ANI  M3270     ;3270 MODE
       JZ   HIN020    ;NO GO EXIT 
       MVI  A,CNT327  ;SET 3270 HDR CNT 
       LXI  D,HIN020  ;SET RETURN 
       JMP  ABT210    ;GO SET TO CHUCK CHARS
HIN030 EQU  $ 
       LDA  ENQ 
       CMP  B         ;CHAR=ENQ?
       JNZ  EXIT      ;NO IGNORE CHAR 
       LXI  H,TLR+1   ;GET TLR SENT 
       LDA  WACK
       CMP  M         ;CHAR = WACK ?? 
       JZ   SDACK     ;YES  GO CK BUFFER LEFT!! 
       JMP  REACK     ;YES RESEND LAST RESPONSE 
RERROR EQU  $ 
       MOV  A,D       ;A=STATUS 
       ANI  ST1TIM    ;TIMER ERROR
       JNZ  ABORT     ;YES
       MOV  A,D       ;A=STATUS 
       ANI  ST1PER    ;PARITY ERROR 
       JNZ  ABORTN    ;YES  ABORT&SEND NAK
       JMP  ABORTE    ;GO ABORT WITH EOT
HIN020 EQU  $ 
       CALL ETV1P     ;SET TIMER + VECTOR1=DATAIN 
DATAIN EQU  $ 
       CPI  ST1IBF    ;INPUT BUFFER FULL ONLY ??
       JNZ  RERROR    ;NO GO TO RECV ERROR
       CALL PARITY    ;GO CK FORCED PARITY
       CMP  B         ;A=B??
       JNZ  ABORTN    ;NO MUST BE PARITY ERROR
       CALL CKTDLC    ;TPAR OR DLC ON ??
       PUSH PSW       ;SAVE CONDITION CODES 
       JC   DIN010    ;TPAR ON  GO CK FOR DLE 
       LDA  SYNC      ;NO TPAR OR TPAR DLC
       CMP  B         ;CHAR = SYNC??
       JNZ  DIN015    ;NO GO BCCC 
DIN005 EQU  $ 
       POP  PSW       ;CLEAR STACK
       JMP  RTIMER    ;GO WAIT NXT CHAR 
DIN010 EQU  $ 
       CALL CKDLE     ;DLE IN?? 
       JZ   DIN005    ;YES  GO EXIT 
DIN015 EQU  $ 
       CALL BCC       ;DO BCC 
       POP  PSW       ;RESTORE CONDITION CODE 
       JC   DIN050    ;TPAR ON NO DLC GO PUT BUFF 
DIN040 EQU  $ 
       MOV  A,B       ;A=CHAR 
       CALL CKETB     ;CK FOR TERMINATORS 
       JZ   DIN046    ;NO GO PUT CHAR IN BUFF 
       RRC            ;ROTATE 
       JNC  ETXIN     ;NO CARRY CHAR MUST BE ETX
       RRC            ;ROTATE AGAIN 
       JNC  ABORTN    ;NO CARRY = ENQ 
       JMP  BCCIN     ;MUST BE ETB
DIN046 EQU  $ 
       MOV  A,C       ;A=CONFIG 
       ANI  TPAR+HCODE  ;TPAR OR EBCDIC ??
       JZ   DIN050    ;NO  GO PUT IN BUFF 
       ANI  TPAR      ;TPAR ON??
       JNZ  DIN050    ;YES  SKIP XLATE
DIN048 EQU  $ 
       LXI  H,HEXIN 
       MOV  H,M 
       MOV  L,B       ;H+L=XLATE TABLE
       MOV  B,M       ;B = XLATED CHAR
DIN050 EQU  $ 
       MOV  A,B       ;GET CHARACTER
       CALL PUTR      ;PUT CHAR IN BUFFER 
       JNZ  RTIMER
       JMP  ABORTE    ;GO ABORT WITH EOT
ETXIN  EQU  $ 
       LDA  CONFG2    ;GET CONFG2 
       ORI  EOTO      ;SET ETXIN FLAF 
       STA  CONFG2
BCCIN  EQU  $ 
       MOV  A,C       ;A=CONFIG 
       ANI  CRC16+HCODE  ;8 BIT BCC 
       JNZ  BCI010    ;YES SKIP PARITY CK 
       LXI  H,ASBCC   ;H+L=(ASBCC)
       MOV  B,M       ;B=ASBCC LRC
       CALL PARITP    ;CK PMASK + ADD PARITY
       MOV  M,A       ;PUT CHAR +PARITY IN ASBCC
BCI010 EQU  $ 
       CALL ETV1P     ;SET TIMER & VECTOR1=BCC1 
; 
BCC1   EQU  $ 
       LXI  H,ASBCC   ;LH+L=(ASBCC) 
       MOV  A,C       ;A=CONFIG 
       ANI  CRC16     ;CRC16??? 
       JZ   BCC210    ;NO  GO CK CHAR 
       MOV  A,M       ;YES
       CMP  B         ;CHAR OK ?? 
       JZ   BCC150    ;YES, GO SET RETURN 
       INX  H         ;PT TO ASBCC+1 (2ND BCC CHAR
       INR  M         ;PERVERT 2NC CRC CHAR 
;                     (SEND NAK AFTER BCC RECEIVED
BCC150 EQU  $ 
       CALL ETV1P     ;SET TIMER & VECTOR1=BCC2 
BCC2   EQU  $ 
       LXI  H,ASBCC+1 ;H+L=(ASBCC+1)
BCC210 EQU  $ 
       MOV  A,M       ;A=BCC CHAR 
       CMP  B         ;BCC OK?? 
       JNZ  SDABRT    ;NO GO ABORT WITH NAK 
BCCOK  EQU  $ 
       CALL PUTE      ;END OF INPUT BLOCK 
;                     (BLOCK-INPUT MODE ONLY) 
       LDA  ASACK     ;GET ACK FLAG 
       XRI  001Q      ;FLIP ACK FLAG
       STA  ASACK     ;RESTORE ACK FLAG 
       JMP  SDACK     ;GO SEND ACK
 
ABORTE EQU  $         ;ABORT WITH EOT 
       MVI  A,EOTO    ;SET EOTO FLAG
       JMP  ABORIT
ABORTN EQU  $         ;ABORT WITH NAK 
       MVI  A,NAKERR  ;SET NAK FLAG 
ABORIT EQU  $ 
       LXI  H,CONFG2  ;GET CONFG2 FLAGS 
       ORA  M         ;TURN ON ERROR FLAG 
       MOV  M,A       ;SET CONFG2 
ABORT  EQU  $ 
       CALL DABORT    ;GO DEQUE BUFFERS 
ABORT1 EQU  $ 
       LDA  ASACNT    ;GET ABORT TIMER CNT
       CALL ETV1P     ;SET TIMER & VECTOR1=ABORTI 
;*************************************************
; 
;  ABORTI - ABORT INPUT  IGNORE CHARACTERS UNTIL
;             TIMER GOES OFF WITHOUT CHAR  THEN 
;             SEND NAK OR EOT 
; 
;*************************************************
ABORTI EQU  $ 
       ANI  ST1IBF    ;INPUT BUFF FULL??
       JNZ  ABI020    ;YES
ABI005 EQU  $ 
       CALL CKTIME    ;GO CK TIMER
       JNZ  EXIT      ;TIME NOT UP GO WAIT
       LDA  ASACNT    ;GET ABORT TIMER
       DCR  A         ;CONTINUOUS CARRIER 
       JNZ  EOTIN1    ;YES GO BACK TO CTL MODE
ABI010 EQU  $ 
       LDA  CONFG2    ;GET CONFG2 
       RAR
       RAR            ;ROTATR TO NAKERR 
       JC   SDNAK     ;IF NA NAKERR SEND NAK
       RAL            ;ROTATTE BACK TO EOTO FLAG
       JC   SDEOT     ;SEND EOT IF ERROR
       JMP  EOTIN1    ;GO TO CTL MODE 
ABI020 EQU  $ 
       CALL CKTDLC    ;TPAR OR DLC ON ??
       JNC  ABI030    ;CK END  NO TPAR OR DLC ON
       CALL CKDLE     ;DLE IN??  SET FLAGS
       JMP  ABI035    ;GO CK OVERFLOW 
ABI030 EQU  $ 
       MOV  A,B       ;A=CHAR 
       CALL CKETB     ;GO CK FOR TERMINATORS
       JNZ  ABORT2    ;FOUND TERM WAIT FOR BCC
ABI035 EQU  $ 
       LDA  ASACNT    ;GET ABORT TIMER CNT
       MOV  B,A       ;B=CNT
       DCR  B         ;CNT=1
       JZ   RTIME1    ;YES NOT CONT CARRIER 
       JMP  EXIT      ;CONT CARRIER GO EXIT 
ABORT2 EQU  $ 
       MVI  A,002Q    ;SET COUNT = 2
       LXI  D,ABI010  ;SET RETURN AFTER COUNT = 0 
ABT210 EQU  $ 
       LXI  H,ABORTC  ;SET VECTOR 1 = ABORTC
       JMP  ETV1V2    ;SET VECTOR 1 & 2 
ABORTC EQU  $ 
       ANI  ST1IBF    ;INPUT BUFFER FULL ?? 
       JZ   ASJMP2    ;NO RETURN TO CALLER
       CALL BCC       ;GO DO BCC
       LXI  H,ASTCNT  ;GET CHAR COUNT 
       DCR  M         ;DECR CNT 
       JZ   ASJMP2    ;COUNT = ZERO RETURN TO CALL
       JMP  RTIMER    ;GO RESET TIMER 
 
;*************************************************
; 
;  RESET - RESET ALL DATA COMM FLAG AND PUT TERM
;             IN CONTROL MODE 
; 
;*************************************************
RESEXT EQU  $ 
       LXI  H,CKSTX   ;RETURN = CK RESTX
       SHLD ASVCT2    ;SET VECTOR 2 TO EXIT 
RESET  EQU  $         ;RESET DATA COMM CARD 
       CALL RESDC     ;RESET DC COMMANDS
       MVI  A,CT2CAZ+CT2SAZ 
       CALL CTL2ON    ;SET ZERO FLAGS 
       SUB  A 
       STA  ASFLAG    ;CLEAR ASFLAG 
       LXI  H,EOTSRH  ;SET VECTOR 1 TO EOT SEARCH 
       SHLD ASVCT1
       LDA  CONFG2
       ANI  DVRON     ;CLEAR XCEPT DVR
       STA  CONFG2
       RZ             ;NO RETURN
       POP  H         ;YES POP STACK
       JMP  DVRCK     ;GO CHECK DRIVER
; 
RESCT2 EQU  $ 
       STA  IODC+OCTL2  ;OUTPUT CTL2
RESDC  EQU  $         ;RESET ALL DATA COMMANDS
REV1J: LDA  IODC+CHARIN      ;CLEAR INPUT BUFFER
       STA  IODC+RRECV+DISXMT+RTIME 
;                            RESET RECEIVER 
;                            DISABLE XMIT COMPLETE
;                            TURN OFF TIMER 
; 
       LXI  H,CONFIG  ;ADDR OF DLC + TPAR FLAGS 
       MVI  A,377Q-DLC-TPAR  ;TURNING LINE AROUND 
       ANA  M                ;CAN'T BE TRANSPARENT
       MOV  M,A 
       RET
; 
REV1K: CALL TQFQ      ;WACK=POS ACKNOWLEDGEMENT 
       JMP  SDENQ 
CKETB  EQU  $ 
       LXI  H,ETB     ;PT TO ETB
       MVI  D,004Q    ;SET CNT
CKE010 EQU  $ 
       STA  ENQ+1     ;SAVE ORIG CHAR 
CKE020 EQU  $ 
       DCR  D         ;DECR CNT 
       CMP  M         ;A=M
       INX  H         ;BUMP TABLE POINTER 
       JNZ  CKE020    ;NO CK AGAIN
       MOV  B,A       ;PUT CHAR IN B
       MOV  A,D       ;A=CNT
       ANA  A         ;SET CC ON CNT
       RET            ;RETURN TO CALLER 
 
;************************************************ 
; 
;   CBDON     INHIBIT DOWNLINE CB 
; 
;   CBDOFF    DROP CB INHIBIT 
; 
;************************************************ 
;   ENTRY POINT 
; 
CBDON  EQU  $ 
       MVI  A,CT2CBD  ;SET CB INHIBIT 
       JMP  CTL2ON    ;GO TURN ON 
; 
;   ENTRY POINT 
; 
CBDOFF EQU  $ 
       MVI  A,CT2CBD  ;SET CB INHIBIT 
       JMP  CTL2OF    ;GO TURN OFF
CKTDLC EQU  $         ;CK TPAR AND DLC  C=CONFIG
;      EXIT:  Z+NVC=NO TPAR  Z+C=TPAR+NO PREV DLE 
;             NZ+NC=TPAR+PREV DLE IN
       MOV  A,C       ;A=CONFIG 
       ANI  TPAR+DLC  ;TPAR AND DLC ON??
       RZ             ;NO GO RETURN 
       ANI  DLC       ;DLC ON?? 
       STC            ;SET CARRY FLAG 
       RZ             ;NO  CC=Z+C TPAR ON DLC OFF 
       CMA            ;FLIP BITS
       ANA  C         ;TURN OFF DLC 
CKT010 EQU  $ 
       LXI  H,CONFIG  ;H+L=CONFIG 
       MOV  M,A       ;RESTORE CONFIG 
       MOV  C,A       ;C=CONFIG 
       RET            ;RETURN TO CALLER 
CKDLE  EQU  $         ;CK FOR DLE   C=CONFIG
;      EXIT:  NZ=NO DLE  Z=DLE +DLC+TPAR SET ON 
       LXI  D,DLESTX  ;D+E=A(DLESTX)
       LDAX D 
       CMP  B         ;CHAR =DLE??
       RNZ            ;NO RETURN TO CALLER CC=NZ
       MVI  A,DLC+TPAR
       ORA  C         ;TURN ON TPAR+DLC 
       CMP  A         ;SET CC TO ZERO 
       JMP  CKT010    ;GO RETURN
 
;  DCTEST - DATA COMM SELF-TEST 
;             THIS ROUTINE TRANSMITS BIT PATTERNS 
;             FROM 000B TO 177B AND EXPECTS TO
;             RECEIVE THESE PATTERNS AS INPUT 
;             WITHIN  800MS OF EACH XMISSION
; 
;*************************************************
DCTEST EQU  $ 
       DI             ;DISABLE INTERRUPTS 
REV1L: CALL WRUST3    ;SET UP STATUS BYTES
       LXI  H,CTL2
       MOV  C,M       ;C=CONFIG 
       LXI  D,E0EOP   ;SET ERR FLG TO ZERO + EOP
       LDA  KBJMP3    ;SELF-TEST MASK SET?
       ANI  KB3STM    ;SELFTEST MASK SET??
       JNZ  SLFERR    ;YES GO POST ERROR
SLFTST EQU  $ 
       CALL RESDC     ;RESET DC COMMANDS
REV1P: DB   0,0,0     ;DON'T INHIBIT CB & CA* 
       CALL CAON      ;GO PUT CA ON 
       CALL SLFXMT    ;GO WAIT FOR CB 
       MVI  E,062Q    ;E=ACSII 2
LOOPIT EQU  $ 
       LHLD SYNC      ;H+L= 0 + SYNC CHAR 
       MOV  A,L       ;A=SYNC 
       STA  IODC+TMIT  ;GO XMIT SYNC
       CALL SLFBUF    ;GO WAIT FOR INPUT BUFF FULL
       MOV  A,H       ;A=STARTING CHAR
LOP010 EQU  $ 
       STA  IODC+TMIT  ;OUTPUT CHAR 
LOP012 EQU  $ 
       CALL SLFBUF    ;GO WAIT FOR INPUT CHAR 
       LDA  IODC+CHARIN  ;INPUT CHAR
       CMP  H         ;INPUT CHAR = OUTPUT CHAR?? 
       JNZ  LOP016    ;NO GO CK SYNC
       INR  H         ;YES BUMP H 
       JM   CKCE      ;END OF LOP GO CK CE
       CALL SLFXMT    ;GO WAIT FOR OUTPUT BUFF EMP
       MOV  A,H       ;A=CHAR 
       JMP  LOP010    ;GO XMIT CHAR 
LOP016 EQU  $ 
       CMP  L         ;CHAR = SYNC ?? 
       JZ   LOP012    ;YES GO WAIT FOR NXT CHAR 
       JMP  SLFERR    ;SET ERROR MSG
CKCE   EQU  $         ;CE=RS232 HOOD ON 
       LDA  IODC+ST2  ;GET STATUS 2 
       ANI  ST2CEZ    ;CEZERO ON??
       JNZ  SLFTOK    ;YES  LOOP HOOD NOT ON!!
       MVI  E,E4      ;SET ERROR CODE TO 4
       MVI  B,ST2Z    ;B=STATUS 2 ZERO FLAGS
       MVI  A,CT2Z    ;CA, SA, CD, CH  NOT ZERO 
       CALL CTL2OF
       LDA  IODC+ST2  ;GET STATUS 2 
       ANA  B         ;CK 
       JNZ  SLFERR    ;IF ANY ON MUST BE ERROR
       MVI  A,CT2Z    ;CA, SA, CD, CH ZERO
       CALL CTL2ON
       LDA  IODC+ST2  ;GET STATUS 2 
       ANA  B         ;MASK ALL BUT Z FLAGS 
       CMP  B         ;ALL ZERO FLAGS ON
       JNZ  SLB030    ;NO GO SET ERROR
SLFTOK EQU  $         ;SELF TEST OK 
       SUB  A         ;CC = ZERO + NC 
       LXI  H,OKMSG   ;GET OKK MSG
       JMP  SLFMSG    ;GO GET REST OF MSG 
;*******
;      ERROR FLAGS
;           0 = SELFTEST INHIBITED
;           1 = NO CB 
;           2 = CHAR RECV NOT = CHAR SENT 
;           3 = CHARACTER DID NOTY LOOP BACK
;           4 = CE-CF-CB-CC-SB-  DID NOT COME ON
;           5 = CE-CF-CB-CC-SB-  DID NOT TURN OFF 
;**** 
SLFXMT EQU  $         ;CK STATUS FOR XMIT MT??
       MVI  B,ST1XMT+ST1TIM 
       JMP  SLB010    ;GO WAIT FOR SWTATUS
SLFBUF EQU  $         ;CHECK STATUS FOR BUFFER FUL
       MVI  B,ST1IBF+ST1TIM+ST1PER  ;SET MASK 
SLB010 EQU  $         ;RETURN: CC=Z  STATUS  FAILE
       MVI  A,TRISEC  ;SET TIMER TO 3 SECONDS 
       STA  ASTCNT
       STA  IODC+RTIME   ;RESET TIMER 
       STA  IODC+STIME  ;SET TIMER
SLB020 EQU  $ 
       LDA  IODC+ST1  ;GET STATUS 
       ANA  B         ;PUT MASK AGAINST STATUS
       JZ   SLB020    ;NO STATUS CK AGAIN 
       CPI  ST1TIM    ;ANY STAT BESIDES TIMER 
       RNZ            ;YES RETURN MUST BE STATUS
       CALL CKTIME    ;NO GO CK TIMER 
       JNZ  SLB020    ;TIMER NOT UP GO CK STATUS
       POP  H         ;POP RETURN POINTER 
SLB030 EQU  $ 
       INR  E         ;BUMP ERROR BY 1
SLFERR EQU  $         ;SELFTEST ERROR 
       STC            ;CC=CARRY 
       XCHG           ;H+L=D+E  GET ERROR MSG 
       SHLD DCMSG     ;PUT IN DCMSG AREA
       LXI  H,DCMSG   ;H+L=DCMSXG 
       SHLD MSGPT4    ;PUT IN POINTER 
       LXI  H,FMSG    ;H+L= FAIL MSF
SLFMSG EQU  $ 
       PUSH PSW       ;SAVE CC
       SHLD MSGPT3    ;PUT MSG IN MSG PTR 3 
       LXI  H,STMSG   ;GET SELF TEST VERBIAGE 
       SHLD MSGPT2    ;STORE PTR
       MOV  A,C       ;A=CTL2 
       CALL RESCT2    ;RESET CTL2 + DC COMMANDS 
       LXI  H,SLFID   ;H&L=SLFID
       POP  PSW       ;RESTORE PSW
       EI             ;ENABLE INTERRUPTS
       RET            ;RETURN TO CALLER 
STMSG: DB   ' DATA COMM SELF TEST ' 
       DB   000Q      ;CONTINUATOR
OKMSG: DB   'OK'
       DB   EOP       ;SET END
FMSG:  DB   'ERROR '
       DB   000Q      ;CONTINUATOR
E0EOP  EQU  316Q*256+060Q   ;EOP+E0 
E4     EQU  064Q      ;ASCII 4
 
DCCMNT EQU  $         ;MONITOR MODE 
       CALL DCSTOP    ;GO WAIT FOR DC TO STOP 
       LXI  H,DVR000  ;SET VECTOR TO DVR/MONITOR
; 
DCC100:POP  D         ;DELETE ADDR OF RETNCZ
       CMP  A         ;SET NC & Z CONDITION CODES 
       PUSH PSW 
       JMP  ETV1      ;SET ASVCT1 & TIMER, EXIT 
; 
;   LEAVE MONITOR/DRIVER MODE 
;   (WARNING: THIS CODE MAY BE CALLED BY
;   MAINCODE EVEN THOUGH NEVER IN MONITOR 
;   OR DRIVER!) 
; 
DCCNRM:LDA  CONFG2    ;ARE WE IN DRIVER MODE? 
       ADD  A         ;YES, DON'T DO ANYTHING 
       RC             ;(JUST WANT TO USE KEYBOARD)
       CM   INIRST    ;IF MONITOR MODE, RE-INIT 
       RET            ;GOTO RETNCZ
; 
DVR000 EQU  $ 
       CALL CNSUMR    ;GO GET DATA
       JZ   MONITR    ;BUFFS EMPTY = MONITOR MODE 
DVR010 EQU  $ 
       LXI  H,DVRMSG  ;H+L ADDR%SS OF DVR PASSWORD
DVR012 EQU  $ 
       PUSH H         ;SAVE H+L 
       CALL CNSUMR    ;GO GET DATA
       POP  H         ;RESTORE H
       JZ   MONITR    ;NO DATA GO TO MONITOR MODE 
       ANI  337Q      ;MAKE UPPER CASE
       CMP  M         ;CHAR = PASSWORD
       JNZ  DVR014    ;NO CK END OF PASSWORD
       INX  H         ;YES BUMP PTR 
       JMP  DVR012    ;GO CK NEXT CHAR
DVR014 EQU  $ 
       MOV  B,A       ;SAVE CHARACTER 
       MOV  A,M       ;A= MATCH CHAR
       ANA  A         ;END OF LIST
       JNZ  MONITR    ;WRONG STRING IN BUFFER 
;                     SO DEFAULT TO MONITOR MODE
DVR020 EQU  $ 
       MVI  A,XCHARU  ;GET UPPER CASE X CHARACTER 
       CMP  B         ;CHAR=X?? 
       JZ   DVR024    ;YES  GO DEFAULT TO LIST
       LXI  H,PLIST   ;H+L=POLL LIST
       CALL PUTLST    ;PUT CHAR IN LIST 
       LXI  H,SLIST   ;H+L=SELECT LIST
       CALL PUTLST    ;GO PUT CHAR IN LIST
DVR024 EQU  $ 
       CALL BUFINI    ;GO RESET BUFFERS 
       LXI  H,CONFG2
       MVI  M,DVRON   ;SET DVR FLAG IN CONFG2 
DVRCK  EQU  $ 
       CALL RESDC     ;RESET DATA COMM COMMANDS 
       LDA  POLRAT    ;GET DRIVER POLL RATE TIMER 
;                     NORMALLY = 20*40 MSEC 
;                     MODIFY 177216 TO 1-377
;                     TO RESET POLL RATE (*40MSEC)
       CALL ETV1P     ;SET TIMER & VECTOR1=DVC010 
DVC010 EQU  $ 
       ANI  ST1TIM    ;TIMER INTR?? 
       JZ   EOTIN     ;NO  GO RESET 
       CALL CKTIME    ;YES GO CK TIMER
       JNZ  RTIMER    ;WAIT FOR NEXT TIMER
DVC020 EQU  $ 
       LXI  D,CKLST   ;D+E=RETURN 
       JMP  SDE005    ;GO SEND EOT
CKLST  EQU  $ 
       STA  IODC+DISXMT  ;TURN OFF XMIT COMP FLAG 
       LXI  H,ASACK 
       MVI  M,ACK0F   ;SET ACK0 FLAG
       LDA  ASBCNT    ;GET BUFFER CNT 
       DCR  A         ;ANY DATA ? 
       JM   POLIT     ;NO GO POLL 
       LXI  H,SLIST   ;H+L=DATA 
       LXI  D,SLEND   ;D+E=RETURN ADDRESS 
CKL010 EQU  $ 
       SHLD ASWK2     ;ASWK2=DATA 
       XCHG           ;GET D+E
       SHLD ASWK3     ;ASWK3=RETURN ADDR
       LXI  H,SDRESP  ;SET INTERMEDIATE RETURN
       SHLD ASVCT2
       JMP  XIT025    ;GO SEND LIST 
SLEND  EQU  $         ;SEND LIST COMPLETE 
       LXI  H,ASFLAG
       MVI  M,POL+HDRSW  ;SET FLAGS 
       JMP  STENQ     ;GO TO SENT ENQ 
POLIT  EQU  $ 
       LXI  H,ASFLAG
       MVI  M,SELEC   ;SET SELEC ON 
       CALL DEQALL    ;GO SET BUFFERS TO RECV 
       LXI  H,PLIST   ;H+L=DATA 
       LXI  D,STACK   ;D+E=RETURN 
       JMP  CKL010
;***************
;                     SO DEFAULT TO MONITOR MODE
PLT010 EQU  $ 
       MOV  B,A       ;B=CHAR 
       CALL PAREBC    ;GO SET PARITY+XLATE
       POP  H         ;RESTORE H
       MOV  M,A       ;PUT CHAR IN LIST 
       INX  H         ;BUMP LIST PTR
       MOV  M,A       ;PUT CHAR IN LIST 
       INX  H         ;BUMP LIST PTR
       LDA  ENQ       ;GET ENQ
       CMP  M         ;END OF LIST
       JNZ  PUTLST    ;NO GET NEXT CHAR 
       RET
DVRMSG:DB   'DVR' 
       DB   0Q        ;STOPER 
XCHARU EQU  130Q      ;UPPER CASE X CHARACTER 
; 
;      PUTLST         PUT CHARS FROM BUFFERS INTO 
;           LISTS  H+L=LIST ADDR
; 
PUTLST EQU  $ 
       PUSH H         ;SAVE H+6 
       CALL CNSUMR    ;GO GET DATA
       JNZ  PLT010    ;GO PROCESS CHARACTER 
       POP  H         ;RESTORE H
       POP  H         ;POP STACK FOR RETURN 
 
;*************************************************
; 
;  SCANIT - SCAN ALL DATA BEING SENT OR RECEIVED
;             BY COMMUNICATION LINE AND DISPLAY I 
;             ON CRT
;           CONTROL-DISPLAY-FUNCTION KEYS SET THIS
;             MODE
; 
;*************************************************
; 
;   ENTER MONITOR MODE
; 
MONITR EQU  $         ;SET UP FOR MONITOR MODE
       SUB  A         ;TURN OFF BLKIN MODE
       STA  FLAG      ;(NO BLK END IN MONITOR)
       LXI  H,ASFLAG  ;TURN ON RCVN (MONITOR
       MVI  M,RCVN    ;ALWAYS IN RECEIVE STATE) 
       INX  H         ;H,L POINT TO CONFG2
       INX  H 
       MVI  M,MONTR   ;TURN ON MONITOR MODE FLAG
; 
       CALL DEQIT2    ;REFRESH BUFFERS (ALL TO FQ)
;                     (DON'T TURN ON RCVMDE;
;                     BECAUSE KEYBOARD WILL BE
;                     LOCKED AND WE WON'T BE ABLE 
;                     TO GET OUT OF MONITOR MODE) 
;                     (PUTDC NOW UNSUCCESSFUL)
; 
       MVI  A,CT2CMM  ;TURN ON MONITOR MODE BIT 
       CALL CTL2ON    ;(TERMINAL SEES DATA FROM 
;                     BOTH DIRECTIONS ON CHANNEL) 
; 
SCN002 EQU  $ 
       LXI  D,SCANIT  ;D+E=VECTOR 2 
       LXI  H,SCANIN  ;H+L=VECTOR 1 
       JMP  ETV1V2    ;GO SET TIMER + VECTOR 1+2
SCANIN EQU  $ 
       ANI  ST1IBF    ;INPUT BUFFER FULL
       JNZ  ASJMP2    ;YES GO THRU VECTOR 2 
       CALL CBDOFF    ;SET CB DOWNLINE INHIBIT OFF
       CALL RESDC     ;RESET DC COMMANDS
       JMP  EXIT      ;GO EXIT + WAIT 
SCANIT EQU  $ 
       LXI  H,ASBCC   ;GET CAZ FLAG 
       MOV  E,M       ;E=CAZ FLAG 
       LDA  IODC+ST2  ;GET STATUS 2 
       ANI  ST2CAZ    ;GET CAZ FLAG 
       CMP  E         ;CAZ FLAG = PREV CAZ FLAG 
       JZ   SCN020    ;YES NO CHG IN DIRECTION
       MOV  E,A       ;YES  E=NEW CAZ FLAG
       ANA  A         ;CAZ ON ??
       MVI  A,LTCHAR  ;SET LT CHAR
       JZ   SCN010    ;NO  CA IS ON DOWNLINE !! 
       MVI  A,GTCHAR  ;YES  MUST BE UPSTREAM DATA 
SCN010 EQU  $ 
       CALL PUTR      ;PUT CHAR IN BUFFER 
       STA  IODC+RRECV  ;RESET RECEIVER 
       MOV  A,E       ;A = CAZ FLAG 
SCN020 EQU  $ 
       ANA  A         ;CAZ ON ??? 
       JZ   SCN030    ;NO MUST BE DOWN STREAM !!
       LDA  EOT 
       CMP  B         ;CHAR = EOT?? 
       JNZ  SCN030    ;NO GO PUT CHAR IN BUFF 
       LDA  IODC+ST2  ;GET STATUS 2 
       ANI  ST2CCZ    ;FIRST DEVICE IN LINE ??
       CZ   CBDON     ;IF YES PUT CB INHIBIT ON 
       STA  IODC+RRECV  ;RESET RECEIVER 
SCN030 EQU  $ 
       LXI  H,ASBCC 
       MOV  M,E       ;SAVE CAZ FLAG
       MOV  A,C       ;A=CONFIG 
       ANI  HCODE     ;EBCDIC ??
       JZ   SCN040    ;NO GO PUT BUFFER 
       LXI  H,HEXIN 
       MOV  H,M 
       MOV  L,B       ;H+L=XLATE TABLE
       MOV  B,M       ;B=XLATED CHAR
SCN040 EQU  $ 
       MOV  A,B       ;A = CHAR 
       CALL PUTR      ;GO PUT CHAR IN BUFFER
       JNZ  RTIMER    ;GO WAIT FOR NXT CHAR 
       LXI  H,SCNFUL
       JMP  ETV2      ;SET VECTOR 2 = SCNFUL
SCNFUL EQU  $ 
       MVI  A,FCHAR   ;GET FULL CHAR
       CALL PUTR      ;PUT CHAR IN BUFFER 
       JZ   RTIMER    ;CHAR NOT ACCEPTED GO WAIT
       JMP  SCN002    ;GO RESET SCAN
GTCHAR EQU  076Q      ;GREATER THAN CHAR
LTCHAR EQU  074Q      ;LESS THAN CHARACTER
FCHAR  EQU  030Q      ;CANCEL CHAR
 
REV1M: LDA  SYNC      ;INPUT CHAR = SYNC? 
       CMP  B         ;(MUST IGNORE SYNC INPUT
       JZ   EXIT      ;FOR VALID RESET RECEIVER)
REV1N: STA  IODC+RRECV       ;NOT EOT NOR SYNC
       JMP  EXIT             ;SO RESET RECEIVER 
REV1O: LDA  IODC+ST2  ;IF FIRST IN CHAIN, 
       ANI  ST2CCZ    ;THEN KEEP INHIBIT UP 
       JZ   CTL350    ;UNTILL TPAD GOES BY
       JMP  RPADIN    ;ELSE, DROP INHIBIT 
;                     (KNOW SEQUENCE NOT FOR
;                     US AND NOT 1ST) 
       END
