ASMB,Q,C
**************************************************************
*                                                            *
*     D  V  M  0  0     12792A MULTIPLEXER INTERFACE DRIVER  *
*                                                            *
*    VERSION 0.49  800819 GDD                                *
*                                                            *
***************************************************************** 
* (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1980. ALL RIGHTS        * 
* RESERVED. NO PART OF THIS PROGRAM MAY BE PHOTOCOPIED,         * 
* REPRODUCED OR TRANSALATED TO ANOTHER PROGRAM LANGUAGE WITHOUT * 
* THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY.         * 
***************************************************************** 
* 
* THE FOLLOWING CONTROL REQUESTS ARE SUPPORTED: 
* 
* REQ# (OCTAL)     DESCRIPTION
* ----------------------------------------------------
*    6         DYNAMIC STATUS 
*    20        ENABLE PROGRAM SCHEDULE
*    21        DISABLE PROGRAM SCHEDULE 
*    22        SET LOGICAL TIMEOUT
*    23        BUFFER FLUSH 
*    24        BUFFER UN-FLUSH
*    26        FLUSH CARD BUFFER(S) 
*    27        SET PROGRAM ADDRESS TO SCHEDULE
*    30        SET PORT ID  
*    31        OPEN MODEM LINE
*    32        CLOSE MODEM LINE 
*    33        CONFIGURE DRIVER RESPONSES 
*    34        SET CARD PARAMETERS
*    35        >> NOT USED << 
*    36        SET TEMPORARY CARD PARAMETERS
*    37        SET READ CONFIGURATION 
* 
* THE FOLLOWING I/O REQUESTS ARE SUPPORTED: 
* 
*  READ:
* 
*   BIT  10     9     8     7     6 
*     +-----+-----+-----+-----+-----+ 
*     |XPRNT|NOCLR| ECHO|     |BINRY| 
*     +-----+-----+-----+-----+-----+ 
* 
*   BIT 10: TRANSPARENT; NO EDITING OF USER DATA (BACKSPACE,DEL) IS 
*           PERFORMED. END OF RECORD CHAR IS <CR> 
*       9:  ANY DATA IN CURRENT CARD RECORD PAST END OF USER BUFFER 
*           IS SAVED ON CARD UNTIL NEXT READ(S), ELSE IT IS CANCELLED 
*           THIS BIT IS INDEPENDENT OF 10,8,6 
*       8:  ENABLE ECHO OF INCOMMING CHARACTERS, IF APPLICABLE
*       7:  NOT USED  
*       6:  BINARY TRANSFER; CHARACTERS ARE RECEIVED UNTIL USER BUFFER
*           IS FULL.  CARD IS NOT RECONFIGURED FOR CHARACTER LENGTH!!!
*  WRITE: 
* 
*   BIT  10     9     8     7     6 
*     +-----+-----+-----+-----+-----+ 
*     |XPRNT|     |     |     |BINRY| 
*     +-----+-----+-----+-----+-----+ 
* 
*    BIT 10:  TRANSPARENT; NO CR/LF IS APPENDED TO BUFFER 
*        9-7: NOT USED
*         6:  BINARY; SAME AS TRANSPARENT.  
* 
* 
* DRIVER STATUS (EQT5 BITS 7-0) IS DEFINED AS FOLLOWS:
* 
*   BIT  7     6     5     4     3     2     1     0
*     +-----+-----+-----+-----+-----+-----+-----+-----+ 
*     |TIMOT|BREAK| EOT |MODEM|PF/OV|DATA |SCHED|     | 
*     +-----+-----+-----+-----+-----+-----+-----+-----+ 
* 
*  BIT 7: TIMEOUT OCCURRED ON LAST REQUEST
*      6: BREAK KEY HIT, BUT NOT DURING READ
*      5: END-OF-TAPE (CONTROL-D HIT) 
*      4: MODEM LINE DOWN OR FATAL MULTIPOINT ERROR 
*      3: PARITY ERROR OR OVERFLOW ON LAST READ 
*      2: TYPE-AHEAD DATA AVAILABLE (LEN IN B REGISTER) 
*      1: PROGRAM SCHEDULING ENABLED
*      0: NOT USED, ALWAYS ZERO 
* 
* 
* WHEN THE SUCH HARDWARE EXISTS, THIS DRIVER WILL SUPPORT 
* FULL DUPLEX MODEMS, EITHER DOWNING THE LU ON LINE FAILURE 
* OR SIMULATING AN EOT (AT USER'S OPTION).  
* 
* FULL DATA BUFFERING (TYPE-AHEAD) IS PROVIDED.  IF DATA IS RECEIVED
* BEFORE A READ REQUEST IS POSTED TO THE EQT, IT WILL BE SAVED ON THE CARD
* UNTIL SUCH A REQUEST APPEARS OR A FLUSH COMMAND (26B) IS GIVEN. 
* MULTIPLE CLASS READ REQUESTS ARE THEREFORE NOT REQUIRED TO PREVENT DATA 
* LOSS, AND YOU DON'T GET THOSE STUPID PROMPTS WHEN EDITING!
* 
* 
*  LABEL NAMING CONVENTIONS USED IN THIS DRIVER:
* 
*   FIRST CHAR = .   "DEF" TO SOME ROUTINE OR TABLE 
*                @   I/O CARD COMMAND 
*                ?   MASK FOR LOOKING AT OR SETTING A BIT 
*                !   MASK FOR REMOVING A BIT
*                #   GENERAL MISC CONSTANT
*                BITXX  BIT XX TURNED ON
*                BXX  OCT XX
*                DXX  DEC XX
*                DMXX DEC -XX 
* 
*    COMMENTS OF THE FORM "A(XXXX)" MEAN "ADDRESS OF XXXX"
* 
      NAM DVM00,0 12792-16002 REV.2032 800819 V.49  
      EXT $LIST,$UPIO,PM00,$OPSY,$DVTB
      ENT IM00,CM00 
* 
A     EQU 0 
B     EQU 1 
SC    EQU 0 
* 
EQT1  EQU 1660B 
EQT2  EQU 1661B 
EQT3  EQU 1662B 
EQT4  EQU 1663B 
EQT5  EQU 1664B 
EQT6  EQU 1665B 
EQT7  EQU 1666B 
EQT8  EQU 1667B 
EQT9  EQU 1670B 
EQT10 EQU 1671B 
EQT11 EQU 1672B 
EQT12 EQU 1771B 
EQT13 EQU 1772B 
EQT14 EQU 1773B 
EQT15 EQU 1774B 
* 
EQTA  EQU 1650B     A(FIRST EQT)
EQT#  EQU 1651B     NO. OF EQTS IN SYSTEM 
INTBA EQU 1654B     A(INTERRUPT TABLE)
CHAN  EQU 1673B     CURRENT DMA CHANNEL ASSIGNMENT
SYSTY EQU 1675B     SYSTEM CONSOLE EQT ADDR 
OPATN EQU 1734B     SYSTEM ATTENTION FLAG 
* 
*  EQT EXTENSION
* 
EXST  EQU * 
* 
EQT16 NOP 
EQT17 NOP 
EQT18 NOP 
EQT19 NOP 
EQT20 NOP 
EQT21 NOP 
EQT22 NOP 
EQT23 NOP 
EQT24 NOP 
EQT25 NOP 
EQT26 NOP 
EQT27 NOP 
EQT28 NOP 
EQT29 NOP 
EQT30 NOP 
EQT31 NOP 
EQT32 NOP 
* 
EXND  EQU * 
* 
*  EQT LABELS:
* 
EQTM4 EQU EQT9      EQT TEMP (BUFFER ADDRESS) 
EQTM2 EQU EQT10     EQT TEMP (LEN OF THIS XFER) 
PSW   EQU EQT11     PORT STATE WORD:  BIT 15 = CARD BUSY ON THIS EQT
*                                         14 = DEFERRED ABORT IN PROGRESS 
*                                         13 = WAITING FOR/USING DMA
*                                         12 = BUFFER FLUSH STATE 
*                                         11 = USING DMA CHANNEL 1
*                                         10 = I/O XFER IN PROGRESS 
*                                          9 = UNSOL. INT BEING PROCESSED 
*                                          8 = DON'T ABORT - UNSOL INT RUNNING
*                                         7-0= LAST READ CONFIG 
NXTEQ EQU EQT12     BIT 15: THIS EQT SUSPENDED ON ITSELF
*                   BIT 14-0: A(NEXT EQT SUSPENDED ON THIS CARD)
PGMAD EQU EQT16     A(PROGRAM ID SEG TO SCHEDULE) 
LEVL1 EQU EQT17     LEVEL 1 INTERRUPT RETURN POINT (WAIT,DMA WAIT)
LEVL2 EQU EQT18     LEVEL 2 RETURN POINT (CMD1W,CMD2W,RQDMA,DOXFR)
LEVL3 EQU EQT19     LEVEL 3 RETURN POINT (QUEUE, STXFR, CANIT)
PID   EQU EQT20     PORT ID WORD (FROM CTRL 30) 
CNFG1 EQU EQT21     DRIVER CONFIGURATION WORD (CTRL 33) 
CNFG2 EQU EQT22     CARD CONFIG WORD (CTRL 34)
TAHLN EQU EQT23     LENGTH OF TYPE'D AHEAD MESSAGE IN CHARS 
EQTM3 EQU EQT24     EQT TEMP (THIS XFER COUNT REMAINING)
EQTM1 EQU EQT25     EQT TEMP (2ND WORD SENT/RECEIVED) 
EQTM5 EQU EQT26     EQT TEMP (REMAINING USER BUFFER LEN)
PSW2  EQU EQT27     PORT STATUS, 2ND WORD:
*                   BIT 15:  PARTIAL READ 
*                       14,13:  00=CTRL-D RECEIVED
*                               01=<CR> 
*                               10=<DC2>
*                               11=<RS>   
*                       12-9: NOT USED
*                          8: PORT HAS KEY
*                        7-0: PORT STATUS AS DEFINED ABOVE
DVCMD EQU EQT28     DEVICE DRIVER COMMAND TO INTF DVR 
DVTMO EQU EQT29     DEVICE DRIVER TIMEOUT 
EXCOD EQU EQT30     INTERFACE DRIVER EXEC REQUEST 
BUFRA EQU EQT31     INTERFACE DRIVER I/O BUFFER ADDRESS OR OPT PARAM
BUFLN EQU EQT32     INTERFACE DRIVER I/O BUFFER LENGTH
* 
*   VARIOUS CONSTANTS:
* 
BIT0  OCT 1 
BIT1  OCT 2 
BIT2  OCT 4 
BIT3  OCT 10
BIT4  OCT 20
BIT5  OCT 40
BIT6  OCT 100 
BIT7  OCT 200 
BIT8  OCT 400 
BIT9  OCT 1000
BIT10 OCT 2000
BIT11 OCT 4000
BIT12 OCT 10000 
BIT13 OCT 20000 
BIT14 OCT 40000 
BIT15 OCT 100000
* 
*  INITIATION ENTRY POINT 
* 
IM00  NOP           INIT ENTRY POINT
      JSB SETUP     CONFIGURE I/O AND EQT EXTENT POINTERS 
      CLA,INA       SET ENTERED AT I. FLAG
      STA I.FLG 
      LDA EQT5,I    POWER FAIL ENTRY??
      SSA           ...CHECK IF BEEN HERE BEFORE
      STA PFFLG     YES! SET FLAG FOR READ
      LDA IM00      MOVE RETURN POINT TO C. 
      STA CM00
      LDA PGMAD,I   FIRST TIME FOR THIS CARD? 
      SZA 
      JMP I.1       NO
* 
      LDA SCODE     INDEX INTO INTERRUPT TABLE
      ADA DM6 
      ADA INTBA 
      LDB A,I       FETCH ENTRY 
      SSB,RSS       A(PGM)? 
      CLB,INB       NO
      CMB,INB       NEGATE: PGM->TRUE ADDR; NO PGM-> -1 
      STB PGMAD,I   SAVE IN EQT 
      LDB EQT1      SET INTERRUPT TABLE ENTRY TO THIS EQT 
      LDA SCODE 
      ADA DM6 
      ADA INTBA 
      STB A,I       PLOP
      LDA JSB       CREATE PRIVILEGED INTERRUPT LINK TO PRE-DRIVER
      JSB USRMP     USER MAP ENABLED??? 
      XSA SCODE,I   YES, CROSS STORE TO SYS BASE PAGE 
      RSS 
      STA SCODE,I   NO, DIRECT STORE
      LDA EQTA
      STA TMP1      A(FIRST EQT)
      LDA EQT#
      CMA,INA 
      STA TMP       # OF EQT'S
* 
I.2   LDB TMP1      A(EQT)
      ADB B3        ..A(EQT4) 
      LDA B,I       ..FETCH 
      AND #SCOD     ISOLATE SELECT CODE 
      CPA SCODE     OUR CARD? 
      JMP I.3       YES, GOT ONE (MAYBE)
* 
I.4   LDB TMP1      GET NEXT EQT
      ADB D15 
      STB TMP1
      ISZ TMP       DONE? 
      JMP I.2       NO, CHECK THIS GUY OUT
      LDA PSW2,I    YES, SET 'PORT HAS KEY' FLAG INCASE OF CONSOLE
      IOR ?KEY
      STA PSW2,I
      JMP I.1       DONE WITH SETUP 
* 
I.3   ADB DM1       LOOK AT C. ENTRY POINT
      LDA B,I       ..INCASE OF WIERD GEN OR BOOT 
      CPA EQT3,I
      RSS 
      JMP I.4       NOOOOOP, TRY AGAIN
      INB           BUMP TO EQT4
      LDA B,I       ..TO SET ENTER-ON-TIMEOUT BIT 
      IOR #ENTO 
      STA B,I 
      LDB TMP1      BEGINNING OF THIS EQT 
      ADB D12       BUMP TO A(EXTENT) 
      LDB B,I 
      LDA PGMAD,I   A(PROGRAM TO SCHED) 
      STA B,I       ..SET IN NEW EQT
      JMP I.4       END OF THIS EQT SETUP 
* 
I.1   LDA PSW2,I    FETCH OLD STATUS
      AND #CLFC     ..CLEAR OUT P-FAIL, TO, EOT, PARITY BITS
      STA PSW2,I    ..UPDATE
      LDA EQT6,I    FETCH REQUEST 
      CPA #SYCL     SYSTEM CLEAR REQUEST? 
      JMP IOCLR     ..YES, THINK ABOUT IT 
      LDA EQT3,I    DMA ALLOCATION? 
      SSA,RSS 
      JMP I.5       NO
      LDA LEVL1,I   YES, RETURN TO REQUESTOR
      JMP A,I       ..(PROBABLY RQDMA)
* 
IOCLR JSB CKIO      CHECK IF WE HAVE CARD.  IF SO, ABORT..
      JMP COMPL     ELSE EXIT, AND CALL DEVICE DRIVER 
* 
* 
*    CALL DEVICE DRIVER FOR THIS NEW USER REQUEST 
* 
I.5   JSB DVDVR     CALL DEVICE DRIVER
      CPA #NWRQ     START REQUEST?
      JMP *+3       YES 
      SZA           ALSO CHECK A=0 FOR NEW REQUEST
      JMP CM00,I    NO, WE IS DONE! A&B REGS ALREADY SET, EXIT
* 
I.6   CLA           SET DEFAULT EXIT PARAMS 
      STA EXCMD     
      STA XLOG
      LDA EXCOD,I   FETCH DEVICE DRIVER REQUEST 
      RAR 
      SSA,SLA       READ OR WRITE 
      JMP CTRL      NO, CONTROL -> PROCESS
      SLA,RSS 
      JMP READ      PROCESS READ REQUEST
      JMP WRITE     ........WRITE...... 
**********************************************************
* 
*   CONTINUATION ENTRY
* 
CM00  NOP 
      JSB SETUP     SET I/O AND EQT PTRS
      LDA EQT4,I    CHECK FOR TIMEOUT 
      AND BIT11 
      LDB LEVL1,I   PREPARE EXIT ADDRESS..
      SZA,RSS       TIMEOUT?
      JMP B,I       NO, MUST BE INTERRUPT, GO PROCESS!
* 
      XOR EQT4,I    TIMEOUT! CLEAR FOR NEXT ENTRY 
      STA EQT4,I
      LDA PSW,I     WAITING FOR DMA?
      AND ?DMA
      SZA 
      JMP B,I       YES, COULDN'T GET IT, HANDLE WITH LOOP
* 
      LDA PSW2,I    SET TIMEOUT BIT IN STATUS 
      IOR ?TO 
      STA PSW2,I
* 
      JSB CKIO      PLAIN OLD TIMEOUT... CHECK IF I/O IN PROGRESS 
IOCL2 LDA CNFG1,I   IN TYPE-AHEAD MODE? 
      AND #TACN 
      SZA 
      JMP COMPL     YES, LEAVE ANY DATA ALONE 
* 
      JSB QUEUE     NO, MUST SEND CANCEL TO CLEAR OLD DATA
      JSB CANIT 
      LDA #BRD      RESET CARD READ CONFIG
      STA EQTM2,I   SET CONFIG..
      CLA,INA       ..AND LEN (1 CHAR DEFAULT)
      STA EQTM3,I 
      JSB STREC     GO SET! 
      JMP COMPL     DONE!  CALL DEVICE DRIVER 
* 
?TO   EQU BIT7      TIMEOUT BIT IN PSW2 
**********************************************************
* 
*  CHECK IF USER MAP IS ENABLED.  
*       
*     RETURNS:  P+1  USER MAP 
*               P+4  SYSTEM MAP OR NOT MAPPED 
* 
*   SO...  CALLING SEQUENCE = JSB USRMP 
*                             XLA/XSA ... 
*                             RSS 
*                             LDA/STA ... 
* 
USRMP NOP           CHECK IF USER MAP IS ENABLED
      LDB $OPSY     GET SYSTEM TYPE 
      RBR,SLB       (CHECK BIT 1 OF $OPSY)
      JMP USRM2     ..YES! CHECK WHICH MAP
      JMP USRM3     NOT MAPPED (SAME AS SYS MAP) P+4 RETURN 
USRM2 RSB           DMS SYSTEM: IS USER MAP ENABLED?
      BLF,SLB 
      JMP USRMP,I   YES, P+1 RETURN 
USRM3 LDB USRMP     SYSTEM MAP: P+4 RETURN
      ADB B3
      JMP B,I 
* 
*   CLEAR BUFFER FLUSH STATE FLAG IN PSW
* 
CLBFL NOP           CLEAR BUFFER FLUSH CONDITION
      LDA PSW,I     FETCH PORT STATUS 
      AND !BFL      ..KILL BIT
      STA PSW,I     ..RESTORE 
      JMP CLBFL,I   ..RETURN
* 
DM6   DEC -6
D15   DEC 15
DM1   DEC -1
D12   DEC 12
B77   OCT 77
B7    OCT 7 
#SCOD EQU B77       SELECT CODE MASK
#XCMD EQU B7        EXIT COMMAND MASK IN DEV DVR CMD TO INTF DVR
#EXSZ ABS EXST-EXND SIZE OF EXTENT
#AV   OCT 140000    AV FIELD IN EQT5
#CLFC OCT 177426    CLEAR TO/PF/EOT/ABT/PE BITS IN STATUS 
#ENTO OCT 30000     ENTER DRIVER ON TIMEOUT AND POWER FAIL (EQT4) 
#SYCL OCT 100003    EQT WORD 6 ON SYSTEM CLEAR (XSIO CTRL 0)
?DMA  EQU BIT13     DMA WAIT BIT IN PSW 
!DMA  OCT 157777    REMOVE DMA WAITING BIT IN PSW 
?BFL  EQU BIT12     BUFFER FLUSH BIT IN PSW 
!BFL  OCT 167777    REMOVE BUFFER FLUSH BIT IN PSW
* 
*************************************** 
*   READ REQUEST PROCESSOR            * 
*************************************** 
READ  JSB CLBFL     KILL BUFFER FLUSH 
      JSB IOINT     INITIALIZE POINTERS FOR I/O XFER
      LDA DVCMD,I   FETCH FUNCTION FROM DEVICE DRIVER 
      ALF,ALF       ROTATE..
      AND #DVF1     ..AND MASK CODE 
      STA B         SAVE
      SZA           ANY SET?
      JMP RDT15     YES, USE IT 
* 
      LDA CNFG1,I   DON'T SEND READ CONFIG BIT SET??
      AND ?SREC 
      SZA 
      JMP RDT1      YES, SO DON'T SEND IT!
* 
      LDA EXCOD,I   NO, MAKE READ CONFIG WORD FROM EXEC FUNCTION
      AND #RMSK     ISOLATE XPARENT, ECHO, BINARY BITS
      RRR 6         POSITION BITS 10,8,6 IN 4,2,0 
      INA           MOVE BIT 0 TO BIT 1 
      RAR           10,8,6 IN 3,1,0 
      STA B 
      AND BIT3      ISOLATE XPARENT BIT 
      RAR           POSITION
      IOR B         MERGE: BITS 10,8,6 IN 2,1,0 
      AND B7        CLEAN OFF GARBAGE 
      ADA .RCMD     VECTOR TO FIND CORRECT CONFIG WORD
      LDB A,I 
* 
      LDA B         IS THIS BINARY? 
      AND ?ENCT     ..CHECK END-ON-COUNT BIT IN CARD READ CONFIG
      IOR PFFLG     ALSO CHECK POWER-FAIL ENTRY 
      SZA           
      JMP RDT11     YES, MUST SETUP READ
      LDA PSW,I     SAME READ AS LAST TIME? 
      AND #RCMD 
      CPA B         HUMMMM? 
      JMP RDT1      YES, DON'T BOTHER CARD WITH WHAT IT ALREADY KNOWS 
* 
RDT11 STB EQTM2,I   SAVE NEW TYPE HERE FOR LATER
      JSB QUEUE     GO BOTHER CARD..
      JSB STREC     SET READ TYPE 
      LDA PSW2,I    TYPE-AHEAD DATA AVAIL?
      AND ?TAH
      SZA 
      JMP RDT13     YES, GO FETCH 
      JMP UNSOL     NO, WAIT
* 
RDT15 AND ?ENCT     END ON COUNT??
      IOR PFFLG     ..OR POWER FAIL ENTRY?
      SZA 
      JMP RDT11     YES! MUST SET CONFIG
* 
RDT1  LDA PSW2,I    DATA AVAIL? 
      AND ?TAH
      SZA,RSS 
      JMP UNSOL     NO, HANG AROUND A WHILE 
* 
      JSB QUEUE     KNAB CARD 
RDT13 LDA TAHLN,I   FETCH DATA LENGTH 
      STA EQTM3,I   SAVE FOR LATER
* 
* >>>> ENTRY FROM 'MESSAGE RECEIVED' INTERRUPT <<<< 
* 
RDT3  LDA PSW,I     CHECK FOR EOT:  END-ON-CHAR ENABLED?
      AND ?ENCH 
      SZA,RSS 
      JMP RDT14     NO, CAN'T CHECK CHAR
      LDA PSW2,I    YES, CHECK LAST CHAR REC
      AND #RCS2 
      SZA,RSS 
      JMP RCEOT     EOT! NO XFER, DO CANCEL AND SET STATUS
* 
RDT14 JSB STXFR     SET UP TRANSFER 
      LDB EQTM2,I   FETCH XFER LEN
      SZB,RSS       ..ZERO LEN? 
      JMP RDT8      ..YES, CARD WANTS CANCEL, NOT READ
      LDA @READ     TELL CARD WE WANT ITS DATA
      JSB CMD2D     ......HEY CARD!!! 
      JSB DOXFR     ......GIMME IT
      LDA EQTM3,I   ANY DATA LEFT TO TRANSFER?
      SZA 
      JMP RDT4      YES 
RDT9  LDA PSW2,I    NO, END OF MESSAGE? 
      AND ?EOMP 
      SZA 
      JMP RDT7      NO, WAIT FOR MORE 
* 
RDT5  LDA EQTM3,I   NEW COUNT OF WHAT'S LEFT
      STA TAHLN,I 
* 
RDT6  LDA CNFG1,I   TYPE-AHEAD ENABLED OR 'DONT SEND' BIT SET?
      AND #TACN 
      SZA       
      JMP RDT10     YES 
      LDA EXCOD,I   BIT 9 SET IN USER REQUEST (KEEP DATA)?
      AND BIT9
      SZA 
      JMP RDT16     YES, DON'T CLEAR! 
      LDA TAHLN,I   ANYTHING ON CARD TO REMOVE? 
      SZA           
      JSB CANIT     YES, REMOVE FIRST, THEN.. 
RDT16 LDA #BRD      SETUP 1 CHAR BINARY READ
      LDB EQTM2,I   SAVE LEN FOR SXLOG! 
      STB EQTM5,I 
      STA EQTM2,I 
      CLA,INA       1 CHAR..
      STA EQTM3,I 
      JSB STREC     GO SET
      LDB EQTM5,I   RESET LEN 
      STB EQTM2,I 
* 
RDT10 LDB TAHLN,I   LEN OF DATA ON CARD 
      JSB CLTAH     REMOVE TYPE-AHEAD STATUS BIT
      SZB           ..SET IN STATUS IF
      IOR ?TAH      ....SOME DATA LEFT
      STA PSW2,I
      JSB SXLOG     SET TRANSMISSION LOG
      JMP COMPL     THIS READ COMPLETE!! EXIT, STAGE LEFT 
* 
RDT8  JSB CANIT     ZERO LEN READ:  CARD WANTS CANCEL,
      JMP RDT9
* 
RDT4  LDA EQTM5,I   DATA LEFT: SPACE TO PUT IT? 
      SZA 
      JMP RDT14     YES, TRANSFER MORE! 
      LDA EXCOD,I   NO SPACE, SAVE REST?
      AND BIT9      ..LOOK AT BIT9 IN USER REQ
      SZA 
      JMP RDT5      CLEAN UP AND COMPLETE 
      STA EQTM3,I   CLEAR XFER LEN SINCE....
      JSB CANIT     ...USER DOESN'T WANT DATA 
      JMP RDT9      AND FINISH
* 
RDT7  XOR PSW2,I    CLEAR NOT-EOM-BIT 
      STA PSW2,I
      JSB CKABT     CHECK FOR ABORT IN PROGRESS 
      JMP UNSOL     WAIT FOR RAIN 
* 
RCEOT LDA PSW2,I    SET EOT BIT IN STATUS 
      IOR ?EOT
      STA PSW2,I
RCPE2 JSB CANIT     REMOVE DATA 
      CLA           SET LEN OF XFER TO ZERO FOR SXLOG 
      STA EQTM2,I 
      JMP RDT6      CLEAN UP
* 
*  ROUTINE TO SETUP CARD RECEIVE TYPE 
* 
*   INPUT: EQTM2 = READ CONFIG WORD 
*          EQTM3 = RECORD LEN IF BINARY 
*          EQTM5 = RECORD LEN IF BINARY AND EQTM3 IS ZERO (DEFAULT) 
* 
*   SETS CARD TYPE AND UPDATES PSW FOR NEXT TIME
*   THIS ROUTINE IS <LEVEL 3> SO DON'T CALL IT FROM UNSOLICITED PROCESS 
* 
STREC NOP           SET READ TYPE 
      LDA STREC     SAVE RETURN ADDR
      STA LEVL3,I 
      LDA EQTM2,I   
      AND #RCNF     REMOVE GARBAGE
      SZA,RSS       ANYTHING TO SET 
      JMP STREC,I   NO
      AND ?ENCT     BINARY READ?
      SZA,RSS 
      JMP STRC2     NO
      LDB EQTM3,I   FETCH PHYSICAL XFER LEN FROM DEVICE DRIVER
      SZB,RSS       ANY SET?
      LDB EQTM5,I   NO, USE USER'S BUFFER LEN 
      LDA @SBFL 
      JSB CMD2W     TELL CARD 
STRC2 LDB EQTM2,I   FETCH NEW READ TYPE.. 
      LDA @RCTP     SEND NEW RECEIVE TYPE 
      JSB CMD2W 
      LDA PSW,I     SAVE NEW RECEIVE TYPE IN PSW
      AND !RCMD 
      STA B         SAVE... 
      LDA EQTM2,I   FETCH NEW TYPE
      AND #MRCN     SAVE ONLY MUX READ CONFIG 
      IOR B         MERGE WITH REST OF PSW
      STA PSW,I 
      LDA LEVL3,I   RETURN
      JMP A,I 
* 
B377  OCT 377 
#MRCN EQU B377      MUX READ CONFIG IN PSW
* 
*  INITIALIZE POINTERS FOR READ/WRITE PROCESSORS
*   
*   EQTM4 = STARTING BUFFER WORD ADDRESS
*   EQTM5 = CHARACTER LEN OF BUFFER 
* 
IOINT NOP           SET UP POINTERS FOR READ/WRITE ROUTINES 
      LDA BUFRA,I   SET UP BUFFR ADDR FOR LATER XFER
      STA EQTM4,I 
      LDA BUFLN,I   ..BUFR LEN
      JSB TOCHR     ...CONVERT TO CHARS 
      STA EQTM5,I   = MAX XFER LEN
      JMP IOINT,I   RETURN
* 
*  SET TRANSMISSION LOG FOR READ/WRITE PROCESSORS 
*    XLOG IS CALCULATED FROM WHATS LEFT AFTER A TRANSFER BY 
*    DOXFR:  EQTM4 = BUFFER END ADDRESS+1, EQTM2 = LENGTH 
*    OF LAST PIECE TO DETERMINE ODD/EVEN FOR CHAR LEN 
*    IF BUFLN IS POSITIVE.  SINCE ALL PIECES OF XFER ARE EVEN 
*    UP TO THE LAST, EQTM2 CAN BE USED AS AN OVERALL ODD/EVEN 
*    INDICATOR.  BUFFER START ADDER IS IN BUFRA FROM DEVICE DVR 
* 
SXLOG NOP           SET XMIT LOG  
      LDA BUFRA,I   CALCULATE XFER LEN
      CMA,INA       ..FROM OLD AND NEW
      ADA EQTM4,I   ..BUFFER ADDRESSES
      RAL           ..IN CHARS
      LDB EQTM2,I   ODD OR EVEN?
      SLB           
      INA           ODD, CHAR COUNT ONE MORE
      LDB BUFLN,I   WANT IN BYTES?
      SSB 
      JMP *+3       YES, LEAVE IT 
      INA           NO, ROUND TO WORDS
      CLE,ERA       CONVERT 
      STA XLOG
      JMP SXLOG,I   AND RETURN
* 
*  CLEAR TYPE-AHEAD DATA AVAILABLE STATUS IN PSW2 
* 
CLTAH NOP           CLEAR TYPE-AHEAD STATUS 
      LDA PSW2,I    GET DRIVER STATUS 
      AND !TAH      REMOVE..
      STA PSW2,I    ...BIT
      JMP CLTAH,I   AND RETURN
* 
*   CANCEL CARD BUFFER(S) 
*   >>>>> DO NOT CALL THIS ROUTINE FROM ANY UNSOLICITED INTERRUPT <<<<
*   >>>>> PROCESSOR!!  LEVL3 WILL BE WIPED BY QUEUE IF THIS EQT   <<<<
*   >>>>> GETS SUSPENDED ON ITSELF!!!!!                           <<<<
* 
CANIT NOP           CLEAR CARD OF GARBAGE DATA
      LDB CANIT     FETCH RETURN ADDR 
      LDA @CAN      GET CARD COMMAND TO CANCEL ONE BUFFER 
      JMP CAN2      
* 
CANAL NOP           ENTRY POINT TO CANCEL >ALL< CARD BUFFERS ON THIS PORT 
      LDB CANAL     ..RETURN ADDR 
      LDA @CANA     ..PORT CLEAR COMMAND
* 
CAN2  STB LEVL3,I   SAVE RETURN ADDR
      JSB CMD1W     SEND COMMAND TO CARD
      CLA           NOW NOTHING ON CARD.. 
      STA TAHLN,I   ..SO CLEAR COUNTER
      STA EQTM3,I   ..INCLUDING DATA REMAINING
      JSB CLTAH     ....AND STATUS
      LDA LEVL3,I   FETCH RETURN ADDR 
      JMP A,I       ..EXIT, STAGE RIGHT 
* 
*  THIS TABLE DEFINES WHICH TERMINATORS TO USE FOR READ REQUESTS
*  TO THE MUX CARD.  BITS 6,8,10 IN EXCOD FORM A 3 BIT INDEX
*  INTO THIS TABLE.  THESE ARE DEFAULT VALUES WHICH ARE USED IF 
*  THE DEVICE DRIVER DOES NOT SPECIFY ANY OVERRIDES 
* 
.RCMD DEF *+1       READ TYPES: VECTOR ON BITS 10/8/6 
      OCT 246       ASCII, ECHO OFF 
#BRD  OCT 010       BINARY, ECHO OFF
      OCT 247       ASCII, ECHO ON
      OCT 011       BINARY, ECHO ON 
      OCT 204       TRANSPARENT, ECHO OFF 
      OCT 010       BI & TR - TAKE BI, ECHO OFF 
      OCT 205       TRANSPARENT, ECHO ON
      OCT 011       BI & TR - TAKE BI; ECHO ON
* 
BM5   OCT 177773
B17   EQU D15 
DM255 OCT 177400
#RMSK OCT 2500      BITS 10,8,6 IN READ FCN 
B160K OCT 160000
#RCS2 EQU B160K     TERMINATING CHARACTER AND NOT-EOM IN PSW2 
#RCMD EQU B377      LAST READ CONF IN PSW 
#DVF1 OCT 174377    DEVICE DRIVER FCN CODE IN DEV DVR CMD TO INTF DVR 
#TACN OCT 20200     TYPE-AHEAD & DON'T SEND ENABLE RECEIVE IN CONFG1
!RCMD EQU DM255     REMOVE READ CONFIG IN PSW 
?TAH  EQU BIT2      TYPE-AHEAD DATA AVAIL BIT IN STATUS 
!TAH  EQU BM5       REMOVE TYPE-AHEAD DATA AVAIL BIT IN STATUS
?EOMP EQU BIT15     NOT-END-OF-MESSAGE-YET BIT IN PSW2
?ENCH EQU BIT2      END-ON-CHARACTER BIT IN ENABLE REC CMD TO CARD
?ENCT EQU BIT3      END-ON-COUNT BIT IN ENABLE REC CMD TO CARD
?SREC EQU BIT7      DON'T SEND READ CONFIG IN CNFG1 
* 
*************************************** 
*    WRITE REQUEST PROCESSOR          * 
*************************************** 
WRITE JSB QUEUE     KNAB CARD 
      LDA PSW,I     CHECK BUFFER FLUSH
      AND ?BFL
      SZA,RSS 
      JMP WRT5      NO, WRITE OK
      LDA EQT1,I    FETCH A(NEXT REQUEST ON Q)
      JSB USRMP     USER MAP ENABLED??
      XLA A,I       YES, CROSS LOAD ITS LINK PTR
      RSS 
      LDA A,I       NO, FETCH DIRECTLY
      SZA           ANYBODY ELSE WAITING? 
      JMP COMPL     YES, IGNORE THIS REQUEST
      JSB CLBFL     NO!  CLEAR BUFFER FLUSH 
* 
WRT5  JSB IOINT     SET UP BUFFER PTRS
      LDA DVCMD,I   FETCH DEVICE DRIVER CMD.. 
      ALF,ALF       POSITION TO GET.. 
      AND #MRCN     ..MUX READ CONFIG.. 
      STA EQTM2,I   ..TO SEND TO... 
      JSB STREC     CARD FOR WRITE-READ REQUEST 
* 
WRT3  LDA @SEL      REQUEST XMIT
      JSB CMD2W     ..SEND TO CARD
* 
*  >>>> ENTRY FROM 'TRANSMIT BUFFER AVAILABLE' INTERRUPT <<<< 
* 
WRT1  SZA,RSS       BUFFER AVAIL? 
      JMP UNSOL     NO,WAIT FOR ONE 
      STA EQTM3,I   YES, SAVE LEN 
      JSB STXFR     SET UP DATA TRANSFER
      LDA DVCMD,I   GET DEVICE DRIVER CMD 
      AND #OVRD     OVERRIDE EXEC FUNCTION CODE?
      ALF,ALF 
      SZA 
      JMP WRT4      YES 
      LDA EXCOD,I   NO, FETCH FUNCTION CODE 
      AND #BITR     ISOLATE BINARY AND XPARENT BITS (6&10)
      SZA,RSS       EITHER SET? 
      LDA ?CRLF     NO, SEND CR/LF
WRT4  AND #OVR2     MASK TO JUST "WRITE DATA CMD" BITS    
      LDB EQTM5,I   CHECK IF WANTED XFER LEN..
      CPB EQTM2,I   ..IS THE SAME AS REAL XFER LEN
      RSS           
      IOR ?PRT      NO!! PARTIAL XFER; THE REST WILL COME LATER 
      IOR EQTM2,I   MERGE FUNCTION FLAGS WITH XFER LEN
      STA B         .. TO 2ND WORD
      LDA @WRT
      JSB CMD2D     SEND 2-WORD-BEFORE-DMA COMMAND TO WRITE 
      JSB DOXFR     DO TRANSFER 
      LDA EQTM5,I   ANY DATA LEFT TO TRANSFER?
      SZA 
      JMP WRT3      YES, TRY AGAIN
* 
      JSB SXLOG     SET XMIT LOG
      JMP COMPL     UNSOLICITED WAIT WITH COMPLETE
* 
#BITR OCT 2100      BINARY&TRANSPARENT BITS IN FCN
#OVRD OCT 370       WRITE OVERRIDE FIELD IN DEVICE DRIVER CMD 
#OVR2 OCT 170000    WRITE DATA PART OF WRITE OVERRIDE FROM DEV DVR
?PRT  EQU BIT11     PARTIAL XFER BIT IN WRITE CMD TO CARD 
?CRLF EQU BIT12     ADD CR/LF IN WRITE CMD TO CARD
B6    OCT 6 
* 
**************************************
*    S T X F R   SET UP DATA TRANSFER*
*                                    *
*   SETS EQTM2 TO TRANSFER LEN       *
* INPUT:  EQTM3 = REQ. BUFR LEN      *
*         EQTM5 = REMAINING SPACE IN *
*                 USER BUFFER        *
**************************************
STXFR NOP           SET UP DATA XFER
      LDA STXFR     SAVE RETURN ADDR
      STA LEVL3,I   ..IN EQT
      LDA EQTM5,I   BUFFER SPACE AVAIL. 
      LDB EQTM3,I   LEN OF DATA TO XFER 
      JSB MIN       ..TAKE LESSER 
      STA EQTM2,I   ..AS LEN OF THIS XFER 
* 
*  REQUEST USE OF A DMA CHANNEL.  A-REG = LENGTH OF PROPOSED XFER.
*  IF NOT LONG ENOUGH, DMA IS A WASTE OF TIME, SO NO CHANNEL WILL 
*  BE ASKED FOR.  REQUEST IS MADE WITH A TIMEOUT RUNNING TO PREVENT 
*  EXCESSIVE WAIT (2 MAG TAPE REWINDS, ETC) 
*  NOTE!!!! BECAUSE OF THE USE OF GET-DMA-ON-THE-FLY IN THIS DRIVER 
*  THIS DRIVER WILL ONLY WORK IN RTE-M OR RTE-IVB (NOT A).  TO MAKE 
*  IT WORK IN OTHER SYSTEMS FORCE USE OF LIA/OTA CODE, ALTHOUGH 
*  DOING SO WILL DOUBLE OVERHEAD ON LONG RECORDS (ABOUT 6%/CHANNEL) 
* 
      ADA #DLEN     REALLY NEED DMA?
      SSA 
      JMP NODM2     NO, FASTER TO DO LIA/OTA LOOP 
      LDA PSW,I     SET WAITING FOR DMA FLAG
      IOR ?DMA
      STA PSW,I 
      LDA #DMTO     SET DMA REQUEST TIMEOUT (SAFETY VALVE)
      STA EQT15,I 
      LDA .RDMA     SET RETURN ADDR FROM REQUEST
      STA LEVL1,I 
      LDA B5        EXIT AT P+3 REQUESTING DMA
      ISZ CM00
      ISZ CM00
      JMP CM00,I
* 
.RDMA DEF *+1 
      LDA I.FLG     >>> RETURN POINT <<< GOT DMA? 
      SZA,RSS       (CHECK IF ENTERED AT I. ) 
      JMP NODMA     NO DMA, MUST DO LIA/OTA LOOP
      LDA PSW,I     SET CHANNEL ALLOCATED IN PSW FOR "BLAST"
      AND !CH1
      LDB CHAN
      CPB B6        CHANNEL 1?
      IOR ?CH1      YES, SET FLAG 
      STA PSW,I     SET IN STATUS 
      JMP GTDMA     GOT IT! 
* 
NODMA LDA B6        SET DMA RETURN FLAG 
      STA DMFLG     ..SO NEXT EXIT WILL REMOVE EQT FROM DMA Q 
NODM2 LDA PSW,I     CLEAR DMA FLAG
      AND !DMA
      STA PSW,I 
      LDA #LXFR     NOPE, MAX XFER LEN MAY BE SMALLER 
      RSS 
GTDMA LDA #MXFR     MAX XFER LEN CARD CAN TAKE IN ONE SHOT
      LDB EQTM2,I   DATA LEN
      JSB MIN       ..TAKE MIN AGAIN
      STA EQTM2,I   ..REAL XFER LEN (HONEST!) 
      LDB LEVL3,I   RETURN
      JMP B,I 
* 
#MXFR OCT 3777      XFER LEN FIELD IN READ/WRITE CMD TO CARD
#LXFR EQU BIT6      MAX XFER BY LIA/OTA LOOP = 64 CHARS 
#DLEN DEC -15       THRESHOLD LEN OF NON-DMA XFER (BYTES) 
* 
**********************************
*   DOXFR:   CALLS EITHER BLAST  *
* OR OOZE TO DO DATA TRANSFER    *
* TO OR FROM I/O CARD            *
*  EQTM4 = A(BUFFER)             *
*  EQTM2 = LEN(BUFFER) IN BYTES  *
**********************************
* 
DOXFR NOP 
      LDA DOXFR     SAVE RETURN ADDR
      STA LEVL2,I 
      LDA PSW,I     GOT DMA?
      AND ?DMA
      SZA,RSS       BLAST DATA AT CARD? 
      JMP OOZE      NO, USE OZMOSIS 
* 
*  DO DMA TRANSFER TO/FROM CARD.  EQTM3 = BUFFER ADDRESS
*                                 EQTM2 = BUFFER LENGTH 
*    EXCOD (EXEC REQUEST) TELLS READ OR WRITE 
*    PSW MUST CONTAIN VALID CHANNEL FLAG
* 
BLAST LDB B6        SET UP DMA CHANNEL
      LDA PSW,I     CHANNEL 1 OR 2? 
      AND ?CH1
      SZA,RSS 
      INB           CH 2
      LDA B 
      LDB .DMIN     SET DCPC I/O INSTS
      JSB SETEM 
      LDA SCODE     CARD SELECT CODE
OTA03 OTA 6         CW 1
CLC01 CLC 2         SET FOR CW 2
      LDA EQTM4,I   A(BUFFER START) 
      LDB EXCOD,I   READ OR WRITE?
      SLB 
      IOR BIT15     READ: SET INPUT 
OTA04 OTA 2         CW 2
STC02 STC 2         SET FOR CW 3
      LDA EQTM2,I   MAKE XFER LEN 
      JSB TOWRD     CONVERT TO -WORDS 
OTA05 OTA 2         CW 3
STC03 STC 6,C       START DMA 
CLC02 CLC 6         KILL FINISH INTERRUPT (GET ONE FROM CARD) 
      JSB WAIT      WAIT FOR CARD INT.
BLSTX CCA           SEND ONE LAST WORD
      JSB OUT2      ...TO FINISH XFER 
      LDA PSW,I     I/O NO LONGER IN PROGRESS 
      AND #NXFR     ..SO REMOVE DMA, CHANNEL & XFER BITS
      STA PSW,I     ..IN STATUS 
      LDA B6        SET TO RETURN DMA.. 
      STA DMFLG     ...TO SYSTEM
      JSB WAIT      WAIT FOR FINAL INTERRUPT
* 
*  UPDATE POINTERS TO REFLECT WHAT HAS BEEN TRANSFERRED 
*    EQTM4 WILL CONTAIN FIRST WORD OF 'NEXT' BUFFER 
*    EQTM3,5 ARE DECREMENTED TO SHOW WHAT'S LEFT
* 
      LDB EQTM2,I   LEN OF THIS XFER
      CMB,INB       MAKE NEG
      LDA EQTM5,I   BUFR LEN REMAINING..
      ADA B         ..NOW LESS
      STA EQTM5,I 
      LDA EQTM3,I   REMAINING STUFF TO XFER 
      ADA B         ..ALSO LESS 
      STA EQTM3,I 
      LDA EQTM4,I   START ADDR OF BUFFER
      LDB EQTM2,I   LEN IN BYTES..
      CLE,ERB       ..MAKE WORDS
      ADA B         NEW START OF BUFFER 
      STA EQTM4,I 
      LDA LEVL2,I   END OF XFER 
      JMP A,I 
* 
.DMIN DEF *+1       DMA SETUP INSTRUCTIONS
      DEF OTA03 
      DEF OTA04 
      DEF OTA05 
      DEF CLC01 
      DEF CLC02 
      DEF STC02 
      DEF STC03 
      OCT 0         END OF DMA SETUP
* 
*    SIMULATE DMA XFER WITH LIA/OTA LOOP
*    INPUT PARAMS SAME AS "BLAST" 
* 
OOZE  JSB WAIT      WAIT TILL CARD IS READY 
      LDA EQTM2,I   GET LEN 
      SZA,RSS       ZERO LEN RECORD?? 
      JMP BLSTX     YES, DONE 
      JSB TOWRD     CONVERT TO -WORDS 
      STA TMP 
      LDB EXCOD,I   READ OR WRITE?
      SLB 
      JMP OOZ1      READ..
      DLD OUT       WRITE..SET FOR OUTPUT TO CARD 
      JMP OOZ4
OOZ1  DLD IN        READ..SET FOR INPUT FROM CARD 
OOZ4  DST OOZ2
      LDB EQTM4,I   A(BUFFER START) 
OOZ2  NOP           LIA SC,C OR LDA B,I 
      NOP           STA B,I  OR OTA SC,C
      INB           INCR BUFFR PTR
      ISZ TMP       DONE? 
      JMP OOZ3      NO
      LDA EXCOD,I   YES, READ OR WRITE? 
      SLA 
      JMP BLSTX     READ: XFER DONE 
      JSB SFCLP     WRITE, WAIT FOR ONE LAST FLAG 
      JSB WAIT      NO FLAG, WAIT A WHILE   
      JMP BLSTX     ...THEN EXIT
* 
OOZ3  JSB SFCLP     WAIT FOR FLAG 
      JSB WAIT      NO FLAG, WAIT A WHILE (SHOULD NEVER HAPPEN) 
      JMP OOZ2      ..NOW XFER NEXT WORD
* 
* 
IN    EQU * 
LIA02 LIA SC,C
      STA B,I 
* 
OUT   LDA B,I 
OTA06 OTA SC,C
* 
#SFLC DEC -50       # TIMES FOR SFC LOOP TO WAIT FOR CARD FLAG
?CH1  EQU BIT11     USING DMA CHANNEL 1 BIT IN PSW
!CH1  OCT 173777    REMOVE CHANNEL BIT IN PSW 
?XFR  EQU BIT10     DATA TRANSFER IN PROGRESS IN PSW
B1    EQU BIT0
#NXFR OCT 151777    REMOVE DMA, CH1 & XFER BITS IN PSW
* 
****************************************
*  CONTROL REQUEST PROCESSOR           *
****************************************
CTRL  JSB QUEUE     FETCH CARD
      LDA EXCOD,I   GET REQUEST 
      AND #FCN      ISOLATE FUNCTION
      ALF,ALF 
      RAL,RAL       POSITION
      CPA B6        DYNAMIC STATUS? 
      JMP CN06      YES 
      ADA BM20      OFSET FOR VECTORING 
      SSA           OK? 
      JMP COMPL     NO, IGNORE OTHER REQ'S BETWEEN 1&20B
      ADA .CTRL     VECTOR..
      JMP A,I 
* 
.CTRL DEF *+1,I 
      DEF CN20      ENABLE PROGRAM SCHEDULING 
      DEF CN21      DISABLE PROGRAM SCHEDULING
      DEF CN22      SET DEVICE TIMEOUT
      DEF CN23      ENTER BUFFER-FLUSH STATE
      DEF CN24      TERMINATE BUFFER-FLUSH STATE
      DEF COMPL     >>>> NOT USED <<<<  
      DEF CN26      CLEAR CARD BUFFER(S)
      DEF CN27      SET ID-SEGMENT ADDRESS FOR SCHEDULING 
      DEF CN30      SET CARD CONFIG (KEY) 
      DEF CN31      OPEN MODEM LINE 
      DEF CN32      CLOSE MODEM LINE
      DEF CN33      CONFIGURE DRIVER
      DEF CN34      SET CARD PARAMETERS 
      DEF COMPL     >>>> NOT USED <<<<
      DEF CN36      SET TEMPORARY PARAMETERS
      DEF CN37      SET READ CONFIGURATION
* 
CN06  LDA BUFRA,I   DYNAMIC STATUS
      SZA           IPRAM DEFINED?
      JMP CN6.1     YES, FETCH CARD STATUS
CN6.2 LDB TAHLN,I   SET XMIT LOG = LEN OF TYPE-AHEAD DATA 
      STB XLOG      ..AND RETURN NOW
      JMP COMPL 
* 
CN6.1 LDA @GMOD     GET CARD STATUS 
      JSB CMD1W 
      LDB BUFRA,I   FETCH A(USER PARAM) 
      STA B,I       ..AND SAVE CARD STATUS
      JMP CN6.2     SET XMIT LOG AND EXIT 
* 
CN20  LDA PSW2,I    ENABLE PROGRAM SCHEDULING 
      IOR ?ENAB 
CN20A STA PSW2,I
      JMP COMPL     COMPLETE NOW
* 
CN21  LDA PSW2,I    DISABLE PROGRAM SCHEDULING
      AND !ENAB 
      JMP CN20A 
* 
CN22  LDA BUFRA,I   SET TIMEOUT 
      SSA,RSS       IF POS, MAKE NEG
      CMA,INA 
      STA EQT14,I 
      JMP COMPL 
* 
CN23  LDA PSW,I     SET BUFFER FLUSH
      IOR ?BFL
      STA PSW,I 
      JMP COMPL     AND COMPLETE
* 
CN24  JSB CLBFL     CLEAR BUFFER FLUSH
      JMP COMPL     ..AND EXIT
* 
CN26  LDA BUFRA,I   CANCEL CARD BUFFER(S)...FETCH PARAM 
      SZA           KILL ALL? 
      JMP CN26A     YES 
      JSB CANIT     NO, JUST THE CURRENT BUFFER 
      JMP COMPL     EXIT PEACEFULLY 
CN26A JSB CANAL     HAYEEEEEEEEEE! KLUNK! 
      JMP COMPL     EXIT QUICKLY
* 
CN27  LDA BUFRA,I   SET PROG ADDR TO SCHEDULE 
      SSA,RSS       NEG?? 
      SZA,RSS       ZERO??
      CCA           NEGATIVE OR ZERO: DEFAULT TO NO PGM 
      STA PGMAD,I 
      JMP COMPL 
* 
CN30  LDA PSW2,I    SET PORT KEY
      IOR ?KEY
      STA PSW2,I    SET 'PORT KEY SET' FLAG 
      LDA @SKEY     SET PORT KEY
      LDB BUFRA,I 
      STB PID,I     SAVE IN EQT 
CN30A JSB CMD2W     SEND TO CARD
      JMP COMPL     AND EXIT
* 
CN34  LDA @CNF2     CONFIGURE CARD
      LDB BUFRA,I 
      STB CNFG2,I   SAVE IN EQT 
      JMP CN30A     SEND TO CARD AND EXIT 
* 
CN33  LDA #NFLD     CONFIGURE DRIVER FOR THIS PORT
      STA TMP       SET # OF FIELDS COUNTER 
      LDB #AV       SET INITIAL MASK
* 
CN33B LDA BUFRA,I   FETCH USER REQUEST WORD 
      AND B         PICK OFF A FIELD
      SZA,RSS       USER WANT IT SET? 
      JMP CN33A     NO
* 
      STA TMP1      YES 
      LDA B         GET MASK
      CMA           ..COMPLEMENT TO GET CONFIG MASK 
      AND CNFG1,I   CLEAR OLD FIELD 
      IOR TMP1      SLIDE IN NEW FIELD
      STA CNFG1,I   .. AND RESTORE
* 
CN33A RBR,RBR       SET FOR NEXT FIELD TWO BITS THATAWAY
      ISZ TMP       DONE WITH ALL FIELDS? 
      JMP CN33B     NO
* 
      LDA BUFRA,I   SET DEVICE DRIVER # 
      AND #LDVN     ISOLATE.. 
      SZA,RSS       DEFAULT?
      JMP COMPL     YES, EXIT 
      STA TMP       NO, SAVE
      LDB $DVTB     FETCH 1ST WORD OF DEVICE DRIVER JUMP TABLE
      CMA,INA       ...WHICH IS LEN OF TABLE
      INB           CORRECT FOR MISSING DEFAULT DEVICE DRIVER 
      ADB A         WANTED DVR# IN RANGE? 
      SSB 
      JMP CMPL2     NO, DON'T SET 
      LDB .DVTB     OK, CHECK FOR UNDEFINED "DEF" (BAD GEN) 
      ADB TMP       INDEX TO WANTED ENTRY 
      ADB DM1 
      LDB B,I       FETCH 
      SZB,RSS       OK????? 
      JMP CMPL2     NO! CAN'T TALK TO THIN AIR, EXIT
* 
      LDA CNFG1,I   OK, SET IN DRIVER CONFIG WORD 
      AND #LDVM 
      IOR TMP       ..MERGE 
      STA CNFG1,I 
      LDA EQT5,I    CLEAR DRIVER TYPE TO 00 
      AND !DVTP 
      STA EQT5,I    
      JMP CMPL2     AND EXIT NOW (DON'T CALL DEVICE DRIVER) 
* 
CN36  LDA @SMOD     SET TEMPORARY PARAMETERS
      LDB BUFRA,I   FETCH PARAM 
      JMP CN30A     DOIT! 
* 
CN31  LDA @OPL1     OPEN LINE (TYPE 1)
      LDB BUFRA,I   WHICH TYPE??
      SZB 
      LDA @OPL2     OH, TYPE 2
CN31A JSB CMD1W 
      JMP COMPL 
* 
CN32  LDA @CLOS     CLOSE LINE
      JMP CN31A 
* 
CN37  LDA BUFRA,I   SET READ CONFIGURATION
      ALF,ALF 
      AND #RCNF     CLEAR UNWANTED BITS 
      IOR ?RCN2     SET WANTED BITS 
      STA EQTM2,I   SET NEW CONFIGURATION 
      JSB STREC 
      JMP COMPL     DONE
* 
BM20  OCT 177760    -20B
#FCN  OCT 3700      FUNCTION CODE FIELD (EXCOD) 
#NFLD EQU BM5       -# OF FIELDS IN CONTROL 33 IPRAM
#LDVN EQU B17       DEVICE DRIVER NUMBER FIELD IN DRIVER CONFIG (CNFG1) 
#LDVM EQU BM20      REMOVE DEVICE DRIVER NUMBER FIELD IN CNFG1
#RCNF OCT 170377    READ CONFIGURATION FROM USER FOR CN37 
?RCN2 EQU BIT2      FORCE END-ON-CHAR BIT IN CN37 
?ENAB EQU BIT1      SCHEDULE ENABLE BIT IN STATUS 
?KEY  EQU BIT8      PORT KEY SET FLAG IN PSW2 
?NABT EQU BIT8      NO ABORT BIT IN PSW 
!ENAB OCT 177775    REMOVE ENABLE BIT IN STATUS 
!DVTP OCT 140377    REMOVE DRIVER TYPE FIELD IN EQT5
* 
***************************************** 
*   UNSOLICITED INTERRUPT PROCESSOR     * 
*                                       * 
*  READS REQUEST FROM CARD AND VECTORS  * 
*  TO APPROPRIATE ROUTINE FOR PROCESSING* 
***************************************** 
UNSLP JSB LIA       >> UNSOLICITED INTERRUPT PROCESSOR << 
      STA EQTM1,I   SAVE TEMPORARILY
      JSB SBUSY     SET EQT OWNED HERE
      LDA PSW,I     SET UNSOLICITED INTERRUPT BEING PROCESSED 
      IOR ?NABT     SET DON'T ABORT YET BIT 
      LDB EQT1,I    REQUEST PENDING?? 
      SZB,RSS       
      IOR ?UNSL     NO, SET FLAG TO PROTECT QUEUEING
      STA PSW,I 
      LDA @ACK      SEND ACKNOWLEGE 
      JSB CMD1X 
      LDB EQTM1,I   FETCH FIRST WORD
      STA EQTM1,I   SAVE SECOND WORD, IF ANY
      LDA B         COMMAND WORD... 
      AND #CMD      STRIP COMMAND 
      ALF,ALF 
      ADA .CMTB     YES, INDEX INTO COMMAND TABLE 
      STA B 
      LDA EQTM1,I   GET 2ND WORD INCASE SOMEBODY WANTS IT 
      JMP B,I       GO PROCESS! 
* 
.CMTB DEF *+1,I 
      DEF UNSOL     0 ILLEGAL INT (SHOULD NEVER GET HERE) 
      DEF BUFAV     1 XMIT BUFFER AVAIL 
      DEF LINUP     2 MODEM LINE IS UP
      DEF LINDN     3 MODEM LINE IS DOWN
      DEF RCBRK     4 BREAK KEY HIT 
      DEF MSGRC     5 MESSAGE RECEIVED
      DEF UNSOL     6 ILLEGAL 
      DEF UNSOL     7 ILLEGAL 
* 
*  LINE IS NOW UP 
* 
LINUP LDA PSW2,I    MODEM LINK HAS COME UP
      AND !LNDN     REMOVE LINE DOWN BIT IN STATUS
      STA PSW2,I
      AND #AV       EQT DOWN? 
      CPA #DOWN 
      JMP UNSOL     NO, DONE
      LDA .$UP      YES, SET FOR RETURN TO $UPIO
      STA CM00
      JMP CMPL2     EXIT
* 
* LINE IS NOW DOWN
* 
LINDN LDA PSW2,I    MODEM LINK HAS DIED 
      IOR ?LNDN     SET LINE DOWN BIT IN STATUS 
      STA PSW2,I
      LDA CNFG1,I   DOWN DEVICE?
      AND ?DNDV 
      SZA,RSS 
      JMP LIND1     YES 
      LDA EQT1,I    NO, REQUEST PENDING?
      SZA,RSS 
      JMP UNSOL     NO, EXIT QUIETLY
      LDA PSW,I     SET BUFFER FLUSH STATE
      IOR ?BFL
      STA PSW,I 
      JSB RPEND     READ PENDING? 
      RSS 
      JMP UNSOL     NO, EXIT
      LDA PSW2,I    READ: SET EOT BIT 
      IOR ?EOT
      STA PSW2,I    IN STATUS 
      JMP COMPL     ..AND EXIT
LIND1 LDA B1        DOWN DEVICE 
      STA EXCMD 
      JMP COMPL     EXIT
* 
*  USER HIT THE BREAK KEY 
* 
RCBRK JSB RPEND     RECEIVED A BREAK
      JMP UNSOL     READ PENDING: IGNORE
      LDA PSW2,I    SET BREAK RECEIVED BIT IN STATUS
      IOR ?BRK
      STA PSW2,I
      LDA CNFG1,I   CANCEL ON BREAK?
      AND #BRKM 
      CPA #BRKC 
      JMP RCBK3     YES 
RCBK2 JSB SCHED     NO, SCHEDULE PROGRAM
      JMP UNSOL     ..AND EXIT
RCBK3 LDA @CANA     CANCEL ALL BUFFERS! 
      JSB CMD1W 
      CLA           CLEAR ANY KNOWLEGE OF TAH DATA
      STA TAHLN,I   
      JSB CLTAH     ..INCLUDING THE STATUS
      JMP RCBK2     SCHEDULE AND EXIT 
* 
*  ROUTINE TO TEST IF A READ REQUEST IS CURRENTLY PENDING 
*  AND ACTIVE (NOT STUCK IN QUEUE).  RETURNS P+1 YES, P+2 NO
* 
RPEND NOP           CHECK IF CURRENT REQUEST IS A READ
      LDA EQT1,I    ANYBODY HOME? 
      SZA,RSS 
      JMP RPND1     NO
      LDA NXTEQ,I   IS IT REALLY THERE? 
      SSA           ..CHECK SUSPEND-ON-SELF BIT 
      JMP RPND1     NO, PRETEND WE DIDN'T SEE THAT
      LDA EXCOD,I   IS IT A READ? 
      AND B3
      CPA B1
      JMP RPEND,I   YES, P+1 RETURN 
RPND1 ISZ RPEND     NO, P+2 RETURN
      JMP RPEND,I 
* 
*  MESSAGE FROM USER RECEIVED 
* 
MSGRC AND ?PERR     PARITY ERROR OR OVERFLOW? 
      SZA 
      JMP RCERR     YES 
      LDA EQTM1,I   FETCH RECEIVE STATUS WORD AGAIN 
      RAL,RAL       POSITION..
      AND #RCST     ..TO GET PARTIAL&TERM CHAR BITS 
      STA B         SAVE
      LDA PSW2,I    FETCH PORT STATUS 
      AND #RMST     REMOVE OLD STATUS 
      IOR B         INSERT NEW STATUS 
      STA PSW2,I    RETURN TO BED 
* 
      JSB RPEND     READ PENDING? 
      JMP MSG3      YES 
      LDA CNFG1,I   NO, IN TYPE-AHEAD MODE? 
      AND ?TAHM 
      SZA 
      JMP MSG2      YES 
      LDA @CAN      NO, CLEAR CARD OF THE DATA
      JSB CMD1W 
      JSB SCHED     SCHEDULE PROGRAM
      JMP UNSOL     EXIT
MSG2  LDA CNFG1,I   TYPE-AHEAD SCHEDULE ENABLED?
      AND ?TAHS 
      SZA 
      JSB SCHED     YES, DO SO
      LDA PSW2,I    NOW SET BIT IN STATUS TO INFORM 
      IOR ?TAH      ..USER OF THE DATA
      STA PSW2,I
      LDA EQTM1,I   SAVE MESG LEN.. 
      AND #MXFR 
      STA TAHLN,I   ..FOR LATER READ
      JMP UNSOL     AND WAIT FOR RAIN 
* 
MSG3  LDA EQTM1,I   FETCH MESG LEN
      AND #MXFR     ..SAVE LEN ONLY 
      STA EQTM3,I   .. IN EQT 
      STA TAHLN,I     
      JMP RDT3      ENTER READ ROUTINE TO UNLOAD
* 
*  RECEIVED DATA ERROR (PARITY OR OVERFLOW) 
* 
RCERR LDA @CAN      CLEAR BAD BUFFER
      JSB CMD1W 
      LDA PSW2,I    RECEIVED DATA ERROR 
      IOR ?PEOV     ..SET PARITY ERROR OR OVERFLOW BIT
      STA PSW2,I
      JSB RPEND     READ PENDING
      JMP RCPE2     YES, RETURN ZERO LEN RECORD & BAD STATUS
      JMP UNSOL     NO, CAN'T DO ANYTHING, EXIT 
* 
*  TRANSMIT BUFFER AVAILABLE
* 
BUFAV LDB EQT1,I    CHECK IF WRITE STILL PENDING (COULD HAVE BEEN OFF'D)
      SZB,RSS 
      JMP UNSOL     NO REQUEST, IGNORE
      JSB CKABT     CHECK FOR ABORT 
      LDB EXCOD,I   REQUEST A WRITE?
      SLB 
      JMP UNSOL     NO, ALSO IGNORE 
      LDA EQTM1,I   RESTORE LEN 
      JMP WRT1      YES! GO SEND SOME DATA! 
* 
B3    OCT 3 
#CMD  OCT 3400      CARD->HOST COMMAND FIELD
#DOWN EQU BIT14     EQT DOWN (BIT15=0, 14=1)
#BRKM OCT 1400      CANCEL BUFFERS ON BREAK MODE FIELD IN CNFG1 
#BRKC EQU BIT9      CANCEL ON BREAK MODE IN CNFG1 
#RCST EQU B160K     RECEIVE STATUS IN PSW2
#RMST OCT 17777     REMOVE RECEIVE STATUS IN PSW2 
?LNDN EQU BIT4      LINE DOWN BIT IN STATUS 
!LNDN OCT 177757    REMOVE LINE DOWN BIT IN STATUS
?DNDV EQU BIT15     DOWN DEVICE ON LINE FAILURE IN CONFIG WORD
?EOT  EQU BIT5      EOT BIT IN STATUS 
?PEOV EQU BIT3      PARITY ERROR / OVERFLOW BIT IN STATUS 
?PERR EQU BIT14     PARITY ERROR OR OVERFLOW BIT IN RECEIVED MESG INT 
?TAHM EQU BIT13     TYPE-AHEAD MODE ENABLED IN CONFIG1
?TAHS EQU BIT11     SCHEDULE ON TYPE-AHEAD DATA AVAIL 
?BRK  EQU BIT6      BREAK RECEIVED BIT IN STATUS
?UNSL EQU BIT9      UNSOLICITED INTERRUPT BEING PROCESSED FLAG IN PSW 
.$UP  DEF $UPIO+0 
* 
* 
*  LOW LEVEL UTILITY FUNCTIONS
* 
* 
*  PROGRAM SCHEDULER
* 
SCHED NOP           >> PROGRAM SCHEDULER << 
      LDA EQT1      SYSTEM TTY? 
      CPA SYSTY 
      ISZ OPATN     YES, TAP ON SHOULDER
      CPA SYSTY     
      JMP SCHED,I   AND RETURN
* 
      LDA PSW2,I    SCHED ENABLED?
      AND ?ENAB 
      SZA,RSS 
      JMP SCHED,I   NO, IGNORE
      LDB PGMAD,I   REGULAR PROG, GET ID SEG ADDR 
      SSB           ANY SET?
      JMP SCHED,I   NO, IGNORE
      STB IDADR 
      LDA EQT4      SET A(EQT WORD 4) 
      STA BVAL
      JSB $LIST     TELL SYSTEM ABOUT IT
      OCT 601 
IDADR NOP 
BVAL  NOP 
      JMP SCHED,I   RETURN
* 
*  WAIT FOR SOLICITED INTERRUPT 
* 
WAIT  NOP           WAIT FOR SOLICITED INTERRUPT
      LDA WAIT      SAVE RETURN ADDR... 
      STA LEVL1,I   ..IN EQT AS DESTINATION OF NEXT INT 
      LDA #CTMR     SET TIMEOUT FOR CARD COMMAND
      STA EQT15,I 
WAIT1 LDA I.FLG     ENTERED AT I.???? 
      SZA 
      JMP RTN       YES P+1 RETURN
      LDA DMFLG     RETURN DMA REQUESTED? 
      SZA,RSS 
      JMP WAIT3     NO
      STA EXCMD     YES, SET A=6
      ISZ CM00      ..AT P+3
WAIT3 ISZ CM00
* 
RTN   LDA EXCMD     GET EXIT COMMAND
      LDB XLOG      AND XMIT LOG
      JMP CM00,I    ...POOF...! 
* 
#CTMR DEC -300      TIMEOUT FOR CARD COMMANDS (3 SEC) 
* 
************************************************************************
*  WAIT FOR UNSOLICITED INTERRUPT:  IF ANY OTHER EQT NEEDS
*  CARD ACCESS GIVE CARD A NOP TO CAUSE INTERRUPT.  PRE-DRIVER
*  WILL ENTER DRIVER ON THAT EQT TO CONTINUE REQUEST
************************************************************************
* 
UNSOL LDA EQT1,I    ANY REQUEST PENDING?
      SZA           IF NOT, NO TIMER
      LDA DVTMO,I   SET UP DEVICE DRIVER TIMEOUT
      STA EQT15,I 
      LDA I.FLG     INITIATE ENTRY??
      SZA           ..POSSIBLY FROM READ
      JMP RTN       YES! DON'T TOUCH ANYTHING - LEAVE 
      LDA PSW,I     DO WE HAVE THE CARD?
      SSA,RSS 
      JMP WAIT1     NO, EXIT
      LDA NXTEQ,I   YES, GOING TO RESTART SAME EQT? 
      SSA,RSS 
      ISZ CM00      NO, SET FOR CONTINUATION EXIT 
      LDA DMFLG     RETURN DMA? 
      SZA,RSS 
      JMP UNSL3     NO
      STA EXCMD     YES, SET A=6
      ISZ CM00      ..AT P+3
* 
UNSL3 LDA .UNSL     SET INTERRUPT DESTINATION   
      STA LEVL1,I   ..IN EQT
      JSB NBUSY     CLEAR BUSY BIT
      LDB NXTEQ,I   CHECK EQT QUEUE:
      SSB           EQT QUEUED'D ON ITSELF? 
      JMP UNSL4     YES 
      SZB,RSS       NO, ANYBODY ELSE WAITING? 
      JMP UNSL1     NO
      CLA           YES, CLEAR EQT Q
      STA NXTEQ,I 
      JSB STINT     SET EQT OWNED THERE 
      LDA @NOP      KICK CARD TO WAKE UP
UNSL2 JSB OUT1      SEND TO CARD
      JMP RTN       AND EXIT; INT WILL CAUSE SWITCH TO NEW EQT
UNSL1 LDA @ENAB     NOBODY WAITING, ALLOW CARD TO INTERRUPT 
      JMP UNSL2     ..ON ANY CHANNEL
* 
UNSL4 RBL,CLE,ERB   REMOVE WAITING BIT
      STB NXTEQ,I 
      JMP Q5        ..AND RE-START SUSPENDED TASK 
* 
.UNSL DEF UNSLP     A(UNSOLICITED INTERRUPT PROCESSOR)
* 
*  SET B REGISTER INTO INTERRUPT TABLE FOR THIS CARD.  THIS 
*  ROUTINE IS USED TO SET UP FOR NEXT CARD INTERRUPT IN RESPONSE
*  TO A HOST->CARD COMMAND. B REG SHOULD CONTAIN THE EQT FOR WHICH
*  THE INTERRUPT IS TO BE DIRECTED. 
* 
STINT NOP           SET B-REG INTO INTBL ENTRY FOR THIS CARD
      LDA SCODE 
      ADA DM6       FIND ENTRY
      ADA INTBA 
      STB A,I 
      ADB #PSW      SET CARD BUSY FLAG IN THIS EQT
      LDA B,I       FETCH PSW 
      IOR ?BUSY 
      STA B,I       CARD NOW OWNED BY THIS GUY
      JMP STINT,I 
* 
*  ROUTINE TO CHECK FOR DEFERRED ABORT (I/O CLEAR IN PROGRESS)
*   
*    MUST BE CALLED BY ANY UNSOLICITED INTERRUPT PROCESS WHICH
*    DOES NOT EXIT THROUGH 'UNSOL'.  DO NOT CALL IF NO REQUEST IS 
*    CURRENTLY PENDING AND DON'T CALL MORE THAN ONCE! 
* 
CKABT NOP           CHECK FOR ABORTS
      LDA PSW,I     
      XOR ?NABT     REMOVE NO-ABORT FLAG
      STA PSW,I     ..SINCE THE COAST IS CLEAR NOW
      AND ?DABT     DEFERRED ABORT? 
      SZA,RSS 
      JMP CKABT,I   NO, EXIT
      XOR PSW,I     CLEAR DEFERRED ABORT STATUS 
      STA PSW,I     ..INCASE DEV DVR WANTS ANOTHER REQUEST
      JMP COMPL     COMPLETE REQUEST
* 
?DABT EQU BIT14     DEFERRED ABORT BIT IN PSW 
* 
************************************************************************* 
*   DEVICE DRIVER COMMAND COMPLETE:  CALL DEVICE DRIVER WITH RESULTING
*   STATUS AND XMIT LOG TO REQUEST FURTHER INSTRUCTIONS.  >>>ALL<<< CMDS
*   MUST EXIT THROUGH THIS ROUTINE WHEN COMPLETE. 
************************************************************************* 
* 
COMPL JSB DVDVR     CALL DEVICE DRIVER
      CPA #NWRQ     NEW REQUEST TO DO?
      JMP I.6       YES, GO EXECUTE 
      STA EXCMD     NO, SAVE EXIT COMMAND 
      STB XLOG      ..AND XMIT LOG
CMPL2 LDA EXCMD     FETCH EXIT COMMAND
      LDB DMFLG     RETURNING DMA?? 
      SZB 
      IOR BIT15     YES, SET BIT TO TELL RTE TO RELEASE IT
      STA EXCMD 
      LDA PSW,I     GOT CARD? 
      SSA 
      JMP UNSL3     YES, SEE IF ANYONE ELSE WANTS CARD
      JMP RTN       NO, JUST EXIT 
* 
B5    OCT 5 
#NWRQ EQU B5        NEW REQUEST CMD FROM DEVICE DRIVER
* 
*  SEND A ONE WORD COMMAND TO CARD, A-REG = RETURN STATUS 
*  ON EXIT
* 
CMD1W NOP           SEND A ONE WORD COMMAND TO CARD 
      IOR KEY       COMBINE WITH KEY
      LDB CMD1W     FETCH RETURN ADDR 
      JMP *+3 
CMD1X NOP           SEND ONE WORD CMD TO CARD, NO KEY 
      LDB CMD1X     GET RETURN ADDR 
      STB LEVL2,I   SAVE IN EQT 
      JSB OUT1      SEND CMD TO CARD
CMD1C JSB WAIT      WAIT FOR INTERRUPT
      JSB LIA       FETCH RESPONSE, IF ANY
      LDB LEVL2,I   GET RETURN ADDR 
      JMP B,I       ..AND GO
* 
*  SEND 2 WORD COMMAND TO CARD (A/B). A-REG = RETURN STATUS 
*  ON EXIT
* 
CMD2W NOP           SEND 2 WORD COMMAND TO CARD 
      IOR KEY 
      STB EQTM1,I   SAVE 2ND WORD IN EQT
      LDB CMD2W 
      STB LEVL2,I   SAVE RETURN ADDR IN EQT 
      JSB OUT1      SEND 1ST WORD 
      JSB SFCLP     TRY TO WAIT FOR FLAG
      JSB WAIT      NOT IN TIME, EXIT TILL IT COMES 
      LDA EQTM1,I   SEND 2ND WORD 
      JSB OUT2
      JMP CMD1C     WAIT, FETCH RESPONSE, AND EXIT
* 
*  SEND 2 WORD COMMAND TO CARD BUT DON'T CLEAR FLAG AFTER SECOND WORD 
*  THIS ROUTINE IS USED TO SEND READ OR WRITE COMMANDS BEFORE DMA XFERS 
* 
CMD2D NOP           SEND 2 WORD CMD W/O CLEARING LAST FLAG
      IOR KEY       COMBINE CMD WITH KEY
      STB EQTM1,I   SAVE 2ND WORD FOR LATER 
      LDB CMD2D     SAVE RETURN ADDR
      STB LEVL2,I 
      JSB OUT1      SEND FIRST WORD 
      JSB SFCLP     TRY SFC LOOP
      JSB WAIT      NOT IN TIME, LONG WAIT
      LDA EQTM1,I   2ND WORD..
      JSB OUT2      ..SEND TO CARD BUT DONT WAIT FOR FLAG!!!!!! 
      LDA PSW,I     SET XFER IN PROGRESS BIT
      IOR ?XFR      ..IN PSW
      STA PSW,I     FOR ABORT PROCESSING
      LDB LEVL2,I   AND RETURN WITH FLAG STILL SET
      JMP B,I       ..FOR NEXT DMA TRANSFER 
* 
*  ROUTINE TO WAIT FOR THE CARD FLAG FOR A SHORT TIME.  THIS ROUTINE
*  IS CALLED BETWEEN EACH WORD OF AN LIA/OTA DATA TRANSFER AND BETWEEN
*  THE FIRST AND SECOND WORDS OF A TWO WORD HOST->CARD CMD. 
*  RETURNS:  P+1 TIMEOUT, P+2 GOT FLAG
* 
SFCLP NOP           SKIP-FLAG LOOP WITH TIMEOUT 
      LDA #SFLC     DO WAIT LOOP
SFC01 SFC SC        CARD READY FOR 2ND WORD YET?
      JMP CLF02     YES, FINALLY! 
      ISZ A         TIRED OF WAITING? 
      JMP SFC01     NO
      JMP SFCLP,I   TIMEOUT, P+1 RETURN 
CLF02 CLF SC        CLEAR CARD FLAG 
      ISZ SFCLP     SET P+2 RETURN
      JMP SFCLP,I   AND RETURN
* 
*  THIS PROCESS REQUESTS ACCESS TO CARD.  IF CARD IS BUSY 
*  PROCESS MUST BE SUSPENDED UNTIL FREE.  UNSOL/COMPL WILL
*  AWAKEN PROCESS IF SUSPENDED HERE.  THIS ROUTINE ALSO 
*  TURNS OFF CARD UNSOLICITED INTERRUPTS BEFORE EXIT. 
* 
QUEUE NOP           REQUEST ACCESS TO CARD
      LDA QUEUE     SAVE RETURN ADDR
      STA LEVL3,I   ..IN EQT
      LDA SCODE 
      ADA DM6       CARD BUSY?
      ADA INTBA     
      LDB A,I 
      ADB #PSW      CHECK BUSY BIT IN HIS PSW 
      LDA B,I 
      SSA           WELL? 
      JMP Q6        CARD IS BUSY, MAY HAVE TO WAIT
      LDB EQT1      NOT BUSY, MARK IT ..
      JSB STINT     ..OWNED HERE
      CLA           CLEAR WAITING CHAIN 
      STA NXTEQ,I   
      LDA @SHUP     ..AND TELL CARD TO SHUDDUP
      JSB CMD1X 
      SZA           CARD STILL TALKING??
      JSB WAIT      YES, BE PATIENT 
* 
Q5    JSB SBUSY     SET EQT BUSY ON CARD
      LDA EQT1,I    REQUEST STILL PENDING?? 
      RAL,CLE,ERA   ..REMOVE SYSTEM CLEAR BIT 
      SZA,RSS         
      JMP CMPL2     NO, COMPLETE NOW! 
      LDA LEVL3,I   RETURN
      JMP A,I 
* 
Q6    CPB PSW       OUR EQT?
      JMP Q7        YES, CHECK FURTHER
* 
*  PUT THIS EQT ON QUEUE WAITING FOR CARD ACCESS
* 
      INB           POINT TO NEXT EQT LIST
Q3    LDA B,I       GET POINTER 
      AND !SPND     REMOVE SUSPENDED-ON-SELF BIT
      SZA,RSS       END OF LIST?
      JMP Q4        YES, LINK IN
      CPA EQT1      ALREADY ON LIST?
      JMP Q8        YES, DON'T GET ALL TANGLED UP!
      STA B 
      ADB #NEQ      NO, GET ITS LINK
      JMP Q3        LOOP TO END OF LIST 
Q4    STA NXTEQ,I   LINK THIS EQT IN LIST 
      LDA EQT1
      IOR B,I       OR IN SUSPEND BIT, IF ANY 
      STA B,I 
      LDA .QRTN     SET RETURN POINT..
      STA LEVL1,I   ..FOR SUSPEND 
Q8    CLA 
      STA EXCMD 
      JMP WAIT1     EXIT FOR A WHILE
* 
Q7    AND ?UNSL     UNSOLICITED INTERRUPT BEING PROCESSED?
      SZA,RSS 
      JMP QUEUE,I   NO, WE'VE ALREADY GOT THE CARD, GO USE IT!
      LDA NXTEQ,I   YES, MUST WAIT FOR UNSOLICITED PROCESS TO FINISH
      IOR ?SPND     ..SO SET SUSPEND-ON-SELF BIT..
      STA NXTEQ,I   ..FOR UNSOL/COMPL TO WAKE US UP.
      JMP Q8        HANG IN LIMBO........ 
* 
.QRTN DEF Q5        RETURN POINT AFTER SUSPEND
B5.7S OCT 77777     5 SEVENS
?SPND EQU BIT15     SUSPEND TASK ON OWN EQT BIT IN NXTEQ
!SPND EQU B5.7S     REMOVE SELF-SUSPEND BIT IN NXTEQ
#CBSY OCT 36377     REMOVE BUSY,NO-ABORT,D-ABORT & UNSOL INT BITS IN PSW
* 
*  SET BUSY BIT IN PSW
* 
SBUSY NOP           SET BUSY BIT IN PSW 
      LDA PSW,I 
      IOR ?BUSY 
      STA PSW,I 
      JMP SBUSY,I 
* 
*  CLEAR BUSY, NO-ABORT, DMA ABORT, AND UNSOLICITED INT BITS IN PSW 
* 
NBUSY NOP           CLEAR BUSY AND UNSOLICITED BITS IN PSW
      LDA PSW,I     
      AND #CBSY 
      STA PSW,I 
      JMP NBUSY,I 
* 
*  CKIO:  THIS CHANNEL HAS RECEIVED AN ABORT REQUEST OR TIMEOUT FROM SYSTEM:
* 
*   IF CHANNEL IS USING CARD, ABORT MUST BE DEFERRED UNTIL INTERRUPT
*   IS RECEIVED.  ABORTS DURING DATA TRANSFERS ALSO REQUIRE SPECIAL 
*   PROCESSING TO MAINTAIN HOST-CARD SYNCHRONIZATION.  IF NO ABORT
*   PROCESSING IS NEEDED, P+1 RETURN WILL BE TAKEN.  IF SOME ACTION 
*   NEEDS TO BE TAKEN, IT WILL BE HANDLED HERE AND THE REQUEST
*   COMPLETED.
* 
CKIO  NOP           CHECK I/O USAGE 
      LDA PSW,I     GOT CARD? 
      SSA,RSS 
      JMP CKIO,I    NO, P+1 RETURN
      AND ?XFR      DATA XFER IN PROGRESS?
      SZA,RSS 
      JMP CKIO3     NO
      XOR PSW,I     YES, CLEAR BIT
      STA PSW,I     ..SINCE XFER IS ABOUT TO DIE
      LDA @DABT     SEND ABORT CMD TO BACKPLANE 
      JSB OUT2      ..TO SET BPRDY
      JSB SFCLP     WAIT FOR CARD DMA TO EAT IT 
      JSB WAIT      NOT HUNGRY? WAIT FOR TIMEOUT
STC04 STC SC,C      SET CONTROL TO WAKE UP CARD CMD PROCESSOR 
CKIO4 JSB WAIT      WAIT FOR ABORT ACKNOWLEGE 
      JMP COMPL     REQUEST NOW DEAD
* 
CKIO3 LDA PSW2,I    TIMEOUT?? 
      AND ?TO 
      SZA 
      JMP RESET     YES, CARD IS DEAD, RESET
      LDA PSW,I     NO-ABORT BIT SET? 
      AND ?NABT 
      SZA,RSS 
      JMP CKIO5     NO, GO CHECK DMA WAIT 
* 
      LDA PSW,I     YES, SET DEFERRED ABORT 
      IOR ?DABT 
      STA PSW,I 
      JMP WAIT1     AND EXIT. ABORT WILL BE FINISHED LATER
* 
RESET LDA @RST      THE CARD IS DEAD!!!!
      JSB CMD1X     ...LONG LIVE THE CARD!
      JMP CMPL2     EXIT WITHOUT CALLING DEVICE DRIVER
* 
CKIO5 LDA EQT3,I    WERE WE WAITING FOR DMA?? 
      SSA           ..(CHECK ALLOCATION BIT)
      JMP IOCL2     YES! PRETEND WE DIDNT HAVE CARD 
      JMP CKIO4     NO, WAIT FOR UP COMMING INTERRUPT 
* 
****************************************************
*     D V D V R    DEVICE DRIVER INTERFACE MODULE  *
*                                                  *
*    CALLS DEVICE DRIVER SET IN PORT CONFIGURATION *
*  WORD (CNFG1).  DEV DVR SETS UP A SERIES OF EXEC *
*  REQUESTS IN EQT EXT FOR THE INTERFACE DRIVER    *
*  (THIS THING) TO EXECUTE.  A DEFAULT DEVICE DVR  *
*  IS PROVIDED FOR SIMPLE REQUESTS.                *
****************************************************
* 
DVDVR NOP           ROUTINE TO CALL DEVICE DRIVER 
      LDA CNFG1,I   FETCH DEVICE DRIVER # 
      AND #LDVN 
      SZA,RSS       DEFAULT?
      INA           YES, SET TO 1 (=DEFAULT DEVICE DRIVER#) 
      ADA DM1       SUBTRACT 1
      LDB .DEFD     FETCH A(DEFAULT DEVICE DRIVER)
      SZA,RSS       DEFAULT?
      JMP DVDV2     YES 
      ADA .DVTB     NO, VECTOR INTO DEVICE DRIVER ADDRESS TABLE 
      LDB A,I 
* 
DVDV2 STB TMP       SAVE A(WANTED DEVICE DVR) 
      DLD EQT6,I    COPY EXEC PARAMS TO EXTENT FOR DEVICE DRIVER
      DST EXCOD,I 
      LDA EQT8,I
      STA BUFLN,I 
      CLA           SET DEFAULT PHYSICAL XFER LEN 
      STA DVTMO,I 
      LDA PSW2,I    COPY STATUS TO EQT5 FOR DEV DVR 
      AND #STAT 
      STA B 
      LDA EQT5,I    
      AND #RSTA 
      IOR B         ..MERGE 
      STA EQT5,I
      LDA PSW2,I    REMOVE TO,PE,EOT BITS FOR NEXT TIME 
      AND #CLFC 
      STA PSW2,I      
      LDA I.FLG     ENTERED AT I. FLAG
      RAR 
      IOR DVTMO     MERGE I. FLAG WITH DEVICE DRIVER EQT EXTENT 
      LDB XLOG      FETCH PREVIOUS XMIT LOG, IF ANY 
      JSB TMP,I     CALL DEVICE DRIVER!!!!! 
* 
      STA DVCMD,I   SAVE DEVICE DRIVER CMD
      LDA DVTMO,I   MOVE PHYSICAL RECORD LEN..
      STA EQTM3,I   ..TO A SAFE PLACE IN CASE OF READ 
      STB DVTMO,I   SAVE DEVICE DRIVER TIMEOUT
      LDA DVCMD,I   RESTORE CMD FOR EXIT
      AND #XCMD     STRIP TO EXIT COMMAND 
      JMP DVDVR,I   ..AND RETURN
* 
.DVTB DEF $DVTB+0   A(DEVICE DRIVER ADDRESS TABLE)
.DEFD DEF DEFDD     A(DEFAULT DEVICE DRIVER)
* 
#STAT EQU B377      USER STATUS FIELD IN PSW2 
#RSTA EQU DM255     REMOVE STATUS FIELD IN EQT5 
* 
*  DEFAULT DEVICE DRIVER:  PASSES ALL USER REQUESTS DIRECTLY TO 
*  INTERFACE DRIVER FOR EXECUTION (OR WHATEVER) 
* 
DEFDD NOP           DEFAULT DEVICE DRIVER 
      SSA           NEW REQUEST?? 
      LDB EQT14,I   YES, SET TIMER
      CLA           START/COMPLETE REQUEST
      JMP DEFDD,I   ..RETURN TO INTERFACE DRIVER
* 
?BUSY EQU BIT15     CARD BUSY ON THIS EQT BIT IN PSW
#PSW  DEC 10        PSW OFSET FROM EQT1 
#NEQ  DEC 11        NXTEQ OFSET FROM EQT1 
#DMTO DEC -20       -# 10'S MS TO WAIT FOR DMA
* 
*  -CHARS/+WORDS TO +CHAR CONVERSION
*   
*    INPUT : A = LEN FROM BUFLN 
*    OUTPUT: A = LEN IN CHARACTERS
* 
TOCHR NOP           -CHAR/+WORD -> +CHAR CONVERSION 
      SSA           ALREADY CHARS?
      JMP TOCH1     YES 
      CLE,ALS       NO,CONVERT
      JMP TOCHR,I   RETURN
TOCH1 CMA,INA       MAKE POS
      JMP TOCHR,I   ..THEN RETURN 
* 
*  +CHAR TO -WORD CONVERSION,  USED TO INIT DCPC
* 
*   INPUT : A = + CHARS 
*   OUTPUT: A = -WORDS
* 
TOWRD NOP           +CHAR -> -WORD CONVERSION 
      INA           ROUND 
      CLE,ERA       CONVERT 
      CMA,INA       MAKE NEG
      JMP TOWRD,I 
* 
*  SET A TO MINIMUM OF (A,B)  
* 
MIN   NOP           SET A TO MIN(A,B) A,B > 0 
      STA TMP1
      CMA,INA       ..DO A "#$%$ SUBTRACT 
      ADA B 
      SSA,RSS       WHO WON?
      LDB TMP1      A WAS SMALLER 
      STB A 
      JMP MIN,I     RETURN
* 
********************************
*  CARD I/O ROUTINES
********************************
OUT1  NOP           OUTPUT 1ST WORD OF CMD TO CARD
OTA01 OTA SC        SEND..
STC01 STC SC,C      ..WAKE UP 
      JMP OUT1,I    ..AND RETURN
* 
OUT2  NOP           OUTPUT WORD TO CARD 
OTA02 OTA SC,C
      JMP OUT2,I
* 
LIA   NOP           READ WORD FROM CARD 
CLF03 CLF SC        FIRST CLEAR FLAG
LIA01 LIA SC        ..THEN READ DATA (NEED THIS ORDER FOR @SHUP CMD)
      SSA           POWER FAILURE?
      JMP PFAIL     YES, PANIC! 
      JMP LIA,I     NO, RETURN
* 
*  POWER FAIL RECOVERY
* 
*    AT THIS POINT THE SYSTEM HAS RE-STARTED A REQUEST TO THE CARD
*    AND IN THE PROCESS OF TALKING TO THE CARD THE CARD HAS RECEIVED
*    A COMMAND FOR WHICH THERE IS NO KEY, I.E. THAT PORT HAS NOT BEEN 
*    RECOVERED.  THE SIGN BIT OF THE RESPONSE TO A COMMAND WAS SET  
*    AND WE ENDED UP HERE.  THIS ROUTINE RECOVERS THAT CHANNEL TO THE 
*    STATE IT WAS BEFORE POWER FAILED, EXCEPT THAT SINCE THE CARD'S 
*    INPUT BUFFER HAS BEEN WIPED ANY BINARY TRANSFER WILL BE TRUNCATED
*    AT THE NEXT CHAR (BINARY RECORD LEN SET TO 1).  OTHERWISE THE REQUEST
*    MAY NEVER COMPLETE.  THE REQUEST WHICH THE CARD REPORTED FAILURE 
*    ON IS THEN RESTARTED FROM THE BEGINNING AS IF THE USER HAD JUST
*    ISSUED IT.  NOTE THAT ONLY THIS ONE PORT IS RECOVERED.  WHEN AUTOR 
*    GETS AROUND TO IT THE OTHER PORTS WILL BE RECOVERED. 
* 
PFAIL LDA PSW2,I    PORT BEEN INITIALIZED?? 
      AND ?KEY
      SZA,RSS 
      JMP CMPL2     NO!!! IGNORE WHOLE REQUEST
      LDB PID,I     GET THIS GUY'S ID 
      LDA @SKEY     ..AND SEND TO CARD
      JSB CMD2W 
      LDB CNFG2,I   ..CONFIG WORD 2 
      LDA @CNF2 
      JSB CMD2W 
      LDA PSW,I     RESTORE READ CONFIGURATION
      AND #MRCN     ...FOR THE MUX CARD 
      STA EQTM2,I 
      CLA,INA       SET 1 CHAR LEN..
      STA EQTM3,I   ...INCASE OF BINARY 
      JSB STREC 
      LDA PSW2,I    SET POWER-FAILED BIT IN STATUS
      IOR ?PF 
      STA PSW2,I
      JMP I.6       RE-START REQUEST
* 
?PF   EQU BIT7      POWER FAILED BIT IN STATUS
* 
*  SETUP I/O INSTRUCTIONS, EQT POINTERS AND PORT KEY
* 
SETUP NOP           SET I/O INSTRUCTIONS & EQT POINTERS 
      STA SCODE     SAVE SELECT CODE
      CLA           SET DEFAULT EXIT COMMAND
      STA EXCMD 
      STA XLOG
      STA DMFLG     CLEAR RETURN-DMA-NEXT-EXIT FLAG 
      STA I.FLG 
      STA PFFLG 
* 
      LDA EQT1      MAKE PORT KEY 
      LDB EQTA
      CMB,INB       MAKE NEG
      ADA B         -> RELATIVE ADDR
      CLB 
      DIV D15       -> EQT NO. (EQT1=0, EQT2=1, ETC)
      STA KEY 
* 
      LDA SCODE 
      LDB .IOIN     MAKE ALL THOSE I/O INSTRUCTIONS 
      JSB SETEM 
* 
      LDA EQT13,I   EQT PTRS SETUP? 
      CPA EQT16 
      JMP SETUP,I   YES, RETURN 
      LDB #EXSZ     ..LEN OF EXTENT 
      STB TMP 
      LDB .EQ16     A(1ST EXTENT PTR) 
SET2  STA B,I       SET.. 
      INA 
      INB           BUMPITY BUMP
      ISZ TMP       DONE? 
      JMP SET2      NO
      JMP SETUP,I   YES, RETURN 
* 
*  ROUTINE TO CONFIGURE I/O INSTRUCTIONS.  THE FIRST ENTRY IN 
*  THE TABLE IS COMPARED TO WHAT IT SHOULD BE.  IF ANY DIFFERENCES
*  ARE NOTED, THEY ARE EXCLUSIVE-OR'D INTO EACH INSTRUCTION.
* 
*   INPUT: A = WANTED SELECT CODE 
*          B = ADDRESS OF TABLE OF DEF'S TO I/O INSTS, TERMINATED 
*              BY A ZERO ENTRY
* 
SETEM NOP           SET I/O INSTRUCTIONS
      STA TMP1      SAVE WANTED SELECT CODE 
      STB TMP       SAVE A(INST ADDRESS TABLE)
      LDA B,I       FETCH FIRST 
      LDA A,I       ..INSTRUCTION 
      AND #SCOD     GET JUST SELECT CODE
      XOR TMP1      FIND DIFFERENCES
      SZA,RSS       ANY?
      JMP SETEM,I   NO, EXIT
      STA TMP1      SAVE
* 
SETM2 LDB TMP,I     GET A(INSTRUCTION)
      SZB,RSS       DONE? 
      JMP SETEM,I   YES 
      LDA B,I       FETCH INSTRUCTION 
      XOR TMP1      UPDATE
      STA B,I       RETURN
      ISZ TMP       NEXT! 
      JMP SETM2     LOOP FOR A WHILE
* 
.IOIN DEF *+1       CARD I/O INSTRUCTIONS 
      DEF OTA01 
      DEF OTA02 
      DEF OTA06 
      DEF LIA01 
      DEF LIA02 
      DEF STC01 
      DEF STC04 
      DEF SFC01 
      DEF CLF02 
      DEF CLF03 
      OCT 0         END OF CARD I/O 
* 
* 
* MORE OF THOSE $%!"#% CONSTANTS: 
* 
TMP   NOP 
TMP1  NOP 
XLOG  NOP 
EXCMD NOP 
SCODE NOP 
I.FLG NOP           ENTERED AT I.=1; C.=0 
KEY   NOP 
DMFLG NOP           RETURN-DMA-NEXT-EXIT FLAG (0=NO, 6=YES) 
PFFLG NOP           ENTERED AFTER POWER-FAIL (0=NO, NOT=YES)
* 
*  ONE WORD CARD COMMANDS 
* 
@NOP  OCT 40000     0  NOP
@ACK  OCT 42000     4  ACKNOWLEGE 
@ENAB OCT 41000     2  ENABLE UNSOLICITED INTERRUPT 
@SHUP OCT 41401     3  DISABLE UNSOLICITED INTERRUPT (SHUDDUP)
@DABT OCT 41402     3  ABORT DMA TRANSFER 
@CAN  OCT 42400     5  CANCEL RECEIVE BUFFER
@CANA OCT 43000     6  CANCEL ALL RECEIVED BUFFERS
@OPL1 OCT 44000     8  ??????? OPEN LINE TYPE 1 
@OPL2 OCT 44400     9  ??????? OPEN LINE TYPE 2 
@CLOS OCT 45000     10 ??????? CLOSE LINE 
@GMOD OCT 45400     11 ??????? FETCH MODEM LINES
@RST  OCT 40400     1  RESET CARD 
* 
*  TWO WORD CARD COMMANDS 
* 
@SEL  OCT 140400    1 REQUEST TRANSMIT
@SKEY OCT 141400    3 SET PORT ID TO KEY
@CNF2 OCT 143000    6 ?????? SET CONFIG WORD  
@RCTP OCT 142000    4 SET RECEIVE TYPE
@SBFL OCT 142400    5 SET RECEIVE CHAR COUNT LIMIT
@READ OCT 143400    7 FETCH RECEIVE DATA
@WRT  OCT 141000    2 WRITE BUFFER TO CARD
@SMOD OCT 146000    12 ?????? SET MODEM LINES 
* 
.EQ16 DEF EQT16 
      ORB 
JP00  DEF PM00+0    DIRECT LINK TO PRE-DRIVER 
JSB   JSB JP00,I    CREATE LINK TO PRE-DRIVER 
      END 
                                                        