Trailing-Edge
-
PDP-10 Archives
-
BB-BT99S-BB_1990
-
10,7/mon/scnser.mac
There are 14 other files named scnser.mac in the archive. Click here to see a list.
TITLE SCNSER - TERMINAL SCANNER SERVICE V1067
SUBTTL R CLEMENTS/RCC/DAL/PMW/EJW/WRS/RCB 31-OCT-89
SEARCH F,S,DEVPRM
IFN FTNET,<SEARCH NETPRM>
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VSCNSR,1067
SCNSER::ENTRY SCNSER
; TABLE OF CONTENTS FOR SCNSER
;
;
; SECTION PAGE
; 1. PARAMETER AND CONFIG DEFINITIONS.......................... 3
; 2. DATA STRUCTURES
; 2.1 LINTAB AND DSCTAB................................. 5
; 2.2 LINE DATA BLOCK (LDB)............................. 6
; 2.3 TTY DEVICE DATA BLOCK (DDB)....................... 19
; 3. TRANSMIT INTERRUPT ROUTINE................................ 20
; 4. RECEIVE INTERRUPT ROUTINE................................. 36
; 5. KI10 CONSOLE TERMINAL SERVICE............................. 70
; 6. KS10 CTY AND KLINIK TERMINAL SERVICE...................... 71
; 7. FILLERS AND SIMULATION ROUTINES........................... 72
; 8. FILL CHARACTER DATA....................................... 81
; 9. TIMING ROUTINE............................................ 84
; 10. CHUNK HANDLERS............................................ 97
; 11. CHUNK HANDLERS
; 11.1 ALLOCATION AND DEALLOCATION....................... 100
; 11.2 CLEAR BUFFERS..................................... 102
; 12. UUO LEVEL ROUTINES FOR BUFFERED I/O....................... 103
; 13. DDT MODE CALLI'S.......................................... 110
; 14. TTCALL AND TRMOP.
; 14.1 TTCALL DISPATCH................................... 111
; 14.2 OUTCHR AND IMAGE OUTCHR........................... 113
; 14.3 OUTSTR AND RESCAN................................. 114
; 14.4 SKPINL AND SKPINC................................. 115
; 14.5 GETLIN............................................ 116
; 14.6 SETLIN, INCHSL, INCHWL, INCHRS & INCHRW........... 117
; 14.7 TRMNO. UUO........................................ 118
; 14.8 TRMOP. DISPATCH................................... 119
; 14.9 SKIPS AND CLEARS.................................. 131
; 14.10 TRMOP. I/O........................................ 132
; 14.11 TRMOP. I/O SUBROUTINES............................ 134
; 14.12 TRMOP. DATASET FUNCTIONS.......................... 135
; 14.13 TYPE INTO TTY ON BEHALF OF A USER................. 139
; 14.14 MIC -- SET/CLEAR LDBMIC......................... 140
; 14.15 MIC -- RETURN MIC STATUS........................ 141
; 14.16 MIC -- READ ERROR RESPONSE TEXT................. 142
; 14.17 MIC -- LOG ALL TERMINAL OUTPUT.................. 143
; 14.18 MIC -- MISCELLANEOUS MIC SUBROUTINES............ 144
; 15. SUBROUTINES FOR I/O....................................... 148
; 16. COMMAND LEVEL ROUTINES.................................... 156
; 17. SUBROUTINES FOR COMCON OR UUO LEVEL....................... 171
; 18. CTY ROUTINES.............................................. 175
; 19. DDB ROUTINES.............................................. 178
; 20. ROUTINES FOR PTY.......................................... 194
; 21. IMPURE DATA............................................... 200
SUBTTL PARAMETER AND CONFIG DEFINITIONS
STTYBF==:20
;DATASET TRANSACTION CODES FROM SCNSER TO/FROM XXXINT'S
DSTOFF==:1 ;DSCREC OR DSCTYP
DSTON==:2 ;DSCREC OR DSCTYP
DSTRNG==:3 ;DSCREC
DSTREQ==:3 ;DSCTYP
DSTINI==:4 ;TO AND FROM. SENDING COMPUTER WAS RESTARTED.
DSTSTS==:5 ;REQUEST DATA SET STATUS
DSTCRQ==:10 ;CALL REQUEST TO MODEM. WANT TO DIAL OUT.
DSTPND==:20 ;PRESENT NEXT DIGIT, TO AND FROM.
; NOTE - TO MODEM, 20-37 MEAN SEND DIGIT N-20
; WHERE DIGIT 17 MEANS END OF NUMBER (TO BOTH HARDWARE AND SOFTWARE)
; AND DIGIT 16 MEANS 5-SECOND DELAY TO SOFTWARE, FOR SECOND DIAL TONE.
DSTNAC==:40 ;NO ACTION -SYSINI (ONLY USER OF DSTREQ) SHOULD
; NOT MODIFY LINE STATUS CODES (CARRIER ON/OFF)
;LINE CONTROL TRANSACTION CODES
LNTEHC==:1 ;ENABLE HUNG CHECK
LNTDHC==:2 ;DISABLE HUNG CHECK
ND STDALT,033 ;VALUE OF STANDARD ALTMODE
ND VTAB,10 ;VERTICAL TAB SPACING (MUST BE POWER OF 2)
ND RCQMAX,^D32 ;RECINT QUEUE SIZE
ND FTMLOG,-1 ;NON-ZERO TO INCLUDE MIC LOG CODE
IMGTIM==:^D10 ;MUST FIT IN LDPTIM FIELD. HUNG TIME FOR IMI
SUBTTL DATA STRUCTURES -- LINTAB AND DSCTAB
;DATA STRUCTURES IN COMMON
;LINTAB: BLOCK # OF LINES INCLUDING SCANNER,CTY AND PTY'S
;EACH WORD= FULLWORD LDB ADDRESS
;DSCTAB: BLOCK # OF DATASETS NEEDING TIMING
; RH= LINKED TERMINAL LINE NUMBER FOR DATA
; LH= TIME IN 14-17, ALSO DSCHWC,DSCSWC,DSCFAI
DSCHWC==:400000 ;WHEN LAST HEARD FROM, THE HARDWARE CARRIER WAS ON
DSCSWC==:200000 ;THE SOFTWARE CONSIDERS THE CARRIER TO BE ON OR
; TO BE COMING ON IMMINENTLY
DSCFAI==:100000 ;CARRIER WENT OFF, BUT MAY BE BRIEF FAILURE
; EXCEPT FOR GPO 2B MODEM, MUST QUIT IMMEDIATELY
DSCNCR==:040000 ;NEW CARRIER FLAG, ON FOR FRACTION OF SECOND FOR CLOCK SYNC
DSCBLI==:020000 ;BLIND FLAG - IGNORE EVERYTHING FOR 1 SEC AFTER CARRIER ON
DSCDLW==:010000 ;DIALLER WAIT. WAITING FOR RESULTS FROM DIALLER
DSCDLF==:004000 ;DIALLER FAIL. UNSUCCESSFUL DIALLER ATTEMPT
DSCDLC==:002000 ;DIALLER COMPLETE. SUCCESSFUL DIALLER ACTION.
DSCEON==:001000 ;END OF NUMBER. SENT ALL DIGITS TO DIALLER.
DSCTMM==:777 ;TIME MASK. MUST AGREE WITH DSTIMP POINTER.
;DEFINITIONS FOR INITIALIZATION ROUTINE (FORMERLY IN SYSINI)
DSCICL==DSCHWC!DSCSWC!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON!DSCTMM
DSCIC1==DSCHWC!DSCSWC
DSCIC2==DSCTMM!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON
SUBTTL DATA STRUCTURES -- LINE DATA BLOCK (LDB)
;PROTOTYPE LINE DATA BLOCK FOR A TTY (OR PTY) LINE
SCNLDB:! ;HANDY LABEL TO FIND THE DEFINITION
.ORG 0
LDBDDB::!0 ;ADDRESS OF LINE'S ATTACHED DDB, IF ANY
LDBCOM::!0 ;BITS WHICH USED TO BE IN LH OF LDBDDB
LDBCMR==:400000 ;SIGN BIT OF LDBCOM IS COMMAND REQUEST BIT
; MUST BE IN WORD ZERO, FOR @U, 13-17 MUST BE ZERO
LDBCMF==:200000 ;COMMAND FORCED. MEANS TYI ATE A CONTROL C
; WHICH WAS DESTINED FOR COMCON, OR SOME OTHER COMMAND
; IS TO BE FORCED, VIA LDPCMX. MUST BE IN SAME
; WORD AS LDBCMR
LDBCMK==:100000 ;FORCING KJOB COMMAND
LDBDET==:40000 ;JOB DETACHED FROM THIS LINE DURING COMMAND
;PROCESSING. FORCE CLEANUP OF JOB/COMMAND
;AT NEXT TICK.
LDBFDX==:20000 ;PROCESSING A FILDAE EXIT MESSAGE. LEAVE LDBCMF ALONE.
;BITS 9-12 ARE INDEX FOR FORCED COMMAND,
; POINTER = LDPCMX
LDBATR::!0 ;TERMINAL ATTRIBUTES
LAL8BT==:400000 ;EIGHT-BIT TERMINAL. MUST BE SIGN BIT. TERMINAL
; CAN ACCEPT AND GENERATE ASCII CODES 200-377.
LALDIS==:200000 ;TERMINAL IS A DISPLAY. AT A MINIMUM, THIS IMPLIES
; THAT BACKSPACE GOES BACKWARD ON THE SCREEN, AND
; THERE IS A WAY TO HOME AND CLEAR THE SCREEN.
; (FORMERLY LPLDIS)
LALCOS==:100000 ;CAN OVERSTRIKE. USED WHEN LAL8BT OFF TO GENERATE
; 7-BIT EQUIVALENTS FOR 8-BIT CHARACTERS.
LALISO==:(TA.ISO) ;ISO EXPANSIONS DESIRED
LDBAT2:!0 ;TERMINAL ATTRIBUTE BYTES
LDBAT3:!0 ;CUSTOMER ATTRIBUTES
LDBTTN:!0 ;TTY TYPE MODEL NAME
LDBOST::!0 ;OUTPUT SPECIAL STATES BIT TABLE
;BITS ARE DEFINED AT XMTDSP
;SAVED CHARACTERS IN RH (SEE XMTREO & XMTREE)
LDBIST::!0 ;INPUT STATE WORD
;LH STORES THE CHARACTER BEING DEFERRED,
;RH STORES THE REASON FOR DEFERRING IT:
LISDCI==1 ;DEFERRED CLEAR INTERRUPT
LISQOT==2 ;QUOTING A CHARACTER
LISSWI==3 ;EVALUATING A POSSIBLE SWITCH SEQUENCE
LISFND==4 ;LOOKING FOR A CHARACTER TO FIND
LDBBKU:!0 ;COPY OF LDBECT AT LAST BREAK XMTECH
LDBBKI:!0 ;COPY OF LDBTIP AT LAST BREAK RECINT
LDBTIP::!0 ;T2 TO PUT CHARACTERS IN INPUT BUFFER
LDBTIT::!0 ;T2 TO TAKE CHARACTERS FROM INPUT BUFFER
LDBTIC::!0 ;COUNT OF ECHOED CHARACTERS IN INPUT BUFFER
LDBBKC::!0 ;COUNT OF BREAK CHARACTERS IN INPUT BUFFER
LDBTOP::!0 ;T3 TO PUT CHARACTERS IN OUTPUT BUFFER
LDBTOT:!0 ;T2 TO TAKE CHARACTERS FROM OUTPUT BUFFER
LDBTOC::!0 ;COUNT OF CHARACTERS IN OUTPUT BUFFER
LDBECT:!0 ;T2 TO TAKE CHARACTERS FROM INPUT FOR ECHOING
LDBECC::!0 ;COUNT OF CHARACTERS TO ECHO
LDBIEC:!0 ;INVISIBLE (NOT-IN-STREAM) CHARACTERS YET TO BE ECHOED
LDBIIC:!0 ;INVISIBLE (NOT-IN-STREAM) CHARACTERS ECHOED AND PENDING
LDBEOP:!0 ;T3 TO PUT CHARACTERS IN ECHO OUTPUT BUFFER
LDBEOT:!0 ;T2 TO TAKE CHARACTERS FROM ECHO OUTPUT BUFFER
LDBEOC::!0 ;COUNT OF ECHO STREAM CHARACTERS TO OUTPUT
LDBOOP:!0 ;BYTE POINTER TO ENQUEUE OUT-OF-BAND CHARACTERS
LDBOOT:!0 ;B.P. TO DEQUEUE OUT-OF-BAND CHARACTERS
LDBOOC:!0 ;COUNT OF ENQUEUED OUT-OF-BAND CHARACTERS
LDBCLP:!0 ;COMMAND LINE POINTER (FOR COMCON)
LDBXNP::!0 ;XON CLASS CHARACTER POINTER FOR OUTPUT
IFN FTXMON,<
0 ;TWO WORD GLOBAL BYTE POINTER
>
LDBFLP::!0 ;FILLER CHARACTER POINTER FOR OUTPUT
IFN FTXMON,<
0 ;TWO WORD GLOBAL BYTE POINTER
>
LDBNNP:!0 ;FILLER POINTER FOR 'NOT NOW' TEXT (BUSY/GOAWAY)
IFN FTXMON,<
0 ;TWO WORD GLOBAL BYTE POINTER
>
LDBPBK:!0 ;WORD OF UP TO 4 BREAK CHARACTERS (8 BIT)
;FOR PACKED IMAGE MODE (PIM); SET WITH TRMOP 2037
LDBHPS:!0 ;HORIZONTAL POSITION COUNTER. COUNTS UP FROM
;MINUS CARRIAGE WIDTH TO ZERO.
LDBBCT::!0 ;TOTAL COMMAND,,BREAK CHARACTER COUNT
LDBICT:!0 ;TOTAL INPUT CHARACTER COUNT
LDBOCT:!0 ;TOTAL OUTPUT CHARACTER COUNT
;MORE OF THE PROTOTYPE LINE DATA BLOCK
LDBDCH::!0 ;DEVICE CHARACTERISTICS BITS
;BITS IN LH OF LDBDCH (CARRIED IN LH OF U DURING INTERRUPT ROUTINE)
LDLIDL==:400000 ;LINE IS IDLE. IF CLEAR, WE ARE EXPECTING
;A TRANSMIT INTERRUPT
; MUST BE SIGN BIT.
LDLPPS==200000 ;PROMPT POSITION SET THIS LINE
LDLCRP==100000 ;CONTROL-R PENDING (FOR XMTECH SYNCH PLUG)
LDLDIP==040000 ;DELETE IN PROGRESS IN XMTECH (BLOCK TYICC4)
LDLCNE==:020000 ;COMMAND-LEVEL NO ECHO
LDL8BI==:010000 ;8-BIT INPUT MODE, DUE TO PROGRAM
LDLDLR==004000 ;SUPPRESS DOLLAR SIGN ON ALTMODES.
LDLNEC==:002000 ;NO ECHO, DUE TO PROGRAM
LDLFCS==:001000 ;LINE INITED IN FULL CHAR SET MODE
LDLIMI==:000400 ;IMAGE INPUT (KEEP NULLS)
LDLCOM==:000200 ;LINE IS AT COMMAND LEVEL
LDLBKA==:000100 ;BREAK ON ALL CHARACTERS (DDTIN, TTCALL)
;*** BEGINNING OF GROUP OF BITS POINTED TO BY LDPVR1 ***
;*** BEGINNING OF 4 BITS POINTED TO BY GETLP1 FOR GETLIN ****
LDLSLV==:000040 ;SLAVE. THIS TERMINAL MAY BE ASSIGNED.
LDLLCT==:000020 ;LOWER CASE TRANSLATE TO UPPER
LDLTAB==:000010 ;LINE ACCEPTS TABS, NOT SPACES.
LDLLCP==:000004 ;LOCAL COPY (NO ECHO)
;*** END OF BITS POINTED TO BY GETLP1 ***
LDLFRM==:000002 ;LINE ACCEPTS FF AND VT (ELSE USE LF'S)
LDLNFC==:000001 ;NO FREE CARRIAGE RETURN AT 72 COLUMNS
;*** END OF GROUP FOR LDPVR1 ***
;BITS TO BE CLEARED ON A 140 RESTART
ZZL==LDLIDL+LDLIMI+LDLNEC+LDLDLR+LDLBKA+LDLFCS+LDLCRP+LDL8BI+LDLDIP+LDLCNE
;RH OF LDBDCH - BITS 27-35 = LINE NUMBER, POINTER = LDPLNO
LDRPTY==:400000 ;PSEUDO-TERMINAL
LDRCTY==:200000 ;CONSOLE TERMINAL
;*** START OF GROUP OF BITS POINTED TO BY LDPVR2 ***
LDROSU==:100000 ;OUTPUT SUPPRESS (^O)
LDRDSD==:040000 ;DATASET DATA LINE
;(FREE)==020000 ;FREE
;(FREE)==010000 ;FREE (FORMERLY HDX)
LDRRMT==:004000 ;REMOTE NON-DATASET LINE
LDRDSR==:LDRDSD+LDRRMT ;REMOTE OR DATA SET LINE (FOR PATCH)
; SO CAN'T ATTACH TO PROJECT 1 #
;*** END OF GROUP FOR LDPVR2 ***
; 002000 ;FREE
LDRSHC==001000 ;SUPPRESS HUNG CHECK -I.E. DON'T FORCE CHAR'S OUT
; WHEN NO XMIT FLAG.--SET BY 680 FOR SPECIAL
; DEVICES (E.G. 2741) & ITS OPR. TERMINAL
;BITS TO BE CLEARED ON A 400 RESTART
ZZR==LDRPTY+LDRCTY+LDRSHC+LDROSU
;MORE OF THE PROTOTYPE LINE DATA BLOCK
LDBOFL::!
LDBBYT::!0 ;A WORD OF BYTES FOR THIS LINE
;BITS POINTER USE
;35-28 (FREE) FREE BITS
;27 L1RDEM DEFERRED ECHO BIT. SET BY SET TERMINAL DEFER
;26 L1RDEC ECHO MAY ECHO 1 CHARACTER IF DEFERRED
;25 L1RDEL ECHO MAY ECHO 1 LINE IF DEFERRED
;24-22 LDPCPU CPU NUMBER--
;21 L1RCHP CHANGE HARDWARE PARAMETERS FLAG (MEANINGUL EVEN FOR PTYS!)
;20 L1RMIF MIC INTERLOCK FLAG
;19-15 LDPTIM TIMEOUT ON IMAGE INPUT
;14 L1LDEM DEFERRED ECHO BIT FOR XMTECH. SET/CLEARED BY XMTECH
;13 L1LQOT TTY QUOTE ENABLED
;12 L1LQTC QUOTE NEXT CHARACTER IN XMTECH
;11 L1LQNC QUOTE NEXT CHARACTER IN TYICC4
;10 L1LQCC QUOTE NEXT CHARACTER IN CCTYI
;09 L1LUNR UNREAD IN PROGRESS
;08-07 FREE
;06 L1LEEL END OF ERROR LINE SEEN FOR MIC RESPONSE WAKEUP
;05-03 POHPOS OLD HORIZONTAL POSITION. NEEDED FOR TAB SIMULATION
;02-01 LDPFLC COUNT OF NUMBER OF FILLERS BY CLASS
;0 1 IF FRONT END FOR THIS LINE IS DOWN.
; USE LDBOFL AS THE SYMBOL TO SKIPGE/SKIPL ON.
L1LOFL==:400000 ;THE OFF-LINE BIT
L1RDEM==:1B27 ;DEFERRED ECHO MODE
L1RDEC==:1B26 ;MAY ECHO ONE CHARACTER (DEFERRED ECHO ONLY)
L1RDEL==:1B25 ;MAY ECHO ONE LINE (DEFERRED ECHO ONLY)
L1RCHP==:1B21 ;CHANGE HDW PARMS
L1RMIF==:1B20 ;MIC INTERLOCK FLAG
L1LDEM==(1B14) ;XMTECH'S DEFERRED ECHO FLAG
L1LQOT==:(1B13) ;TTY QUOTE ENABLED FLAG
L1LQTC==(1B12) ;QUOTE FLAG FOR XMTECH
L1LQNC==(1B11) ;QUOTE FLAG FOR TYICC4
L1LQCC==(1B10) ;QUOTE FLAG FOR CCTYI
L1LUNR==:(1B9) ;UNREAD IN PROGRESS
L1LEEL==(1B6) ;END OF ERROR LINE SEEN (FOR MIC RESPONSE)
L1LPOH==(7B5) ;LOW-ORDER BITS OF PREVIOUS HPOS FOR TAB EXPANSION
L1LFLC==(3B2) ;FILLER CLASS
LDIBCM==477777,,600000+L1RDEM+L1RDEC+L1RDEL+L1RCHP+L1RMIF+377 ;MASK TO CLEAR
;LDBBYT AT SCNINI. ALL ARE CLEARED EXCEPT LDPFLC
;ANOTHER BYTE WORD, FLAGS AT LEFT.
LDBBY2::!0
;BITS POINTER USE
;32-35 FREE
;28-31 LDPAPC ASYNCHRONOUS PORT CHARACTERISTIC
;20-27 LDPWID WIDTH OF TERMINAL CARRIAGE
;18-19 BITS - SEE BELOW
;9-17 LDPDSC DATASET CONTROL TABLE INDEX BACK POINTER
;0-8 BITS - SEE BELOW
L2LDEL==:400000 ;LAST CHAR IN WAS A DELETE (MUST BE SIGN BIT)
L2LCCS==200000 ;LAST CHAR IN WAS A ^C
;(FREE)==100000 ;FREE BIT
;(FREE)==040000 ;FREE BIT
;(FREE)==020000 ;FREE BIT
;(FREE)==010000 ;FREE BIT
;(FREE)==004000 ;FREE BIT
L2LSND==:002000 ;SEND ALLOWED WHILE BUSY
L2LTAP==:001000 ;^Q FROM KEYBOARD TURNS ON L2RXON. SET BY .TERMINAL TAPE COMMAND
L2LCLR==L2LDEL!L2LCCS!L2LSND!L2LTAP
;CLEARED ON INITIALIZATION
L2RXON==:400000 ;XON IS TRUE (PAPER TAPE INPUT)
L2RECS==200000 ;EAT COMMAND SYNC, FOR TTCALL 10
L2RWID==177400 ;FIELD FOR CARRIAGE WIDTH
L2RAPC==000360 ;FIELD FOR ASYNCHRONOUS PORT CHARACTERISTIC
;FREE== 000017 ;FREE BITS
;ANOTHER BYTE WORD, FLAGS AT LEFT.
LDBBY3::!0
;BITS POINTER USE
;27-35 LDPTMR COUNT-UP TIMER FOR AUTO-DISCONNECT
;27 L3RTMO OVERFLOW FOR ABOVE (AUTO-DISCONNECT TIMER EXPIRED)
;19-26 LDPMXT MAXIMUM IDLE TIME FOR AUTO-DISCONNECT LOGIC
;10 L3LCHD COMMAND HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;9 L3LIHD INPUT HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;8 L3LEHD ECHO HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;7 L3LOHD OUTPUT HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;6 L3LFHD FILL HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;5 L3LCPD COMMAND PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;4 L3LIPD INPUT PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;3 L3LEPD ECHO PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;2 L3LOPD OUTPUT PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;1 L3LFPD FILL PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;0 L3LDMC DEFERRED ECHO MODE CHANGED (MUST BE SIGN BIT)
L3RTMO==1B27 ;AUTO-DISCONNECT LOGIC TIMEOUT FLAG
L3LCHD==(1B10) ;COMMAND HALF-DONE (TWO-PART CHARACTER)
L3LIHD==(1B9) ;INPUT HALF-DONE (TWO-PART CHARACTER)
L3LEHD==(1B8) ;ECHO HALF-DONE (TWO-PART CHARACTER)
L3LOHD==(1B7) ;OUTPUT HALF-DONE (TWO-PART CHARACTER)
L3LFHD==(1B6) ;FILL HALF-DONE (TWO-PART CHARACTER)
L3LCPD==(1B5) ;COMMAND PART DONE (THREE-PART CHARACTER)
L3LIPD==(1B4) ;INPUT PART-DONE (THREE-PART CHARACTER)
L3LEPD==(1B3) ;ECHO PART-DONE (THREE-PART CHARACTER)
L3LOPD==(1B2) ;OUTPUT PART-DONE (THREE-PART CHARACTER)
L3LFPD==(1B1) ;FILL PART-DONE (THREE-PART CHARACTER)
TPCLSH==5 ;OFFSET FROM TWO-PART TO THREE-PART BITS
L3LDMC==:(1B0) ;DEFERRED ECHO MODE HAS CHANGED (FLAG FOR RECINT)
;LENGTH AND STOP SIZE AND COUNTERS
LDBLSW:!0
;BITS POINTER USE
;00-08 LDPLNB PAGE (OR "FORMS") LENGTH (BASE VALUE)
;09-17 LDPSTB STOP (AFTER N LINES) SIZE (BASE VALUE)
;18-26 LDPLNC PAGE (OR "FORMS") COUNTER (COUNTED UP TO 0)
;27-35 LDPSTC STOP (AFTER N LINES) COUNTER (COUNTED UP TO 0)
;
; ABOVE ARE 8-BIT FIELDS WITH ONE-BIT OVERFLOW.
; LDPLNC AND LDPSTC MUST BE IN RIGHT HALF WORD!
LPRLC0== 400000 ;LENGTH COUNTER OVERFLOWED
LPRSC0== 000400 ;STOP COUNTER OVERFLOWED
;PAGE COUNTER WORD AND PAGE FLAGS
LDBPAG::!0
;BITS POINTER USE
;3 LDPALT ALTMODE CONVERSION (SET TERMINAL ALT)
;16-17 FREE
;18-26 LDPPFF #LF'S REMAINING ON F.F. SIMULATION
;27-35 LDPACR AUTO CRLF COUNTER
LPLIRM== 400000 ;LOST TRANSMIT INTERRUPT BIT
LPLXNF==:200000 ;PROCESS XON/XOFF
LPLXOF== 100000 ;SENT XOFF, ALWAYS SEND AN XON LATER
LPLALT==:040000 ;ALTMODE CONV. (1:CONVERT 175,176 TO 033)
LPLBLK==:020000 ;SUPPRESS BLANK LINES
LPLSLF== 010000 ;SUPPRESS LINE FEEDS
;(FREE)==004000 ;FREE BIT
;(FREE)==002000 ;FREE BIT
LPLPOK== 001000 ;WE ARE FORCING XMIT START VIA TOPOKE (PREVENT RACE)
LPLSTP==:000400 ;AUTOMATICALLY STOP EVERY (LDPSTB) LINES OF OUTPUT
LPLSST==:000200 ;NO CLRPCT ON RECEIPT OF "FREE" XON
LPLFFS==:000100 ;STOP ON FORM-FEEDS
LPLSBL==:000040 ;UTTER FORTH A STUPID BELL ON AUTO STOP
LPLFFF==:000020 ;SIMULATE FORMFEEDS WITH MANY LINEFEEDS
LPLFFH==:000010 ;SIMULATE FORMFEEDS AS HOME/ERASE SEQUENCE
;(FREE)==000004 ;FREE BIT
;(FREE)==000002 ;FREE BIT
;(FREE)==000001 ;FREE BIT
LPRPFF== 777000 ;FORM FEED SIMULATION LF COUNTER
LPRACR== 000777 ;AUTO-CRLF COUNTER
LPGCLK==LPLIRM!LPLXOF!LPLBLK!LPLSLF,,LPRPFF!LPRACR ;CLEARED BY TTYKIL
LPGCLI==LPGCLK!<LPLSTP!LPLSST!LPLFFS!LPLSBL!LPLFFF!LPLFFH,,0> ;CLEARED BY LDBINI
;FLAGS AND POINTER TO INTERRUPT SERVICE ROUTINES
LDBISR::!BLOCK 1
;13-17 CONTAIN T1 FOR @LDBISR(U)
;18-35 ADDRESS OF ISR DISPATCH TABLE
LDBISB::!BLOCK 1
;BITS POINTER USE
;0 N/A 1 IF THE FRONT END IS CLEVER, 0 IF DUMB
;1-4 LDPTSP TRANSMIT SPEED
;5-8 LDPRSP RECEIVE SPEED
;9 LDPAPL APL MODE
;10 LDP7BT DUMB FE CAN'T DO 8-BIT
;11 LDPRTC CONTROL-R, CONTROL-T COMPATIBILITY
;12-35 (FREE) FREE BITS
LILCFE==:(1B0) ;CLEVER FRONT END
LILRSP==:(17B4) ;RECEIVE SPEED
LILTSP==:(17B8) ;TRANSMIT SPEED
LILAPL==:(1B9) ;APL MODE
LIL7BT==:(1B10) ;LINE IS RESTRICED TO 7-BIT
LILRTC==:(1B11) ;CONTROL-R, CONTROL-T ARE PASSED TO PGM
;FUNCTIONS ARE DEFINED IN S.MAC (ISR??? AND IRR???)
;LDBQUE -- QUEUED PROTOCOL WORDS
LDBQUE:!BLOCK 1
LDBQUH::!BLOCK 1
;BITS
;WORD 1 NEXT LDB IN THE QUEUE (0 TERMINATES)
;WORD 2
; 0-17 ADDRESS OF THE QUEUE HEADER
; 18-35 NOT CURRENTLY USED
;TERMINAL TYPE WORD
LDBTTW::!BLOCK 1
;0 LTLANF ANF-10 NETWORK VIRTUAL TERMINAL (MUST BE SIGN BIT)
;1 LTLNRT DECNET NRT/CTERM VIRTUAL TERMINAL
;2 LTLLAT LAT-SERVER TERMINAL LINE
;3 LTLUSE ALLOCATABLE LDB IN USE
;4-8 FREE
;9 LDLFSP FULL SCNSER PTY
;10 LDLVDC 'VISIBLE' DELETE CHARACTER PROCESSING BIT (FOR XMTECH)
;11 LDLIDC 'INVISIBLE' DELETE CHARACTER PROCESSING BIT (FOR RICW)
;12-19 LDPLCH LAST CHAR READ BY COMCON.
;20-27 LDPPRP POSITION OF PROMPT
;28-35 LDPTTT TERMINAL TYPE AS SPECIFIED BY TTY TYPE COMMAND
LTLANF==:400000 ;ANF NETWORK VIRTUAL TERMINAL
LTLNRT==:200000 ;DECNET NRT/CTERM TTY
LTLLAT==:100000 ;LAT-SERVER TTY
LTLREM==:LTLANF!LTLNRT!LTLLAT ;SOME FORM OF "REMOTE" TERMINAL SERVER
LTLUSE==:040000 ;ALLOCATABLE LDB IS IN USE (SEE GETLDB/FRELDB)
; NOTE: LTLUSE ALWAYS ON FOR 'LOCAL' (E.G., CTY) LDBS
LDLFSP==:000400 ;FULL SCNSER PTY
LDLVDC== 000200 ;CONTROL R IN PROGRESS
LDLIDC== 000100 ;CONTROL W IN PROGRESS (NOT CURRENTLY REFERENCED)
;FIVE WORDS FOR REMOTE STATION TERMINAL STATUS
IFN FTNET,< ;NETWORK RELATED LDB FIELDS
LDBREM::!BLOCK 5 ;WORDS REQUIRED FOR REMOTE TERMINALS
; LAYOUT OF LDBREM FIELDS
;
; +0 BYTE (20)BITS-USED-BY-NETTTY, (16)LAST-DAP-STATUS-MESSAGE-SENT
; +1 BYTE (36)LAST-CHARACTERISTICS-MESSAGE-SENT
; +2 BYTE (14)SLA, (14)DLA, (8)REMOTE-LINE-NUMBER
; +3 BYTE (4)FREE, (8)DRQ-COUNT, (8)EPM-SERIAL, (16)NODE-#
; +4MCR BYTE (9)NEXT-CHAR-TO-OUTPUT, (9)JOB, (9)REMOTE-NCL-VERSION, (9)LAST-TTY-TYPE
; +4VTM BYTE (16)DELAYED-STATUS-MESSAGE, (2)0, (18)VTM-QUEUE-LINK
;DEFINE SYMBOLS FOR SOME LDBREM ENTRIES
LDBCCH==:LDBREM+1 ;COMPRESSED CHARACTERISTICS WORD
LDBVTQ==:LDBREM+4 ;NETVTM'S QUEUE LINK HALF-WORD
; BITS USED IN LDBREM
;BITS USED BY BOTH NETVTM(LOCAL SET HOST) AND NETMCR(REMOTE TERMINALS)
LRLVTM==:(1B0) ;*** MUST BE SIGN BIT ***
; IF SET, THEN THIS IS A "LOCAL TERMINAL"
; THAT HAS "SET HOSTED" TO ANOTHER HOST.
LRLCON==:(1B1) ;IF SET, THEN TERMINAL IS "CONNECTED"
; (I.E. NCL CONNECT SEQUENCE IS COMPLETE)
LRLSTS==:(1B2) ;IF SET, THEN A "STATUS" MESSAGE IS REQUIRED
; SAME BIT, BUT DIFFERENT MPXS FOR VTM & MCR
LRLATO==:(1B3) ;IF SET, THEN IN AN AUTOBAUD SEQUENCE
;BITS USED ONLY BY NETVTM (LOCAL "SET HOST")
LRLSCH==:(1B4) ;IF SET, THEN A "CHARACTERISTICS" MESSAGE
; IS REQUIRED (WORKS LIKE "LRLSTS")
LRLDST==:(1B5) ;A "DELAYED" STATUS MESSAGE IS REQUIRED
; (USED TO OPTIMIZE MESSAGE TRAFFIC.
; THIS BIT HAS PRIORITY OVER LRLSTS)
LRLQED==:(1B6) ;IF SET, THEN VTM LINE HAS BEEN "QUEUED"
; BY "VTMENQ"
LRLDIP==:(1B7) ;IF SET, THEN WE HAVE/WANT-TO INITIATE A
; DISCONNECT ON THIS LINE
LRLVTF==:(1B8) ;VTM TERMINAL NEEDS TO BE "FREED" (A LA FRELDB)
LRLVTZ==:(1B9) ;VTM TERMINAL IS ZAPPED
;LDBREM (CONTINUED)
;BITS USED ONLY BY NETMCR ("NORMAL" REMOTE TERMINALS .. ALA DN87)
LRLTTW==:(1B4) ;LINE IS WAITING FOR A DATA-REQUEST
LRLSCG==:(1B5) ;^O ACTION REQUESTED (SEND CHAR GOBBLER)
LRLEPW==:(1B6) ;ECHO PIPELINE MARKER WAITING TO GO.
LRLIMO==:(1B7) ;INDICATES THAT REMOTE IS IN IMAGE MODE OUTPUT
LRLADR==:(1B8) ;USE OF THE AUTO-DIALER HAS BEEN REQUESTED
LRLXOF==:(1B9) ;AN XOFF (^S) MESSAGE HAS BEEN REQUESTED
LRLCHR==:(1B10) ;THIS TERMINAL HAS RECEIVED AT LEAST 1
; CHARACTERISTICS MSG. (SEE NETTTY.MAC, ROUTINE
; SCNMCR FOR DETAILS OF THE RACES INVOLVED...)
LRLHUR==:(1B11) ;HANG-UP THE PHONE REQUESTED
LRLDSR==:(1B12) ;THE -10'S COPY OF WHAT IT THINKS CARRIER
; SHOULD BE. (KEPT SO WE CAN TELL IF THE -11
; CHANGED IT WHILE WE WEREN'T LOOKING)
LRLGRT==:(1B13) ;NEED TO "GREET" THE TERMINAL (E.G., RUN INITIA)
LRLTTO==:(1B14) ;LDPCHR HAS THE NEXT CHAR TO OUTPUT. THIS IS
; NECESSARY SINCE THERE IS NO WAY TO TELL IF
; XMTCHR WILL GIVE A CHAR WITH OUT GETTING IT.
LRLADL==:(1B15) ;INDICATES THAT THIS LINE POSSESES AN AUTO-
; DIALER (ALSO SET BY CONNECT MESSAGE)
LRLTMO==:(1B16) ;HANG-UP REQUESTED BY AUTO-DISCONNECT TIMEOUT
LRLABR==:(1B17) ;AUTOBAUD REQUEST PENDING FOR REMOTE
LRRSHC==:1B18 ;SAYS THAT THE LINE AT THE OTHER END HAS
; "SET HOST CAPABILITY". (I.E. IT CAN
; RESPOND TO DISCONNECT MESSAGES). NOT
; SET FOR DC72 LINES. SET FOR ALL OTHERS.
LRRXFF==:1B19 ;WANT TO SEND XON/XOFF STATE IN STATUS
; MESSAGE.
LRLCLR==:LRLDSR!LRLATO ;BITS THAT ARE OFF ON "VIRGIN" LINES
>;END OF IFN FTNET
;DEFINITIONS FOR SUPPORT OF RSX-20F TERMINALS
IFN FTKL10!FTDECNET!FTENET,< ;TTD'S ONLY ON A KL, NRT AND LAT VIA DECnet
LDBLAT::! ;REDEFINES BELOW, USED ONLY FOR LAT LINES
LDBNRT::! ;REDEFINES LDBTTD, USED ONLY FOR NRT LINES
LDBTTD::!0 ;LINE INFO FOR -20F LINES
IFN FTKL10,< ;TTD'S ONLY ON A KL
; 740000 ;REMEMBERED TRANSMIT SPEED
; 036000 ;REMEMBERED RECEIVE SPEED
LTLXOF==:1000 ;SENT XOFF TO -20F
LTLRBS==:400 ;REMOTE BIT SENT FOR -20F DATASETS
LTLCTO==:200 ;NEED TO SEND FLUSH OUTPUT TO -20F
LTLAXF==:100 ;AUTO-XOFF ENABLE SENT TO -20F
LTLACK==:40 ;LINE WAITING FOR AN ACK
LTLXFF==:20 ;SEND XON/XOFF STATUS TO -20F
LTLTIM==:17 ;TIMEOUT FIELD FOR LTLACK
TTDTIM==:6 ;HOW LONG TO WAIT FOR LTLACK TO BE CLEARED
LTRABR==:400000 ;AUTOBAUD REQUEST PENDING FOR -20F
LTR8BE==:200000 ;LAST SENT 8-BIT AS ENABLED
>;END FTKL10
>;END FTKL10!FTDECNET!FTENET
IFN FTMIC,< ;IF MIC INCLUDED
;WORD FOR MIC TO USE
LDBMIC::!0
;0 SET IF SOME BIT 1-14 IS SET
;1 SET IF A ^C HAS BEEN TYPED
;2 SET IF OPERATOR CHAR SEEN IN COLUMN1
;3 SET IF ERROR CHAR SEEN IN COLUMN 1
;4 SET IF A ^P HAS BEEN TYPED
;5 SET IF A ^B HAS BEEN TYPED
;6 SILENCE THIS LINE
;7 LINE IN MONITOR MODE
; NOT SET IN LDBMIC BUT IS SET ON A MICGET
;8 LINE IN USER MODE AND IN TI WAIT OR IN MONITOR MODE
; AND CAN ACCEPT A COMMAND
; NOT SET IN LDBMIC BUT IS SET ON A MICGET
;9 LINE IS IN COLUMN 1 ON OUTPUT
; USED FOR ERROR AND OPERATOR CHECKING
;10 SET IF A ^A HAS BEEN TYPED (ABORT)
;11 SET IF ERROR OUTPUT IS AVAILABLE
;12 SET IF ERROR OUTPUT IS BEING TAKEN
;13 SET IF MIC IS LOGGING
;14 SET IF MORE INFORMATION IS AVAILABLE VIA JOBSTS UUO
;15-21 ASCII CHAR TO BE TREATED AS OPERATOR CHAR
; SET IN RESPONSE TO OPERATOR COMMAND
; CLEARED IN RESPONSE TO NOOPERATOR COMMAND
; OR ON LOGOUT
;22-28 ASCII CHAR TO BE TREATED AS ERROR CHAR
; SET IN RESPONSE TO ERROR COMMAND
; CLEARED IN RESPONSE TO NOERROR COMMAND
; OR ON LOGOUT
;29-35 MIC MASTER JOB NUMBER - ENABLES MORE THAN ONE MIC TO RUN
LDLCHK==400000 ;SOMETHING EXCITING HAPPENED
LDLMCC==200000 ;^C TYPED
LDLOPC==100000 ;OPERATOR CHARACTER SEEN IN COLUMN 1
LDLERC==40000 ;ERROR CHARACTER SEEN IN COLUMN 1
LDLMCP==20000 ;^P TYPED
LDLMCB==:10000 ;^B TYPED
LDLSIL==4000 ;THIS LINE IS .SILENCE'D
LDLMMM==2000 ;LINE IN MONITOR MODE (MICGET)
LDLMTI==1000 ;LINE IN INPUT READY STATE
LDLCL1==400 ;CARRIAGE IS IN COLUMN 1
LDLMCA==200 ;^A TYPED
LDLRSP==:100 ;ERROR RESPONSE
LDLRSY==:40 ;RESPONSE CODE SYNC
IFN FTMLOG,<
LDLLOG==20 ;MIC IS LOGGING
>
LDLMUI==10 ;USER IS INTERESTING, BUT YOU NEED TO ASK JOBSTS WHY
IFN FTMLOG,<
LDBLOT:!0 ;LOG TAKER,,COUNT OF CHARS TO LOG
LDBLOC:!0 ;COUNT OF CHARACTERS TO LOG
> ;END OF FTMLOG CONDITIONAL
> ;END OF MIC CONDITIONAL
;SPECIAL CHARACTER STATUS STORAGE
;BITS IN LDBBKB
;UNUSED BITS LEFT HALF BITS = 100040
LDBBKB::!0 ;FIELD WIDTH AND BITS CONTROLLING USE OF BREAK SET
LDLBKM==400000 ;LINE IS IN BREAK CHARACTER SET MODE (MUST BE SIGN BIT)
LDBCSL==:<CK.CHR/<^D36/CC.WID>>+1 ;NUMBER OF WORDS REQUIRED TO STORE THE BYTES
;***KEEP TOGETHER (FOR ZEROING)***
LDBCSB::! BLOCK LDBCSL ;RESERVE SPACE FOR SPECIAL CHARACTER CODING
LDBCC1:! BLOCK 1 ;'CLEAR' OOB FLAGS FOR LOW-ORDER CONTROL CHARS
LDBCC2:! BLOCK 1 ;DITTO FOR HIGH-ORDER CONTROL CHARACTERS
;***END OF KEEP TOGETHER***
LDBCHM::!0 ;CHARACTERS MAPPED BY RECMAP
LMLNDS==:400000 ;THE NON-DEFAULT SEQUENCE BIT (MUST BE SIGN)
LMLSSE==200000 ;SWITCH SEQUENCE ENABLED
ND EDTCHC,^D132 ;BUFFER HAS ROOM FOR THIS MANY CHARACTERS
LDBEDT::!0 ;POINTER TO EDITOR BLOCK
EDTPTG==0 ;OFFSET INTO BUFFER BYTE GETTER
; *** MUST BE WORD 0 FOR DCSFND
EDTPTP==1 ;OFFSET INTO BUFFER BYTE PUTTER
EDTCNT==2 ;OFFSET INTO BUFFER TO COUNT OF CHARACATERS AVAILABLE
EDTHDL==EDTCNT+1 ;LENGTH OF BUFFER HEADER
EDTBFL==<<EDTCHC/4>+1>+EDTHDL ;TOTAL BUFFER LENGTH
;*** ADD NEW LDB WORDS ABOVE THIS LINE
LDBSLN:! ;STANDARD LENGTH OF AN LDB
.ORG ;BACK TO STANDARD ADDRESSING
LDBLEN==:LDBSLN+M.LCST## ;SIZE OF DATA BLOCK FOR A LINE
;DISPATCH TABLE FOR PTYS AND CTYS.
IFN FTKS10,<
CTYDSP::JRST CTYTYO ;TYPEOUT
POPJ P,0 ;MODEM CONTROL
POPJ P,0 ;ONCE A SECOND
POPJ P,0 ;INITIALIZATION
POPJ P,0 ;CHANGE HARDWARE PARMS
POPJ P, ;LINE PARM CONTROL
POPJ P, ;SET ELEMENT
POPJ P, ;REMOTE STUFF
JRST CPOPJ1## ;IS LINE UP?
>
ERRDSP::POPJ P,0 ;TYPEOUT
POPJ P,0 ;MODEM CONTROL
POPJ P,0 ;ONCE A SECOND
POPJ P,0 ;INITIALIZATION
POPJ P,0 ;CHANGE HARDWARE PARMS
POPJ P, ;LINE PARM CONTROL
POPJ P, ;SET ELEMENT
POPJ P, ;REMOTE STUFF
JRST CPOPJ1## ;IS LINE UP?
;LINE SPEED MNEMONICS
LS0000==:0 ;ZERO BAUD
LS0050==:1 ;50 BAUD
LS0075==:2 ;75 BAUD
LS0110==:3 ;110 BAUD
LS0134==:4 ;134.5 BAUD
LS0150==:5 ;150 BAUD
LS0200==:6 ;200 BAUD
LS0300==:7 ;300 BAUD
LS0600==:10 ;600 BAUD
LS1200==:11 ;1200 BAUD
LS1800==:12 ;1800 BAUD
LS2400==:13 ;2400 BAUD
LS4800==:14 ;4800 BAUD
LS9600==:15 ;9600 BAUD
;DATA POINTERS INTO LDB
LDPFSP::POINT 1,LDBTTW(U),^L<(LDLFSP)> ;POINTER TO FULL SCNSER PTY BIT
LDPLCH: POINT 8,LDBTTW(U),19 ;POINTER TO LAST CHAR COMCON READ
LDPPRP: POINT 8,LDBTTW(U),27 ;POINTER TO POSITION AFTER PROMPT
LDPTTT::POINT 8,LDBTTW(U),35 ;POINTER TO TTY TYPE
LDPCPU::POINT 3,LDBBYT(U),24
LDPFLC::POINT 2,LDBBYT(U),2 ;POINTER TO INDEX OF FILLER CLASSES
LDPLNO::POINT 9,LDBDCH(U),35 ;POINTER TO HARDWARE LINE NUMBER
LDPTIM::POINT 5,LDBBYT(U),19 ;POINTER TO FIELD WHICH TIMES OUT
; IMAGE MODE INPUT
LDPDEM::POINT 1,LDBBYT(U),^L<L1RDEM> ;POINTER TO L1RDEM BIT
LDPSTP: POINT 1,LDBOST(U),^L<(LOLSTP)>;POINTER TO OUTPUT STOPPED BIT
;LDPSSO:POINT 1,LDBOST(U),^L<(LOLSSO)>;POINTER TO SCNSER STOPPED OUTPUT BIT
LDPFRM::POINT 1,LDBDCH(U),^L<(LDLFRM)>;POINTER TO HARDWARE FORM FEED BIT
LDPTAB::POINT 1,LDBDCH(U),^L<(LDLTAB)>;POINTER TO HARDWARE TABS BIT
LDPLCT::POINT 1,LDBDCH(U),^L<(LDLLCT)>;POINTER TO LOWER CASE BIT
LDPIMI::POINT 1,LDBDCH(U),^L<(LDLIMI)>;POINTER TO IMAGE MODE FLAG
LDPPIM::POINT 1,LDBOST(U),^L<(LOLPIM)>;POINTER TO PIM MODE FLAG
LDPFCS: POINT 1,LDBDCH(U),^L<(LDLFCS)>;POINTER TO FULL CHAR SET FLAG
LDPBKA: POINT 1,LDBDCH(U),^L<(LDLBKA)>;POINTER TO BREAK ON ALL CHARS FLAG
LDPOSU: POINT 1,LDBDCH(U),^L<LDROSU> ;POINTER TO OUTPUT SUPPRESSION (^O) BIT
LDPNFC::POINT 1,LDBDCH(U),^L<(LDLNFC)>;POINTER TO NO FREE CRLF BIT
LDPECH::POINT 1,LDBDCH(U),^L<(LDLNEC)>;POINTER TO NO ECHO BY PROGRAM BIT
LDPCOM: POINT 1,LDBDCH(U),^L<(LDLCOM)>;POINTER TO COMMAND-LEVEL BIT
LDPRMT: POINT 1,LDBDCH(U),^L<LDRRMT> ;POINTER TO REMOTE BIT
LDPXNF::POINT 1,LDBPAG(U),^L<(LPLXNF)>;POINTER TO XOFFON BIT
LDPALT: POINT 1,LDBPAG(U),^L<(LPLALT)>;POINTER TO ALTMODE CONVERSION BIT
LDPDIS::POINT 1,LDBATR(U),^L<(LALDIS)>;POINTER TO DISPLAY TERMINAL BIT
LDP8BT::POINT 1,LDBATR(U),^L<(LAL8BT)>;POINTER TO 8-BIT TERMINAL BIT
LDPISO: POINT 1,LDBATR(U),^L<TA.ISO> ;POINTER TO ISO LATIN-1 BIT
LDPALV: POINT 4,LDBAT2(U),6 ;POINTER TO ANSI LEVEL
LDPDLV: POINT 4,LDBAT2(U),10 ;POINTER TO DEC LEVEL
LDPTTN: POINT 36,LDBTTN(U),35 ;POINTER TO MODEL NAME
LDPATR: POINT 36,LDBATR(U),35 ;POINTER TO ATTRIBUTE BITS
LDPAT2: POINT 36,LDBAT2(U),35 ;POINTER TO ATTRIBYTE BYTES
LDPAT3: POINT 36,LDBAT3(U),35 ;POINTER TO CUSTOMER ATTRIBUTES
POHPOS: POINT 3,LDBBYT(U),5 ;POINTER TO LOW 3 BITS OF HPOS
; BEFORE A TAB (FOR TAB SIMULATION)
LDPVR1: POINT 6,LDBDCH(U),17 ;POINTER TO STORE SOME OF INITIAL BITS
LDPVR2: POINT 5,LDBDCH(U),24 ;POINTER TO STORE SOME MORE OF ABOVE.
LDPCMX::POINT 4,LDBCOM(U),12 ;POINTER TO INDEX OF FORCED COMMANDS
LDPWID::POINT 8,LDBBY2(U),27 ;POINTER TO WIDTH OF TERMINAL CARRIAGE
LDPDSC::POINT 9,LDBBY2(U),17 ;POINTER TO DATASET CONTROL TABLE INDEX
LDPAPC::POINT 4,LDBBY2(U),31 ;POINTER TO APC
LDPLNB::POINT 8,LDBLSW(U),8 ;TTY LENGTH BASE VALUE
LDPSTB::POINT 8,LDBLSW(U),17 ;TTY STOP BASE VALUE
LDPLNC: POINT 9,LDBLSW(U),26 ;CURRENT LENGTH COUNTER
LDPSTC: POINT 9,LDBLSW(U),35 ;CURRENT STOP COUNTER
LDPSST::POINT 1,LDBPAG(U),^L<(LPLSST)>;TTY SSTOP
LDPSPE::POINT 1,LDBPAG(U),^L<(LPLSTP)>;TTY STOP (ON/OFF)
LDPPFF: POINT 9,LDBPAG(U),26 ;L.F. COUNTER FOR SIMULATION OF VT & FF
LDPDEB::POINT 2,LDBBYT(U),26 ;POINTER TO DEFERRED ECHO BITS
LDP7BT::POINT 1,LDBISB(U),10 ;DUMB FE BIT (7-BIT RESTRICTION)
LDPAPL::POINT 1,LDBISB(U),9 ;APL MODE
LDPSPD::POINT 8,LDBISB(U),8 ;BOTH SPEEDS
LDPRTC: POINT 1,LDBISB(U),11 ;^R, ^T COMPATIBILITY
LDPRSP::POINT 4,LDBISB(U),8 ;RECEIVE SPEED
LDPTSP::POINT 4,LDBISB(U),4 ;TRANSMIT SPEED
LDPACR::POINT 9,LDBPAG(U),35 ;AUTO CRLF POINT
IFN FTNET,<
;FIELDS IN THE LDBREM AREA. (USED BY NETWORK LINES)
LDPSTS::POINT 16,LDBREM+0(U),35 ;CONTAINS THE LAST DAP STATUS MESSAGE
LDPSLA::POINT 13,LDBREM+2(U),12 ;CONTAINS OUR SOURCE LINK ADDRESS
LDPDLA::POINT 13,LDBREM+2(U),25 ;CONTAINS OUR DESTINATION LINK ADDRESS
LDPRLN::POINT 10,LDBREM+2(U),35 ;LINE NUMBER AT REMOTE STATION
LDPDRQ::POINT 8,LDBREM+3(U),11 ;NUMBER OF DATA-REQUESTS FROM REMOTE
LDPEPM::POINT 8,LDBREM+3(U),19 ;SERIAL NUMBER OF LAST EPM FROM REMOTE
LDPRNN::POINT 16,LDBREM+3(U),35 ;NUMBER OF NODE OWNING THIS TTY
LDPRNF::POINT 16,LDBREM+3(F),35 ; SAME AS ABOVE, EXCEPT INDEXED BY "F"
LDPCHR::POINT 9,LDBREM+4(U),8 ;IF LRLTTO =1, THIS CONTAINS THE NEXT
; OUTPUT CHARACTER
LDPJOB::POINT 9,LDBREM+4(U),17 ;POINTER TO JOB (ONLY FOR CONNECTS)
LDPNVR::POINT 9,LDBREM+4(U),26 ;NCL VERSION OF NODE OWNING TTY
LDPLTT::POINT 9,LDBREM+4(U),35 ;LAST TTY TYPE SENT TO REMOTE
LDPDST::POINT 18,LDBVTQ(U),17 ;"DELAYED" STATUS FOR VTM
>;END OF IFN FTNET
IFN FTMIC,<
LDP.OP: POINT 7,LDBMIC(U),21 ;OPERATOR CHARACTER
LDP.ER: POINT 7,LDBMIC(U),28 ;ERROR CHARACTER
LDPMJN::POINT 7,LDBMIC(U),35 ;MIC MASTER JOB NUMBER
> ;END IFN FTMIC
LDPFWD: POINT 9,LDBBKB(U),11 ;BREAK FIELD WIDTH
LDPQOT::POINT 1,LDBBYT(U),^L<(L1LQOT)>;TTY QUOTE
LDPDTC: POINT CK.WID,LDBIST(U),17 ;CHARACTER DEFERRED BY SETDCS
LDPDCS: POINT 18,LDBIST(U),35 ;SPECIAL INPUT STATE CODE
LDPREO: POINT 9,LDBOST(U),35 ;CHARACTER TO REEAT IN XMTREO
LDPREE: POINT 9,LDBOST(U),26 ;CHARACTER TO REEAT IN XMTREE
LDPUNP::POINT 8,LDBCHM(U),9 ;TTY UNPAUSE CHARACTER
LDPESC::POINT 8,LDBCHM(U),17 ;TTY ESCAPE CHARACTER
LDPSW1::POINT 8,LDBCHM(U),25 ;SWITCH SEQUENCE ONE
LDPSW2::POINT 8,LDBCHM(U),33 ;SWITCH SEQUENCE TWO
LDPSWI: POINT 16,LDBCHM(U),33 ;POINTER TO BOTH OF ABOVE
LDPLCP: POINT 1,LDBDCH(U),^L<(LDLLCP)>;LOCAL COPY BIT
LDPMXT: POINT 8,LDBBY3(U),26 ;AUTO-DISCONNECT MAX. IDLE TIME
LDPTMR: POINT 9,LDBBY3(U),35 ;COUNT-UP TIMER FOR AUTO-DISCONNECT
LDP8BI::POINT 1,LDBDCH(U),^L<(LDL8BI)>;POINTER TO 8-BIT I/O BIT
LDPCNE::POINT 1,LDBDCH(U),^L<(LDLCNE)>;POINTER TO COMMAND-LEVEL NO ECHO BIT
IFN FTKL10,<
LDPTDT::POINT 4,LDBTTD(U),17 ;POINTER TO TTDINT IRMA-LIKE TIMEOUT
>
;BITS TO BE CLEARED ON A 140 RESTART
LDIDCM: XWD ZZL,ZZR ;TO CLEAR BITS IN LDBDCH
BYTCNT: POINT 12,DEVOAD(F),12
;DATA WITHIN THE DDB
;USE OF DEVIOS
;LEFT HALF
TTYOUW==:400000 ;REMEMBERS THAT IF IN IOW, IT IS FOR OUTPUT, AS
; OPPOSED TO INPUT. I.E., WHICH INT WAKES JOB
FRCEND==:200000 ;IN IMAGE INPUT, FORCE END OF FILE DUE TO TIMING
IOLBKA==100000 ;TEMP INTERNAL BIT TO PRESERVE BKA OVER ^C/CONT
;RIGHT HALF
IOSABS==2000 ;BREAK ON CHARACTERS SPECIFIED IN BREAK MASK TABLE
IOSBKA==1000 ;BREAK ON ALL CHARACTERS
IOSTEC==400 ;SUPPRESS ECHO OF DOLLAR SIGN ON ALTMOD
IOSNEC==:200 ;USER (E.G. LOGIN) SUPPRESSING ECHO
IOSFCS==100 ;USER WANTS ALL CHARACTERS.
SUBTTL AUTOCONFIGURE
;DRIVER CHARARCTERISTICS
; SCN = SCNCNF
; SCN = TERMINALS
; 0 = MAXIMUM DEVICES IN SYSTEM
; 0 = KONTROLLER TYPE
; 0 = MAXIMUM DRIVES PER KONTROLLER
; 0 = HIGHEST DRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (SCN,TTY,0,0,0,0,MDSEC0,MDSEC0,<DR.XAD!DR.SFT>)
.ORG DEVLEN
DDBLDB::!BLOCK 1 ;LDB ADDRESS
SCNLEN:! ;LENGTH OF SCANNER DDB
.ORG
$LOW
SCNDDB: DDBBEG (SCN,SCNLEN)
SETWRD (DEVCHR,<STTYBF+1>) ;DEVCHR
SETWRD (DEVSER,<MCSEC0+SCNDSP>) ;DEVSER
SETWRD (DEVMOD,<DVIN!DVOUT!DVTTY,,427>) ;DEVMOD
SETWRD (DEVTYP,<<.TYTTY*.TYEST>,,0>) ;DEVTYP
SETWRD (DEVCPU,<707B8>) ;DEVCPU
DDBEND
$HIGH
EQUATE (LOCAL,0,<SCNCKT,SCNKDB,SCNKLN,SCNUDB,SCNULN>)
EQUATE (LOCAL,0,<SCNICD,SCNICL,SCNINT,SCNULB,SCNULP>)
SCXDSP: DRVDSP (SCN,,SCNDDB,SCNLEN,0)
$HIGH
SCNCFG: SKIPN LINTAB## ;ALREADY INITIALIZED?
SKPCPU (0) ;POLICY CPU?
POPJ P, ;THEN DO NOTHING
JRST SCNCF1 ;DO ONCE-ONLY STUFF
$INIT
SCNCF1: PUSHJ P,SAVE1## ;SAVE P1
SETZ T1, ;NO GENTAB ENTRIES
HRRI T1,TCONLN## ;CTY LINE NUMBER
SETZ T2, ;LOCAL DEVICE
PUSHJ P,AUTDDB## ;CREATE CTY DDB
POPJ P, ;NO CORE??
HRRZS DEVNAM(F) ;CLEAN UP NAME
MOVSI P1,-SCNN## ;NUMBER OF LINES TO BE BUILT
SCNCF2: MOVSI T1,'TTY' ;GENERIC NAME
HRR T1,P1 ;UNIT NUMBER
SETZ T2, ;LOCAL DEVICE
PUSHJ P,AUTDDB## ;BUILD DDB AND LINK INTO CHAIN
POPJ P, ;NO CORE??
AOBJN P1,SCNCF2 ;LOOP FOR ALL TTY DDBS
PUSH P,DINITF## ;CUZ SCNSER IS A SLOB AND SCREWS SYSINI
PUSHJ P,LNKCHK ;ALLOCATE AND LINKUP TTY CHUNKS
PUSHJ P,LNKLDB ;LINKUP LDBS
PUSHJ P,SCNINI ;INIT THE TTYS
POP P,DINITF## ;RESTORE FLAG
POPJ P, ;RETURN
;ALLOCATE AND LINKUP TTY CHUNKS
LNKCHK: HLRZ T2,TTCLST## ;NUMBER OF CHUNKS NEEDED
IMULI T2,TTCHKS## ;TIMES SIZE OF A CHUNK
IFE FTXMON,<
ADDI T2,TTPLEN##*LDBLEN+TTCHKS## ;ACCOUNT FOR LDBS AND RCC CHECKER
PUSH P,T2 ;SAVE AMOUNT REQUESTED
PUSHJ P,GETWDS## ;ALLOCATE CORE
> ;END IFE FTXMON
IFN FTXMON,<
ADDI T2,TTPLEN##*LDBLEN+TTCHKS##+1 ;ACCOUNT FOR LDBS AND RCC CHECKER
MOVEI T1,(MS.SCN) ;SECTION FOR SCNSER DATA
PUSH P,T2 ;SAVE AMOUNT REQUESTED
PUSHJ P,GFWNZN## ;GET THE CORE
> ;END IFN FTXMON
STOPCD .,STOP,NCT, ;++ NO CORE FOR TTY DATABASE
SETZM (T1) ;CLEAR FIRST WORD OF BLOCK
IFE FTXMON,<
MOVSI T2,(T1) ;SOURCE ADDR
HRRI T2,1(T1) ;DEST. ADDR
POP P,T3 ;RESTORE NUMBER OF WORDS
ADDI T3,-1(T1) ;POINT TO LAST WORD OBTAINED
BLT T2,(T3) ;CLEAR OUR CORE (LDB & CHUNK SPACE)
> ;END IFE FTXMON
IFN FTXMON,<
POP P,T2 ;RESTORE WORD COUNT
SOJ T2, ;ALREADY ZEROED ONE WORD
MOVE T3,T1 ;SOURCE ADDRESS
AOS T4,T1 ;DEST. ADDR (LDBS AT 4,,0 SCREW UP DRIVERS)
EXTEND T2,[XBLT] ;CLEAR OUR CORE (LDB & CHUNK SPACE)
> ;END IFN FTXMON
MOVEM T1,LDBVRG## ;SAVE ORIGIN OF LDBS
;INITIALIZE CHUNKS HERE
ADDI T1,TTPLEN##*LDBLEN ;OFFSET BY SIZE OF LDBS
MOVE T2,T1 ;COPY ADDRESS RETURNED
TRZ T1,CK.BDY ;MASK DOWN
TRO T1,1 ;MAKE VALID START OF CHUNK
CAMGE T1,T2 ;IS THIS IN RANGE OF OUR CORE BLOCK?
ADDI T1,TTCHKS## ;NO, ADVANCE TO NEXT BOUNDARY
HRRM T1,TTCLST## ;SAVE AS FIRST CHARACTER CHUNK ADDR
HRRZM T1,TTBASE ;START OF CHUNKS FOR RCC CHECKER
HLRZ T3,TTCLST## ;NUMBER OF CHUNKS (AGAIN)
IMULI T3,TTCHKS## ;NUMBER OF WORDS IN CHUNK SPACE
ADDI T3,-1(T1) ;LAST (SECTION-RELATIVE) WORD IN CHUNK SPACE
HRRZM T3,RCCMAX## ;SAVE FOR RCC CHECKER
;FALL THROUGH TO NEXT PAGE TO SET UP CHUNK LIST
;FALL THROUGH FROM ABOVE
MOVEI J,TTFTAK ;LOC OF START OF CHAIN
IFN FTXMON,<
TLOA T1,(MS.SCN) ;LIGHT SECTION BIT AND SKIP FIRST TIME
>; END IFN FTXMON
LNKCH1: SSX J,MS.SCN ;SECTION WHERE THE CHUNKS LIVE
MOVEM T1,(J) ;STORE POINTER TO THIS CHUNK
HRRZS J,T1 ;ADVANCE PREVIOUS PTR
ADDI T1,TTCHKS## ;ADVANCE TO NEXT
CAIGE T1,(T3) ;REACHED THE END?
JRST LNKCH1 ;NO, CONTINUE
SSX J,MS.SCN ;SET SECTION NUMBER
MOVEM J,TTFPUT ;NOTE END OF CHAIN
HLRZ T1,TTCLST## ;CHUNK COUNT
SUBI T1,^D10 ;SAFETY FACTOR
MOVEM T1,TTFREN## ;SAVE FOR ALLOCATION ROUTINES
;NOW CLEAR THE RECINT CHARACTER QUEUE
SETZM RCQCNT ;NO CHARACTERS QUEUED
MOVEI T1,RCQBEG ;START OF THE QUEUE
MOVEM T1,RCQPTR ;INIT THE QUEUE PUTTER
MOVEM T1,RCQTKR ;AND THE QUEUE TAKER AS WELL
POPJ P, ;RETURN
;LINK LDBS
LNKLDB: PUSHJ P,SAVE1## ;NEED A SPARE AC
MOVE U,LDBVRG## ;FIRST LDB ADDRESS
SETZ J, ;LDB INDEXING STARTS AT ZERO
MOVE P1,[-LNKTTL##/3,,LNKTTB##] ;ENTRY-BASED AOBJN POINTER TO LNKTTB
LNKLD1: HLL J,0(P1) ;MAKE LINTAB AOBJN FOR THIS ENTRY
LNKLD2: MOVEM U,LINTAB(J) ;POINT TO THIS LDB
DPB J,LDPLNO ;SET UP ITS LINE NUMBER
HRRZ T1,0(P1) ;GET OWNING CPU
DPB T1,LDPCPU ;TELL THE LDB
MOVE T1,1(P1) ;GET QUH,,ISR
HLLZM T1,LDBQUH(U) ;SET QUEUE HEADER
IFE FTXMON,<HRLI T1,T1> ;INDEX FOR PUSHJ
IFN FTXMON,<HRLI T1,(<<T1>B5+MCSEC1>)> ;GLOBAL INDEX FOR PUSHJ
MOVEM T1,LDBISR(U) ;SETUP ISR WORD
MOVE T1,2(P1) ;GET ISB-BITS,,TTW-BITS
HLLZM T1,LDBISB(U) ;SETUP ISB BITS
HRLZM T1,LDBTTW(U) ;AND LTLUSE
PUSHJ P,LDBCLR ;CALL ROUTINE WHICH CLEARS IT UP
ADDI U,LDBLEN ;ADVANCE TO NEXT LDB
AOBJN J,LNKLD2 ;SETUP LINTAB AND ALL LDBS FOR THIS ENTRY
HRRI P1,2(P1) ;ACCOUNT FOR LENGTH OF ENTRIES
AOBJN P1,LNKLD1 ;LOOP OVER ALL LINE DEFINITIONS
SETZM LINSAV## ;IN CASE JUNK GOT IN LINSAV
POPJ P, ;RETURN
SCNINI: CONO PI,PI.OFF ;PREVENT INTERRUPTS
;NOW GO THROUGH ALL THE TTY DDB'S VIA CHAIN, AND KILL ALL THOSE WHICH
; HAVE TTYATC AND ASSCON OFF, BY CALLING TTYREL
SETOM DINITF## ;TTYREL BEING CALLED FROM SYSINI
HLRZ F,SCNDDB+DEVSER ;FIRST REAL TTY DDB IN DEVICE CHAIN
SCNIN1: PUSHJ P,TTYREL ;TTYREL WILL KILL IT (TTYKIL)
; UNLESS TTYATC OR ASSCON ARE ON
MOVEI T2,DEPEVM ;GET "DEVICE DOESN'T NEED EVM" BIT
IORM T2,DEVTYP(F) ;SET BIT
HLRZ F,DEVSER(F) ;DO SAME FOR ALL TTY DDB'S
MOVSI T1,DVTTY ;IS THIS A TTY TOO?
TDNE T1,DEVMOD(F) ;CHECK IN DEVICE MODE WORD
JUMPN F,SCNIN1 ;JUMP IF YES.
;NOW CLEAR ANY PHONY LINKS IN THE LDB'S. I.E., ANY WHICH THINK
; THEY ARE POINTING TO DDB'S BUT THE DDB'S HAVE BEEN KILLED (TTYUSE=0)
MOVSI J,-TTPLEN## ;COUNT OF LDB'S
SCNIN2: MOVE U,LINTAB##(J) ;GET LDB ADDRESS
MOVE T1,LDBDCH(U) ;GET DEVICE BITS
MOVE T2,LDBTTW(U) ;GET LINE TYPE FLAGS
TLNE T2,LTLUSE ;IS LDB "IN USE"?
TRNE T1,LDRPTY ;YES, BUT IS IT A PTY-DRIVEN LINE?
JRST SCNIN3 ;LDB NOT IN USE (OR PTY), SKIP THIS LINE
HRRZ T1,J ;GET LINE # IN T1
PUSHJ P,XTCTTY## ;SEE IF DA28
JRST SCNIN3 ;INACTIVE - IGNORE
JFCL ;ACTIVE - TREAT AS REGULAR
SCNIN3: AOBJN J,SCNIN2 ;DO SAME FOR ALL LDB'S
SKIPN T1,DEVOPR## ;SET UP OPERATOR FOR ERROR MESSAGES
SCNIN4: MOVSI T1,(SIXBIT /CTY/) ;IF NONE, ASSUME CTY.
PUSHJ P,STDOPR ;GET A DDB AND LDB FOR OPR AND SET OPRLDB
JRST SCNIN4 ;NO SUCH GUY. TRY CTY.
; DONT REALLY WANT IT NOW
SETZM DINITF## ;DONE WITH TTYREL
;NOW INITIALIZE THE DATAPHONE HANDLING TABLE
SKIPL J,DSCPTR## ;GET THE DATAPHONE INDEX, IF ANY
JRST SCNIN8 ;NONE IN THIS CONFIGURATION
SETOM TTYDDL## ;CLEAR DIALLER DATA ADDRESS CELL (4 WD BLOCK)
HLLZS J ;CLEAR RIGHT HALF OF POINTER
SCNIN5: MOVEI T3,DSTREQ ;TRANSACTION CODE FOR REQUEST
HRRZ U,DSCTAB##(J) ;SET UP BACK POINTERS TO DATASET TABLE
MOVE U,LINTAB##(U) ;IN THE LDB'S
DPB J,LDPDSC ;STORE THE INDEX
MOVEI U,0(J) ;TABLE INDEX AS LINE NUMBER
PUSHJ P,DSCCAL ;GO GET STATE OF LINE
CAIN T3,DSTNAC ;DC76 NO-ACTION?
JRST SCNIN6 ;YES. DC76 WILL TELL US ABOUT ALL LINES
; (MAY HAVE ALREADY)
CAIN T3,DSTON ;IS CARRIER ON?
JRST SCNIN7 ;YES. GO SET ON STATE IN TABLE
MOVSI T1,DSCICL ;HWC+SWC+FAI+TMM
ANDCAM T1,DSCTAB##(J) ;CLEAR ALL BITS. HE'S OFF
MOVEI T3,DSTOFF ;SEND OFF CODE IN CASE WAS ON
MOVEI U,0(J) ;USING TABLE INDEX AS LINE
PUSHJ P,DSCCAL ;SEND THE OFF CODE
SCNIN6: AOBJN J,SCNIN5 ;COUNT THRU ALL DATAPHONES
JRST SCNIN8 ;END OF TABLE
SCNIN7: MOVSI T1,DSCIC1 ;LINE IS ON. SET HWC+SWC BITS IN TABLE
IORM T1,DSCTAB##(J) ; ..
MOVSI T1,DSCIC2 ;AND CLEAR FAIL AND TIME BYTE TMM+FAI
ANDCAM T1,DSCTAB##(J) ; ..
JRST SCNIN6 ;ON TO NEXT LINE
SCNIN8: MOVEI J,TCONLN## ;START WITH CTY
SCNIN9: MOVEI T1,ISRINI ;FUNCTION TO INIT A LINE
MOVE U,LINTAB##(J) ;POINT TO LDB
PUSH P,J
PUSHJ P,@LDBISR(U) ;INIT THE LINE
POP P,J
SOJGE J,SCNIN9 ;LOOP OVER LINES HDW FIRST, SINCE PI IS OFF
CONO PI,PI.ON ;OK TO INTERRUPT
POPJ P, ;END OF SCNINI
TTYINI: SE1ENT ;ENTER SECTION ONE
PUSHJ P,SAVE4## ;SAVE P1-P4
MOVEI T1,COMTIV ;SET UP COMMAND INPUT
MOVEM T1,.CPTIV## ; DISPATCH VECTOR
MOVEI T1,CCTYO ;SETUP OUTPUT DISPATCH
MOVEM T1,.CPTOA## ; ..
TTINI1: MOVSI P1,-<TCONLN##+1> ;COUNT OF REAL (TTY ONLY) LDBS
MOVEI P2,TTFCXI ;SET FOR STARTUP CUSP
MOVE T1,STOPTN## ;GET STARTUP OPTION NAME
CAME T1,['NOINIT'] ;WAS IT "NOINITIA"?
SKIPE REFLAG## ;BUT IF DISK IS BEING REFRESHED?
MOVEI P2,TTFCXR ;JUST GIVE NORMAL MESSAGE
MOVSI P3,LTLUSE ;FLAG TO TEST FOR USELESS LINES
SKIPE [DSDRIC##] ;IF DATASETS RUN THE INITIA CUSP,
TDZA P4,P4 ;THEN SET A NULL TEST
MOVEI P4,LDRDSD ;NO--SETUP TO TEST FOR DATASET
TTINI2: MOVE U,LINTAB##(P1) ;SET UP AN LDB
MOVEI T1,(P2) ;GET FORCED COMMAND INDEX
TDNE P3,LDBTTW(U) ;IF ALLOCATED,
TDNE P4,LDBDCH(U) ;AND NOT AN EXCLUDED DATASET
TRNA ;(WRONG--SKIP IT)
PUSHJ P,TTFORC ;YES--FORCE A COMMAND
AOBJN P1,TTINI2 ;LOOP FOR ALL LDBS
TTINI3: MOVE T1,TICSEC## ;TICKS PER SECOND
IMULI T1,^D10 ;MAKE THAT 10 SECONDS
HRLI T1,CLKCMD## ;ROUTINE TO CALL
IDPB T1,CLOCK## ;IN 10 SECONDS
MOVEI T1,1 ;SET TO SMASH COMCNT
MOVE T2,STOPTN## ;GET STARTUP OPTION NAME
CAME T2,['NOINIT'] ;WAS IT "NOINITIA"?
EXCH T1,COMCNT## ;GET NUMBER TO DO
IDPB T1,CLOCK## ;DO THEM IN 10 SECONDS
MOVSI T1,(POPJ P,) ;ONCE ONLY
MOVEM T1,SCNDSP+DINI ;SO DON'T CALL US AGAIN
;HERE TO FIXUP TTY EDITOR
TTINI4: SKIPN [M.EDIT##] ;DO WANT TO ENABLE IT?
POPJ P, ;NO--DONE WITH TTYINI
MOVE T1,[<TOP.IF+TOP.SA+TOP.RT>+<TOPEDT>] ;DESIRED TRMOP ENTRY
MOVEM T1,TOPTB1+107 ;FIX IT
MOVE T1,[^-<TTCMXL##_-9>,,TTCWDT##] ;POINT TO TTY COMMANDS
MOVE T2,[SIXBIT/.EDIT/] ;AND THE HACKED NAME
PUSHJ P,FNDNAM## ;POINT TO IT
POPJ P, ;PUNT
MOVE T2,['EDITOR'] ;WHAT WE WANT IT TO BE
MOVEM T2,TTCWDT##(T1) ;UPDATE THE COMMAND IN THE TABLE
POPJ P, ;FINALLY DONE WITH TTYINI
$HIGH
SUBTTL TRANSMIT INTERRUPT ROUTINE
;ENTRY FROM DEVICE-DEPENDENT INTERRUPT SERVICE ROUTINE ON A
; TRANSMIT-DONE INTERRUPT. THE HARDWARE LINE NUMBER IS
; IN AC U. ENTER AT XMTIN1 IF U IS SETUP TO THE LDB ADDRESS.
XMTINT::MOVE U,LINTAB##(U) ;GET LINE DATA BLOCK ADDRESS
XMTIN1::SE1ENT ;ENTER SECTION 1
MOVSI T1,L1LOFL
ANDCAM T1,LDBOFL(U)
SKIPGE LDBDCH(U) ;ARE WE EXPECTING THIS?
JRST XMTDMC ;NO, GO UNLOCK KEYBOARD
PUSHJ P,XMTCHR ;GET A CHARACTER FROM THE CHUNKS
POPJ P, ;END OF STRING
MOVSI T1,LPLIRM ;IRMA BIT
ANDCAM T1,LDBPAG(U) ;CLEAR SINCE JUST SENT A CHARACTER
MOVEI T1,ISRTYP ;FUNCTION DESIRED FROM DEVICE DRIVER
PJRST @LDBISR(U) ;GO DO IT
;XMTCHR -- ROUTINE TO RETURN THE NEXT CHARACTER TO SEND FROM
; A TERMINAL OUTPUT BUFFER
;
;CALL
; MOVE U,LDB ADDRESS
; PUSHJ P,XMTCHR
; <IDLE CONDITION>
; <CHARACTER IN T3>
XMTCHR::SE1ENT ;ENTER SECTION 1
MOVSI T1,LDLIDL ;CLEAR THIS NOW, XMTIDL WILL SET IF NEEDED
ANDCAM T1,LDBDCH(U) ;DON'T LET REMOTES ECHO
MOVE T1,.CPTMF## ;GET COUNT OF CLOCK TICKS
CAIL T1,7 ;IF TOO MANY,
POPJ P, ;GET OUT OF HERE BEFORE WE KAF
; (IRMA WILL GET US BACK HERE)
XMTCH1: SCNOFF ;MAKE SURE BITS ARE CONSISTENT
HLLZ T1,LDBOST(U) ;GET STATES WORD
JFFO T1,[JRST @XMTDSP(T2)] ;DISPATCH ON SPECIAL CONDITIONS
XMTCH2: SOSGE T4,LDBTOC(U) ;COUNT DOWN LENGTH OF OUTPUT STREAM
JRST ZAPBUF ;IF EMPTY STREAM. GO RESET COUNT
LDCHKR T3,LDBTOT(U),XMTABO ;TAKE NEXT CHARACTER FROM STREAM
PUSHJ P,TPCOUT ;FUDGE FOR TWO-PART CHARACTERS
XMTCH3: SCNON ;HAVE CHARACTER, ALLOW OTHERS TO ACCESS
CAIN T4,^D50 ;HAVE WE REACHED THE WAKE THRESHOLD?
PUSHJ P,XMTWAK ;YES, GO WAKE JOB IF WAITING
XMTCH4: TRNE T3,CK.MET ;IS THIS A META CHARACTER?
JRST XMTMET ;YES, GO DISPATCH THE FUNCTION
TRNE T3,CK.IMG ;IS THIS AN IMAGE MODE CHARACTER?
JRST XMTCN7 ;YES, COUNT IT AND RETURN
ANDI T3,CK.CHR ;CLEAR POSSIBLE PARITY BIT
SKIPGE T1,CHTABL(T3) ;GET SPECIAL BITS, TEST FOR UNUSUAL CHAR
JRST XMTSPO ;THIS MAY REQUIRE FILL OR BLANK SUPPRESS
AOSG LDBHPS(U) ;INCREMENT HORIZONTAL POSITION
JRST XMTCN7 ;RETURN IF NOT END OF CARRIAGE
PUSHJ P,PTBTCH## ;CHECK FOR REGULAR PTY
JRST XMTCN7 ;NO FREE CRLF FOR LOG FILES
MOVE T2,LDBDCH(U) ;GET CHARACTERISTICS WORD
TLNE T2,LDLNFC ;USER WANT FREE <CR><LF>?
JRST XMTCN7 ;NO, JUST SEND THE CHARACTER
TLZ T1,CHALT!CHUAE!CHCRE ;OUTPUT CHARACTERS GO STRAIGHT
TLO T1,CHFILO ;OUTPUT FILL
PUSHJ P,SETCRF ;YES, GO SETUP A CRLF FILLER
JRST XMTCH1 ; AND SEND THE FILLER INSTEAD
JRST XMTCN7 ;GO SEND THE CHARACTER AFTER ALL!
;COUNT UP THE CHARACTERS PHYSICALLY OUTPUT AND RETURN
XMTCNT: CAIN T3,12 ;LINEFEED?
PUSHJ P,INCPCT ;BUMP PAGE COUNTER
XMTCN4: ANDI T3,CK.CHR!CK.IMG ;TRIM OFF FUNNY BITS
XMTCN7:
IFN FTMIC,<
MOVE T4,LDBMIC(U) ;GET MIC BITS
TLNE T4,LDLSIL ;LINE SILENCED
JRST XMTCH1 ;YES, EAT THE CHARACTER
>
XMTCN8: AOS LDBOCT(U) ;COUNT CHARACTERS OUTPUT THIS LINE
AOS %SCNXI ;AND TOTAL CHARACTERS OUTPUT BY SYSTEM
IFN FTRSP,<AOS .CPNXI##> ;PER CPU AS WELL
PJRST CPOPJ1## ;RETURN THE CHARACTER
;HERE FOR UNUSUAL CHARACTER ON OUTPUT
XMTSPO: MOVSI T2,LPLBLK
TDNE T2,LDBPAG(U)
PUSHJ P,BLSUPO ;CHECK FOR TERMINAL NO BLANKS
PUSHJ P,ADJHP
PUSHJ P,SETFLO ;SETUP FILLERS IF ANY NEEDED
JRST XMTCH1 ;FILLS NEEDED, GO SEND THEM FIRST
CAIN T3,12 ;IF LINE FEED
PUSHJ P,INCPCT ; INCREMENT PAGE COUNT
JRST XMTCN7 ;NONE NEEDED, JUST RETURN IT
;HERE WHEN AN IMBEDDED FUNCTION (META) CHARACTER IS FOUND IN THE OUTPUT STREAM
;TO DISPATCH UPON IT AND RETURN VIA SETCHP
XMTMET: TRNE T3,CK.NIS ;IS THIS REALLY HERE?
JRST XMTCH1 ;NO, SKIP IT
CAIL T3,CK.MET ;IS THIS IN RANGE?
CAIL T3,CK.MET+METLEN ;BOTH WAYS?
JRST XMTCH1 ;NO, SKIP IT ** MAYBE STOPCD HERE? **
PUSHJ P,XMTME1 ;CALL WORKHORSE (FOR SAVING ACS)
JRST SETCHP ;GIVE NON-SKIP AFTER REQUEUEING LINE
JRST XMTCH1 ;KEEP LOOKING FOR A CHARACTER
XMTME1: PUSHJ P,SAVE2## ;PRESERVE OUR REGISTERS
MOVE P1,METABL-CK.MET(T3) ;GET DISPATCH VALUE
TLNN P1,CH2PC ;NEED AN ARGUMENT?
PJRST (P1) ;NO, JUST DISPATCH IT
SCNOFF ;FOR LDCHK'ING
SOSGE LDBTOC(U) ;IS THE ARGUMENT STILL THERE?
JRST ZAPBUF ;NO, GIVE UP
LDCHKR P2,LDBTOT(U),XMTABO ;YES, GET IT
SCNON ;CAN ALLOW OTHERS AGAIN
PJRST (P1) ;NOW CALL THE ROUTINE (AND RETURN A LEVEL)
;ROUTINE TO SET USER'S VALUE OF LDLTAB DURING OUTPUT
METTAB: LDB T2,LDPTAB ;GET PREVIOUS VALUE
CAMN T2,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;DON'T BOTHER ANYBODY
DPB P2,LDPTAB ;STORE IN LDB
POPJ P, ;GIVE SETCHP RETURN
;ROUTINE TO SET USER'S VALUE OF LDLFRM DURING OUTPUT
METFRM: LDB T2,LDPFRM ;GET PREVIOUS VALUE
CAMN T2,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;DON'T BOTHER ANYBODY
DPB P2,LDPFRM ;STORE IN LDB
POPJ P, ;GIVE SETCHP RETURN
;ROUTINE TO SET USER'S VALUE OF LDLNFC DURING OUTPUT
METNFC: LDB T2,LDPNFC ;GET PREVIOUS VALUE
CAMN T2,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;DON'T BOTHER ANYBODY
DPB P2,LDPNFC ;STORE IN LDB
POPJ P, ;GIVE SETCHP RETURN
;ROUTINE TO SET USER'S VALUE OF LDPWID DURING OUTPUT
METWID: LDB T2,LDPWID ;GET PREVIOUS VALUE
CAMN T2,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;DON'T BOTHER ANYBODY
PUSHJ P,HPOS ;GET CURRENT HPOS
DPB P2,LDPWID ;STORE NEW WIDTH IN LDB
MOVE P2,T2 ;MOVE HPOS FOR METHPS
;PJRST METHPS ;FALL INTO METHPS TO RESTORE HPOS
;ROUTINE TO SET USER'S VALUE OF HPOS DURING OUTPUT
METHPS: PUSHJ P,HPOS ;GET PREVIOUS VALUE
CAMN T2,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;DON'T BOTHER ANYBODY
LDB T2,LDPWID ;GET CARRIAGE WIDTH
SUB T2,P2 ;FORM COLUMNS TO GO UNTIL RIGHT MARGIN
MOVNM T2,LDBHPS(U) ;STORE AS COUNT UP VALUE
POPJ P, ;GIVE SETCHP RETURN
;ROUTINE TO FORCE LEFT MARGIN DURING OUTPUT
METFLM: PUSHJ P,HPOS ;GET HPOS
JUMPE T2,CPOPJ1## ;DONE IF ALREADY THERE
AOS (P) ;SET FOR SKIP RETURN
PJRST METNLF ;ELSE, TYPE OUT A NEWLINE
;ROUTINE TO SET L1LDEM
METDEN: SKIPA T2,[IORM T1,LDBBYT(U)] ;INSTRUCTION TO SET THE BIT
METDEF: MOVE T2,[ANDCAM T1,LDBBYT(U)] ;INSTRUCTION TO CLEAR IT
SCNOFF ;FIGHT RACES
MOVSI T1,L1LDEM ;THE BIT IN QUESTION
XCT T2 ;SET OR CLEAR AS REQUESTED
SCNON ;ALLOW OTHERS AGAIN
JRST XMTECD ;DELETE CHARACTER AND GET ANOTHER TO ECHO
;ROUTINE TO CALL SETCHP SYNCHRONOUSLY WITH OUTPUT
METCHP: MOVSI T1,LDLIDL ;GET IDLE BIT
IORM T1,LDBDCH(U) ;LIGHT IT SO FE'S WILL CALL US AGAIN
PJRST SETCHP ;RE-QUEUE LINE & RETURN NON-SKIP FROM XMTCHR
;ROUTINE TO START UP A CONTROL-R (RE-TYPE) FOR XMTECH
METRTS: PUSHJ P,METRT1 ;CALL WORKHORSE
JRST XMTCH1 ;LOOK FOR MORE OUTPUT
METRT1: PUSHJ P,SAVE3## ;NEED SOME EXTRA ACS
SCNOFF ;NO INTERRUPTS
TRC T3,MC.RTS^!MC.RTE ;ALTER THE CHARACTER
DPB T3,LDBECT(U) ;SAVE FOR TURNING OFF ^R MODE WHEN DONE
SETZB P1,P2 ;CLEAR COUNTS OF CHARACTERS PASSED
SKIPN T4,LDBBKU(U) ;POINT TO LAST LINE BREAK
MOVE T4,LDBTIT(U) ;OR BEGINNING IF NO BREAK
MOVE P3,T4 ;SAVE BEGIN POINTER
EXCH T4,LDBECT(U) ;RESET TAKER, GET STOP POINTER
METRT2: CAMN T4,LDBECT(U) ;HAVE WE CAUGHT UP?
JRST METRT3 ;YES, CLEAN UP
LDCHK T3,LDBECT(U),SONPJ1 ;GET A CHARACTER
TRNE T3,CK.NIS ;IF MISSING,
AOS P2 ;COUNT ANOTHER INVISIBLE
AOS P1 ;AND ANOTHER CHARACTER IN ANY CASE
JRST METRT2 ;LOOP OVER ALL CHARACTERS TO BE RETYPED
METRT3: MOVEM P3,LDBECT(U) ;RESET ECHO TAKER AGAIN
ADDM P1,LDBECC(U) ;COUNT HOW MANY CHARACTERS TO RE-ECHO
ADDM P2,LDBIEC(U) ;AND HOW MANY WERE INVISIBLE
MOVNS P1 ;NEGATE BECAUSE SUBM GOES WRONG WAY FOR THIS
MOVNS P2 ; ...
ADDM P1,LDBTIC(U) ;THIS MANY FEWER FOR READ-IN
ADDM P2,LDBIIC(U) ;AND SIMILARLY FOR HOW MANY ARE INVISIBLE
MOVSI T1,LDLCRP ;CONTROL-R PENDING BIT
IORM T1,LDBDCH(U) ;LIGHT IT FOR TYICC4 & XMTECH
SCNON ;SAFE TO ALLOW OTHERS NOW
PUSHJ P,PRSKL ;SPACE OVER PROMPT AND CLEAR THE LINE
JRST METRT4 ;NOT A DISPLAY, DO IT THE OLD WAY
MOVEI T3,MC.CHP ;SET TO TELL FE'S ABOUT HPOS
PJRST SETFCE ;STUFF IN FILL CHUNKS AND RETURN
METRT4: MOVE T2,FLLBSC ;BACKSLASH-THEN-CRLF
MOVSI T1,L2LDEL ;DELETE SEQUENCE BIT
TDNN T1,LDBBY2(U) ;WAS THERE AN OPENING BACKSLASH?
IBP T2 ;NO, DON'T TYPE A CLOSING ONE
ANDCAM T1,LDBBY2(U) ;MAKE SURE FOR LATER
PJRST SETFLE ;STUFF THE SEQUENCE IN THE CHUNKS & GO
;ROUTINE TO SHUT OFF CONTROL-R PROCESSING FOR TYICC4 & XMTECH
METRTE: MOVSI T1,LDLCRP ;CONTROL-R PENDING BIT
ANDCAM T1,LDBDCH(U) ;CLEAR IT
MOVEI T3,"R"-100 ;THIS WAS A CONTROL-R
PJRST XMTECD ;CHANGE TO DELETED CHARACTER AND TRY FOR XMT'S
;HERE WHEN A SPECIAL CONDITION BIT IS SET IN THE LDB. THESE BITS
;ARE PLACED IN LDBOST IN SUCH A WAY THAT A JFFO INSTRUCTION CAN
;BE USED TO FIND THE CONDITION THAT NEEDS ATTENTION FIRST.
;HERE TO TYPE XOFF/XON STRINGS
XMTXFP: SCNON ;RELEASE INTERLOCK
ILDB T3,LDBXNP(U) ;GET NEXT CHARACTER FROM XON/XOFF FILL POINTER
JUMPN T3,XMTCN8 ;RETURN IT IF IT'S THERE
MOVSI T3,LOLXFP ;NO, GET BIT THAT BROUGHT US HERE
ANDCAM T3,LDBOST(U) ;CLEAR IT
SETZM LDBXNP(U) ;AND THE POINTER
JRST XMTCH1 ;AND TRY AGAIN
;HERE TO TYPE A BELL (TTY SBELL OR INPUT LOST)
XMTNBS: SCNON ;RELEASE INTERLOCK
MOVSI T3,LOLNBS ;CLEAR BIT THAT GOT US HERE
ANDCAM T3,LDBOST(U) ;IN THE LDB
MOVEI T3,007 ;GET A BELL (SANS PARITY)
JRST XMTCN8 ;AND RETURN IT
;HERE FOR ECHO/FILL OUTPUT TO BE TYPED
XMTESP: ;SCNOFF ;NO INTERRUPTS FOR A FEW INSTRUCTIONS
SOSGE LDBEOC(U) ;COUNT ANOTHER ECHO OUTPUT
JRST XMTES1 ;DO SANITY CHECK WHEN STREAM LOOKS EMPTY
LDCHKR T3,LDBEOT(U),XMTES2 ;GET NEXT CHARACTER FOR ECHO
PUSHJ P,TPCFIL ;CHECK FOR FILL EXPANSION
SCNON ;ALLOW INTERRUPTS AGAIN
TRNN T3,CK.MET ;UNLESS A FUNCTION CHARACTER
JRST XMTCNT ;COUNT IT AND RETURN
MOVE T1,T3 ;YES, COPY IT
ANDI T1,CK.CHR ;KEEP ONLY THE FUNCTION INDEX
MOVE T1,METABL(T1) ;GET THE DISPATCH
PJRST (T1) ;CALL THE FUNCTION
XMTES1: SETZM LDBEOC(U) ;DON'T GO NEGATIVE
MOVE T3,LDBEOT(U) ;GET TAKER
CAME T3,LDBEOP(U) ;MUST MATCH PUTTER
PUSHJ P,RCDSTP ;ERROR IF NOT EQUAL
XMTES2: MOVSI T3,LOLESP ;CLEAR BIT THAT GOT US HERE
ANDCAM T3,LDBOST(U) ;IN THE LDB
SCNON ;ALLOW INTERRUPTS AGAIN
JRST XMTCH1 ;TRY FOR NEXT CHARACTER
;HERE FOR 'NOT NOW' OUTPUT
XMTNNP: SCNON ;RELEASE INTERLOCK
ILDB T3,LDBNNP(U) ;GET NEXT CHARACTER FROM FILL POINTER
CAILE T3,FLLFLG ;IS IT A REAL CHARACTER
JRST XMTCH4 ;YES, USE IT
SCNOFF ;AVOID RACES
MOVSI T2,LOLNNP ;CLEAR BIT THAT BROUGHT US HERE
ANDCAM T2,LDBOST(U) ;FROM THE LDB
SETZM LDBNNP(U) ;AND THE BYTE POINTER
SCNON ;END OF POSSIBLE RACE
JUMPE T3,XMTCH1 ;TRY AGAIN IF END OF STRING
PUSHJ P,METNLF ;TYPE CRLF IF WAS FILLER FLAG
JRST XMTCH1 ;THEN TRY AGAIN
;HERE TO RE-EAT OUTPUT
XMTREO: ;SCNOFF ;FIGHT RACES
MOVSI T1,LOLREO ;BIT THAT BROUGHT US HERE
ANDCAM T1,LDBOST(U) ;CLEAR IT
LDB T3,LDPREO ;GET CHARACTER TO RE-DO
SCNON ;ALLOW OTHERS AGAIN
PJRST XMTCH4 ;AND USE IT AGAIN
;HERE TO RE-EAT ECHO
XMTREE: ;SCNOFF ;FIGHT RACES
MOVSI T1,LOLREE ;BIT THAT BROUGHT US HERE
ANDCAM T1,LDBOST(U) ;CLEAR IT
LDB T3,LDPREE ;GET CHARACTER TO RE-DO
TRNE T3,CK.IMG ;SINCE WE WANTED TO ECHO IT,
TRO T3,CK.MET ;IMAGE MEANS QUOTED AND NOT UNECHOED
PUSHJ P,SPCHEK ;GET ITS BITS
TRN ;DON'T CARE IF SPECIAL OR NOT
SCNON ;ALLOW OTHERS AGAIN
PJRST XMTEC4 ;AND USE CHARACTER AGAIN
;HERE FOR FORCED STRING OUTPUT (USED ONLY BY SEND ALL)
XMTFSP: SCNON ;RELEASE INTERLOCK
ILDB T3,LDBFLP(U) ;GET NEXT CHARACTER FROM FILL POINTER
CAILE T3,FLLFLG ;IS IT A REAL CHARACTER?
JRST XMTCH4 ;YES, USE IT
SCNOFF ;AVOID RACES
MOVSI T2,LOLFSP!LOLSAP ;CLEAR BITS THAT BROUGHT US HERE
ANDCAM T2,LDBOST(U) ;FROM THE LDB
SETZM LDBFLP(U) ;AND THE BYTE POINTER
SCNON ;END OF POSSIBLE RACE
JUMPE T3,XMTCH1 ;IF NULL, JUST TRY FOR NEXT CHARACTER
PUSHJ P,METNLF ;TYPE A CRLF VIA THE ECHO STREAM
MOVEI T3,"." ;GET A DOT JUST IN CASE
MOVSI T2,LDLCOM ;COMMAND LEVEL BIT
TDNE T2,LDBDCH(U) ;USER AT COMMAND LEVEL?
PUSHJ P,SETFCE ;YES, TYPE THE DOT AS WELL
JRST XMTCH1 ;TRY FOR NEXT CHARACTER TO OUTPUT
;HERE WHEN NEW SEND ALL STRING TO BE SENT (COMCON HAD TO DEFER THE SEND)
XMTSAP: ;SCNOFF ;AVOID RACES
; MOVSI T2,LOLSAP ;CLEAR BIT THAT BROUGHT US HERE
; ANDCAM T2,LDBOST(U) ;FROM THE LDB
SOSGE SNDCTR## ;ONE FEWER LINE WAITING
SETZM SNDCTR## ;DON'T LET THE COUNT GO NEGATIVE!
MOVE T2,SNDPTR## ;GET FILL POINTER FROM COMCON
PUSHJ P,SETFPT ;SET THE FILL POINTER (DOES A SCNON)
JRST XMTCH1 ;AND TYPE FROM THE FILL POINTER
...OST==1B0 ;START OF STATE BITS
DEFINE OSTAT(NM,RTN)<
LOL'NM==:(...OST)
...OST==...OST_-1
IFB<RTN>,< IFIW XMT'NM>
IFNB<RTN>,< IFIW XMT'RTN>
IF1,<IFG 1B17-...OST,<PRINTX % LDBOST LH IS FULL WITH LOL'NM>>
>
XMTDSP:
OSTAT XFP ;XOFF PENDING
OSTAT NBS ;NEED BELL SENT
OSTAT ESP ;ECHO STREAM PENDING
OSTAT FSP ;FORCED STRING PENDING
OSTAT SAP ;SEND ALL PENDING
OSTAT STP,IDL ;XOFF ON LINE
OSTAT SSO,IDL ;SCNSER STOPPED OUTPUT
OSTAT NNP ;'NOT NOW' POINTER
OSTAT REO ;RE-EAT OUTPUT
OSTAT REE ;RE-EAT ECHO
OSTAT PIM,CH2 ;IN PIM MODE
OSTAT MIC ;CONTROLLED BY MIC
;HERE WHEN CHUNKS MESSED UP, TIME TO IDLE THE LINE
XMTABO:!
;HERE TO IDLE THE LINE SINCE IT HAS NO MORE CHARACTERS LEFT TO OUTPUT
XMTIDL: MOVSI T1,LDLIDL ;LINE IS IDLE BIT
IORM T1,LDBDCH(U) ; SET IN LDB
MOVSI T1,LPLIRM ;IRMA BIT
ANDCAM T1,LDBPAG(U) ; CLEAR
SCNON ;RELEASE TERMINAL SERVICE INTERLOCK
HRRZ F,LDBDDB(U) ;ADDRESS OF LINKED DDB
JUMPE F,CPOPJ## ;JUMP IF NO DDB
PUSH P,J ;SAVE J
LDB J,PJOBN## ;GET JOB NUMBER
MOVE T1,JBTSTS##(J) ;GET JOB STATUS
TRNE T1,JS.NTO ;HIBERING FOR NON-BLOCKING TTY OUTPUT?
PUSHJ P,WAKEJB## ;YES--WAKE HIM UP
POP P,J ;RESTORE J
XMTDMC: HRRZ F,LDBDDB(U) ;IF NO DDB ALL DONE
JUMPE F,CPOPJ## ;IF NO DDB.
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
XMTWAK:
IFN FTNET,<
SKIPGE LDBREM(U) ;IF THIS IS A VTM LINE
PJRST VTMENQ## ; QUEUE THE LINE SO WE SEND MORE DATA-REQUESTS
>
IFN FTMIC,<
SKIPN T1,LDBMIC(U) ;CONTROLLED BY MIC?
JRST XMTWK1 ;IF NOT
IFN FTMLOG,<
TLNE T1,LDLLOG ;LOGGING
PUSHJ P,MLOGOF ;TIDY UP
> ;END IFN FTMLOG
PUSHJ P,MICWAK ;WAKE MIC
> ;END IFN FTMIC
XMTWK1: HRRZ F,LDBDDB(U)
JUMPE F,CPOPJ##
MOVE S,DEVIOS(F)
TLNE S,IOW ;IO WAIT?
JUMPL S,TTWAKE ;IF OUTPUT, GO WAKE JOB
POPJ P, ;IF INPUT, RETURN
;PACKED IMAGE MODE (PIM) TRANSMIT INTERRUPT.
REPEAT 0,<
XMTPIM: SCNOFF
SOSGE T4,LDBTOC(U) ;COUNT DOWN
PJRST ZAPPI1 ;IF EXHAUSTED
LDCHKR T3,LDBTOT(U),XMTABO ;TAKE A CHARACTER, RETURN STALE CHUNKS
SCNON ;ALLOW INTERRUPTS
CAIN T4,^D50 ;IF LESS THAN 50. CHARS LEFT
PUSHJ P,XMTWAK ;WAKE UP THE ATTACHED JOB
TRNE T3,CK.MET ;IF META,
JRST XMTMET ;THEN DO THE FUNCTION
JRST XMTCN7 ;ELSE, COUNT AND RETURN THE CHARACTER
> ;END OF REPEAT 0
;HERE WHEN THE OUTPUT STREAM COUNT IS EXHAUSTED. RESET IT TO ZERO
;AND SET THE LINE IDLE. COME HERE ONLY WITH SCANNER INTERLOCK SET.
ZAPPI1: SETZM LDBTOC(U) ;COUNT IS PROBABLY NEGATIVE NOW
MOVE T2,LDBTOT(U) ;MAKE SURE PUTTER MATCHES TAKER
CAME T2,LDBTOP(U) ;MAKE SURE BOTH POINTERS MATCH
PUSHJ P,RCDSTP ;NO, DIE NOW
PJRST XMTIDL ;IDLE THE LINE
;HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBMIC IS NON-ZERO
XMTMIC:
IFN FTMIC,< ;IF MIC
IFN FTMLOG,<
MOVE T2,LDBMIC(U)
TLNE T2,LDLLOG ;HAS HE ASKED FOR LOG
SKIPE LDBLOT(U) ;HAS HE GOT A LOG TAKER
JRST MICLG3
MOVE T2,LDBTOT(U) ;MAKE COPY OF TAKER
MOVEM T2,LDBLOT(U)
MICLG3:
> ;END OF FTMLOG CONDITIONAL
PUSHJ P,HPOS ;GET HORZONTAL POSITION ON LINE
JUMPN T2,XMTOK ;IN COLUMN 1?
SKIPE T2,LDBMIC(U) ;IS HE RUNNING MIC OR
TLNN T2,LDLRSP!LDLRSY ;WANTS RESPONSE FEATURE
JRST XMTOK1 ;NO - MUST NOT INTERFERE
TLNE T2,LDLERC ;HAS HE HAD ERROR?
TLNE T2,LDLMCC ;AND NOT ^C
JRST XMTOK1 ;NO - IGNORE
SKIPN LDBTOC(U) ;IS THERE A CHARACTER WAITING?
JRST XMTOK1 ;NO, IGNORE
MOVE T4,LDBTOT(U) ;COPY OF OUTPUT TAKER
LDCHK T3,LDBTOT(U),XMTABO ;PREVIEW NEXT CHARACTER
MOVEM T4,LDBTOT(U) ;RESTORE POINTER
LDB T2,LDP.ER ;GET ERROR CHAR
JUMPE T2,XMTOK ;MUST BE ONE
ANDI T3,CK.CHR ;JUST 7 BITS
MOVSI T4,LDLRSY!LDLCHK;SETUP TO SET THE SYNC
CAIE T3,"?" ;IS IT A "?"
CAMN T3,T2 ; OR THE ERROR CHARACTER
IORM T4,LDBMIC(U) ;YES, SET THE SYNCH. BITS
MOVE T2,LDBMIC(U) ;RETRIEVE THE BITS
TLNN T2,LDLRSY ;IF WE DIDN'T SET THE SYNCH BIT,
JRST XMTOK1 ;THEN DON'T CLEAR THE RESPONSE BIT
TLNN T2,LDLRSP ;BEEN THIS WAY BEFORE
JRST XMTECH ;YES JUST DO ECHOING
MOVE T4,LDBBYT(U) ;GET WORD WITH END OF ERROR LINE BIT
TLNE T4,L1LEEL ;IF SET,
JRST MICRSC ;GO WAKE UP MIC
HRRZ F,LDBDDB(U)
JUMPE F,XMTECH ;NO ATTACHED DDB
MOVE S,DEVIOS(F)
MOVE T2,LDBDCH(U) ;GET WORD WITH COMMAND WAIT BIT
TLNN S,IOW ;IN IO WAIT?
TLNE T2,LDLCOM ;OR IN COMMAND WAIT
JRST MICRSC ;YES TO EITHER--GO WAKE UP MIC
JRST XMTECH ;NO FORGET IT
MICRSC: MOVSI T2,LDLRSP
ANDCAM T2,LDBMIC(U) ;SAY SYNC
PUSHJ P,MICWAK
JRST XMTECH ;AND PUT THE PLUG IN
XMTOK: MOVE T2,LDBMIC(U) ;GET MIC BITS
XMTOK1: TLNE T2,LDLRSY ;WAITING FOR MIC TO TAKE RESPONSE
JRST XMTECH ;YES, KEEP THE PLUG IN
IFN FTMLOG,<
SKIPN LDBLOT(U) ;ARE WE LOGGING THIS?
JRST XMTCH2 ;NO, GO TAKE CHARACTER NORMALLY
SOSGE LDBTOC(U) ;DECREMENT COUNT OF CHARACTERS AND TEST
JRST ZAPBUF ;IF OUTPUT STREAM NOW EMPTY
LDCHK T3,LDBTOT(U),XMTABO ;TAKE A CHARACTER OUT OF THE STREAM
AOS LDBLOC(U) ;COUNT UP THE NUMBER TO BE LOGGED
JRST XMTCH3 ; AND JOIN PROCESSING
> ;END IFN FTMLOG
> ;END OF IF MIC
;ENTER HERE WITH SCNOFF TO CLEAR LDBTOC AND CHECK FOR ECHO
ZAPBUF: MOVSI T1,LOLPIM ;PIM TEST
TDNE T1,LDBOST(U) ;IF IN PIM,
JRST ZAPPI1 ;DON'T BOTHER WITH XMTECH
SETZM LDBTOC(U) ;ZERO COUNT
MOVE T1,LDBTOP(U) ;GET PUTTER
CAME T1,LDBTOT(U) ;MUST MATCH TAKER
PUSHJ P,RCDSTP ; OOPS, SOMETHING IS WRONG
IFN FTNET,<
SKIPL LDBREM(U) ;IS THIS A VTM LINE?
JRST XMTECH ;NO, LOOK FOR ECHO TO OUTPUT
PUSHJ P,XMTIDL ;YES, MARK LINE IDLE AND RELEASE INTERLOCK
PJRST VTMENQ## ; WE MUST BE SURE TO SEND DATA-REQUESTS
; NOW THAT WE'RE OUT OF DATA.
> ;END IFN FTNET
;FALL INTO XMTECH
;HERE WHEN BUFFERED AND FILLER OUTPUT DONE, AND LDBECT IS NON-ZERO
;NEED TO ECHO A CHARACTER THAT HAS BEEN TYPED IN.
XMTECH: MOVE T1,LDBDCH(U) ;SEE IF SHOULD DEFER ECHOING
TLNE T1,LDLCRP ;CONTROL-R SYNCH BIT SET?
JRST ECHCNR ;YES, GO CHECK OUT ^R THINGS
MOVE T1,LDBBYT(U) ;NO, GET WORD CONTAINING DEFERRED ECHO BITS
TLNN T1,L1LDEM ;IF NOT IN LH DEFERRED ECHO,
TRZ T1,L1RDEM ;THEN GIVE RH BIT TIME TO CATCH UP TO US
SKIPL LDBBKB(U) ;IF BREAK SET SPECIFIED, ALWAYS DEFERRED ECHO
TRNE T1,L1RDEM ;DEFERRED ECHO MODE SELECTED?
TRNE T1,L1RDEL!L1RDEC; HAS AN INPUT REQUEST BEEN MADE YET?
TLNE T1,L1LUNR ;AND NOT BLOCKED BY UNREAD?
CAIA ;DEFERRED AND NOT REQUESTED YET, MAYBE IDLE LINE
JRST ECHCNR ;NO, IT'S FINE TO ECHO
HLLZ T1,LDBOST(U) ;GET STATE BITS
TLZ T1,LOLMIC ;IGNORE BITS THAT MIGHT HAVE BROUGHT US HERE
JUMPE T1,XMTIDL ;RETURN EMPTY-HANDED IF NOTHING TO SEND
SCNON ;YES, RELEASE INTERLOCK
JRST XMTCH1 ;AND TRY AGAIN
ECHCNR: SOSGE LDBECC(U) ;ANY LEFT TO ECHO?
JRST ZAPECH ;NO, FINISH UP
LDCHK T3,LDBECT(U),XMTABO ;TAKE CHARACTER FROM INPUT, SAVE CHUNKS
TRNE T3,CK.NIS ;INIVISIBLE CHARACTER?
JRST [SOS LDBIEC(U) ;YES, COUNT ONE LESS TO ECHO
AOS LDBIIC(U) ;AND ONE MORE FOR INPUT
JRST XMTECI] ;REJOIN MAIN STREAM
MOVE T1,T3 ;COPY CHARACTER
ANDI T1,CK.CHR ;MASK IT DOWN
CAIN T1,40 ;A SPACE?
PUSHJ P,XMTACR ;YES, CHECK OUT ACR CONDITION
PUSHJ P,TPCECH ;SEE IF NEED TO DO EXPANSION AT THIS LEVEL
XMTECI: MOVE T2,LDBECT(U) ;GET ECHO TAKER
CAMN T2,LDBBKI(U) ;TAKING LAST BREAK?
SETZM LDBBKI(U) ;YES, ZAP ITS POINTER
AOS T2,LDBTIC(U) ;COUNT THE INPUT CHARACTERS
SCNON ;ALLOW INTERRUPTS
TRNE T3,CK.NIS ;IS THIS STILL A REAL CHARACTER?
JRST XMTCH1 ;NO, TRY AGAIN
AOS %SCNEI ;COUNT CHARACTERS ECHOED
IFN FTRSP,<AOS .CPNEI##> ;PER CPU AS WELL
MOVE T4,LDBBYT(U) ;GET WORD WITH ECHO BITS AGAIN
TRNE T3,CK.MET ;IF NOT AN IMBEDDED FUNCTION, AND
JRST XMTECE ;NO, DON'T WORRY ABOUT RECEIVE ROUTINES
PUSHJ P,SPCHEK ;YES, GET THE CHARACTER'S CONTROL BITS
JRST XMTECU ;NOT SPECIAL, GO CHECK FOR LDLLCT
TLNE T1,CHRIA ;DOES THIS CHARACTER HAVE A RECEIVE ROUTINE?
TLNE T1,CHNDFR ;AND WAS IT DEFERRED?
JRST XMTECE ;NO TO EITHER, DON'T CALL ITS PREPROCESSOR
PUSHJ P,(T1) ;YES, CALL ITS PROCESSOR NOW
JRST XMTECD ;IT DIDN'T WANT TO BE STORED, GO DELETE IT
MOVSI T4,L3LEHD ;ECHO HALF-DONE FLAG
TDNE T4,LDBBY3(U) ;HAVE WE ALREADY CALLED TPCECH?
JRST XMTECE ;YES, DON'T STORE INTO DECREMENTED B.P.
SCNOFF ;DON'T ALLOW OTHERS IN THE CHUNKS
DPB T3,LDBECT(U) ;STORE THE (POSSIBLY CHANGED) CHARACTER
PUSHJ P,TPCECH ;CHECK FOR EXPANSION (AGAIN)
SCNON ;ALLOW OTHERS AGAIN
JRST XMTECE ;IT WANTS TO BE KEPT, SO ECHO IT
XMTECU: MOVE T1,T3 ;COPY CHARACTER
ANDI T1,CK.CHR ;ISOLATE IT
MOVE T1,CHTABL(T1) ;GET ALL OF ITS BITS
TLNE T1,CHPUNC ;IF PUNCTUATION,
TRNN T3,CK.PAR ;THEN CAN'T RAISE 8-BIT
TRNE T3,CK.IMG ;IF IMAGE MODE,
JRST XMTECE ;THEN CAN'T RAISE ITS CASE
MOVE T4,LDBDCH(U) ;GET BITS FOR TTY UC
TLNN T4,LDLLCT ;DOES USER WANT US TO RAISE CASE?
JRST XMTECE ;NO, JUST GO ECHO
MOVE T4,T3 ;COPY CHARACTER
ANDI T4,CK.CH7 ;QUICKLY MASK IT DOWN
CAIGE T4,140 ;IS IT LOWER CASE?
JRST XMTECE ;NO, DON'T CHANGE IT
TRC T3,040 ;YES, CHANGE ITS CASE
MOVSI T4,L3LEHD ;ECHO HALF-DONE FLAG
TDNN T4,LDBBY3(U) ;DON'T CLOBBER CHUNKS IF SET
DPB T3,LDBECT(U) ;AND ALTER IT IN THE CHUNKS
XMTECE: MOVSI T1,LDLPPS ;PROMPT POS SET BIT
TDNN T1,LDBDCH(U) ;SET YET THIS LINE?
JRST [IORM T1,LDBDCH(U) ;NO, BUT WE'RE ABOUT TO
MOVE T1,T2 ;SAVE INPUT COUNT
PUSHJ P,HPOS ;GET CARRIAGE POSITION
DPB T2,LDPPRP ;STORE AS PROMPT POSITION
MOVE T2,T1 ;RESTORE T2
JRST .+1] ;REJOIN MAIN STREAM
MOVEI T4,L1RDEC ;CHARACTER REQUEST BIT
PUSHJ P,SPCHEK ;SEE IF IT'S SPECIAL.
JRST XMTEC1 ;NO, A SINGLE MUNDANE CHARACTER
TRNE T3,CK.MET ;IF AN IMBEDDED FUNCTION,
JRST (T1) ;GO DO IT
TLNN T1,CHBRK ;YES. IS IT A BREAK CHAR?
JRST XMTEC1 ;NOT A BREAK
SCNOFF ;FIGHT RACE
MOVE T4,LDBECT(U) ;GET CURRENT POINTER
MOVEM T4,LDBBKU(U) ;SAVE FOR BACK-UP LIMIT
CAMN T4,LDBBKI(U) ;LAST BREAK FROM OTHER SIDE?
SETZM LDBBKI(U) ;YES, FORGET ABOUT IT
AOS LDBBKC(U) ;COUNT LINES IN THE LDB
AOS LDBBCT(U) ;COUNT BREAK CHARACTERS INPUT
SCNON ;ALLOW OTHERS AGAIN
PUSHJ P,CPRPOS ;CLEAR LDLPPS SO CAN GET NEW PROMPT POSITION
MOVEI T4,L1RDEC!L1RDEL;GET LINE REQUESTED BIT
XMTEC1: ANDCAM T4,LDBBYT(U) ;CLEAR, SINCE WE ECHOED A CHARACTER
PUSH P,T1 ;SAVE CHARACTER BITS
PUSH P,T3 ;AND CHARACTER
MOVSI T4,LDLBKA+LDLIMI;BREAK ON ALL CHARACTERS?
TDNE T4,LDBDCH(U) ; ..
JRST [PUSHJ P,RCVWKQ ;YES, WAKE JOB
PUSHJ P,CPRPOS ;CLEAR PROMPT POS AS IF BREAK
JRST XMTEC2] ;AVOID EXTRA WAKE IF BREAK TOO
PUSHJ P,CHKTIB ;ARE THERE OVER 72. OF THEM?
TLNE T1,CHBRK ;OR IS IT A BREAK CHARACTER?
PUSHJ P,ECHBRK ;YES. WAKE THE JOB, IF ANY
XMTEC2: POP P,T3
POP P,T1 ;RESTORE CHARACTER BITS INTO T1
IFN FTMIC,<
SKIPE LDBMIC(U) ;IF MIC-CONTROLLED,
PUSHJ P,MICECH ;LET MIC KNOW ABOUT <CR> AND SUCH
>
MOVSI T2,LDLCRP ;ARE WE IN A CONTROL-R?
TDNE T2,LDBDCH(U) ;TEST
JRST XMTEC3 ;YES, KEEP ECHOING
TLNE T1,CHBRK ;A BREAK?
SKIPL LDBBKB(U) ;AND A BREAK MASK SPECIFIED?
CAIA ;NO TO EITHER
JRST XMTCH1 ;BREAK CHARACTERS DON'T ECHO
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
XMTEC3: TRNE T3,CK.IMG ;IS IT IMAGE?
TRNE T3,CK.MET ;YES, BUT IS IT QUOTED?
TRNA ;NO OR YES, KEEP GOING
JRST XMTEC7 ;IMAGE, LEAVE ALONE
MOVE T2,LDBDCH(U) ;NO, GET LINE CHARACTERISTICS
TLNE T2,LDLNEC ;IS IT NON-ECHOING?
TLNE T2,LDLCRP ;AND NOT IN A CONTROL-R?
TRNA ;NO, USE FILL
JRST XMTEC7 ;YES, LEAVE ALONE
TLNN T2,LDLLCP ;LOCAL COPY?
JRST XMTEC4 ;NO, COUNT UP NORMAL CHARACTER
MOVEI T2,L2RXON ;PAPER TAPE?
TDNE T2,LDBBY2(U) ;...
JRST XMTEC7 ;YES. NO FILLERS, ELSE GARBLE.
XMTEC4: MOVSI T2,L2LDEL ;DELETE SEQUENCE BIT
TDNE T2,LDBBY2(U) ;BACKSLASH NEEDED?
TLOA T1,CHSPO!CHFIL ;YES, SAY FILL REQUIRED
TLNE T1,CHSPO ;SPECIAL CHARACTER OF SOME FLAVOR?
JRST XMTEC5 ;YES, MORE EXTENSIVE HANDLING REQUIRED
AOSG LDBHPS(U) ;NORMAL CHARACTER, ECHO ONE CHAR POSITION
JRST XMTEC7 ;GO DO IT
SOS LDBHPS(U) ;UNDO AOSG (ADJHP WILL RE-DO IT)
XMTEC5: MOVSI T2,LPLBLK ;THE SUPPRESS-BLANK-LINES BIT
TDNE T2,LDBPAG(U) ;"TTY NO BLANK" SET?
PUSHJ P,BLSUPI ;YES, NOTE PASSING <LF>S ET AL
PUSHJ P,ADJHP ;ADJUST CARRIAGE POSITION FOR ECHOED CHARACTER
TRZ T3,CK.MET!CK.IMG ;WE WANT TO SEE ECHOING CORRECTLY
PUSHJ P,SETFLI ;SET FILLERS FOR ECHOING
JRST XMTCH1 ;OUTPUT FROM FILLER POSITION.
XMTEC7: PUSHJ P,ECHTST ;SEE IF CHARACTER NEEDS ECHOING
JRST XMTCN4 ;NOT ECHOED YET, RETURN IT
JRST XMTCH1 ;ALREADY DONE, GET THE NEXT
;HERE TO DELETE AN INPUT CHARACTER AND TRY AGAIN
XMTECD: TRO T3,CK.NIS ;THIS IS NO LONGER A CHARACTER
MOVSI T4,L3LEHD ;ECHO EXPANSION IN PROGRESS?
TDNE T4,LDBBY3(U) ;CHECK
JRST XMTCH1 ;YES--JUST TRY THIS AGAIN
SCNOFF ;FIGHT RACES
DPB T3,LDBECT(U) ;FUDGE THE CHARACTER
SKIPE LDBTIC(U) ;UNLESS TSETBI'D
AOS LDBIIC(U) ;THERE'S ANOTHER ECHOED INVISIBLE CHARACTER
SCNON ;ALLOW OTHERS AGAIN
JRST XMTCH1 ;LOOK FOR ANOTHER CHARACTER TO SEND
;SUBROUTINE TO DETERMINE WHETHER CHARACTER NEEDS ECHOING
;RETURNS NON-SKIP IF NEEDS ECHO,
;SKIP RETURN IF NOT NEEDED
ECHTST: MOVE T1,LDBDCH(U) ;GET LEFT AND RIGHT HALF BITS
TLNE T1,LDLCRP ;ARE WE IN A CONTROL-R?
POPJ P, ;YES, ALL CHARACTERS ECHO
TLNN T1,LDLLCP ;NO, LOCAL COPY?
JRST ECHTS2 ;NO, DO NORMAL CHECKS
IFN FTMIC,<
SKIPE T1,LDBMIC(U) ;RUNNING MIC?
TLNE T1,LDLMCB ;IN MIC BREAK?
JRST CPOPJ1## ;MIC BREAK AND LOCAL COPY, DON'T ECHO AGAIN
JRST ECHTS1 ;NO, MIC CHARACTERS ALWAYS ECHO
> ;END IFN FTMIC
ECHTS2:
IFN FTNET,<
TRNE T3,CK.IMG ;IF IMAGE,
JRST ECHTS1 ;THEN NO ECHO WAS DONE
TRNE T3,CK.FDE ;ONLY ECHO IF FRONT-END DIDN'T
JRST CPOPJ1## ;IF NOT VTM, DON'T ECHO, IF VTM, MUST ECHO HERE
> ;END IFN FTNET ;ECHO THE CHARACTER NOW
ECHTS1: MOVE T1,LDBDCH(U) ;BITS
TLNN T1,LDLCNE ;SKIP LEVEL CHECK IF NO-ECHO BY COMMAND
TLNN T1,LDLCOM ;CHARACTER ITSELF SHOULD BE ECHOED
TLNN T1,LDLNEC ;UNLESS USER LEVEL AND HE SAID NO
POPJ P, ;RETURN CHARACTER
JRST CPOPJ1## ;NO, STEP TO NEXT CHARACTER
;META-CHARACTER FUNCTION ROUTINES
;SUBROUTINE TO TYPE A CRLF VIA THE ECHO STREAM
METNLF: MOVE T2,FLLCRF ;GET CRLF FILL POINTER
PJRST SETFLE ;FORCE A CRLF TO BE OUTPUT
;ROUTINE TO ECHO A DELETE-LINE (^U) OPERATION
METDL: PUSHJ P,METDL1 ;CALL WORKHORSE
JRST XMTCH1 ;TYPE ANYTHING WE QUEUED UP
METDL1: PUSHJ P,SAVE4## ;PRESERVE A FEW
MOVSI T1,L2LDEL ;BACKSLASH BIT
ANDCM T1,LDBBY2(U) ;GET COMPLEMENT OF PREVIOUS STATE
PUSH P,T1 ;SAVE IT FOR AFTER SETTING UP
MOVEI T3,CK.NIS+"U"-100 ;REPLACE MC.DL WITH USED ^U
PUSHJ P,DELPRE ;PERFORM DELETION PREAMBLE
POP P,T1 ;GET COMPLEMENT OF PREVIOUS L2LDEL SETTING
ANDCAM T1,LDBBY2(U) ;CLEAR IT IF IT WAS OFF BEFORE
PUSHJ P,PRSKL ;SKIP PROMPT AND KILL REST OF LINE
SKIPA T3,["U"-100] ;NOT A DISPLAY, ECHO OLD WAY WITH ^U<CRLF>
JRST METDL2 ;DONE WITH PROMPT, GO PERFORM DELETION
PUSHJ P,ECHTST ;OLD WAY, SEE IF WE WERE ECHOING
SKIPA T2,FILXUP ;YES, GET POINTER TO \^U<CRLF>
JRST METDL2 ;NO, DON'T BOTHER
MOVSI T1,L2LDEL ;THE BACKSLASH BIT
TDNN T1,LDBBY2(U) ;WAS IT ON?
IBP T2 ;NO, DON'T NEED BACKSLASHES
PUSHJ P,SETFLE ;SEND ^U<CRLF>
METDL2: CAIE P1,DELEND ;DO WE OWN THE INPUT STREAM?
JRST METDL3 ;NO, MUST DO THIS THE HARD WAY
PUSHJ P,RIDLN ;YES, JUST DUMP THE LINE
JRST METDL5 ;AND GO HANDLE CLEAN-UP
METDL3: PUSHJ P,DELSFX ;FIND ANOTHER TO DELETE
JRST METDL5 ;DONE WITH THE LINE, GO CLEAN UP
SCNOFF ;EXCLUDE OTHERS WHILE WE TWIDDLE CHUNKS
SKIPLE LDBTIC(U) ;AVOID CONFLICT WITH TSETBI
PUSHJ P,DELMID ;DELETE IT
SCNON ;SAFE TO ALLOW OTHERS FOR A WHILE
JRST METDL3 ;LOOP UNTIL THE LINE IS GONE
METDL5: MOVSI T1,L2LDEL ;GET DELETION BIT
ANDCAM T1,LDBBY2(U) ;DON'T CONFUSE ANYONE ELSE, WE'RE DONE
MOVSI T1,LDLVDC ;VISIBLE DELETE CHARACTER FLAG
ANDCAM T1,LDBTTW(U) ;YES, OUR DELETE WAS VISIBLE
PJRST DELFIN ;FINISH UP DELETION AND RETURN
;SUBROUTINE TO SKIP OVER THE PROMPT (IF ANY) AND KILL THE LINE
PRSKL: PUSHJ P,TTVID ;SEE IF A VIDEO TERMINAL
POPJ P, ;NO, CAN'T DO IT
HRRZ T1,T1 ;GET ERASE TO EOL TABLE
JUMPE T1,CPOPJ## ;IF NOT THERE, CAN'T DO IT
PUSH P,T1 ;SAVE TABLE ADDRESS
PUSHJ P,HPOS ;GET CURRENT POSITION
LDB T3,LDPPRP ;AND POSITION TO MATCH
MOVSI T1,LDLPPS ;PROMPT POS SET BIT
TDNN T1,LDBDCH(U) ;PROMPT FOUND FOR THIS LINE YET?
CAIN T2,(T3) ;AND POSITIONS DON'T MATCH?
CAIA ;PROMPT IS OK
SETZ T3, ;NO, FAKE IT AS ZERO
PUSH P,T3 ;SAVE COUNT OF POSITIONS TO SKIP
MOVE T1,-1(P) ;RETRIEVE TABLE ADDRESS
MOVE T2,(T1) ;GET <CR> POINTER
PUSHJ P,SETFLE ;AND PUT THAT IN THE CHUNKS
PUSHJ P,SCNBOL ;MAKE SURE AT LEFT MARGIN
ADDM T3,LDBHPS(U) ;ACCOUNT FOR CHARACTERS TO SKIP
PRSKL1: SOSG (P) ;AT LEAST ONE MORE TO SKIP?
JRST PRSKL2 ;NO, FINISH UP
MOVE T1,-1(P) ;YES, GET TABLE ADDRESS
MOVE T2,1(T1) ;GET CURSOR RIGHT SEQUENCE
PUSHJ P,SETFLE ;ENTER IT INTO THE STREAM
JRST PRSKL1 ;LOOP OVER PROMPT LENGTH
PRSKL2: POP P,T2 ;RESTORE COUNT
POP P,T1 ;AND TABLE ADDRESS
SKIPN T2 ;IF ONE LEFT OF PROMPT POSITION
SKIPA T2,2(T1) ;YES, GET CURSOR RIGHT + KILL LINE
MOVE T2,3(T1) ;NO, GET KILL LINE ONLY
AOS (P) ;SET UP SKIP RETURN FOR CALLER
PJRST SETFLE ;STORE STRING IN CHUNKS AND RETURN SUCCESS
;HERE TO DELETE A WORD (^W)
METDW: MOVEI T3,CK.NIS+"W"-100 ;GET A USED ^W FOR REPLACEMENT
PUSHJ P,METDW1 ;DELETE THE WORD
JRST XMTCH1 ;AND TRY FOR ANOTHER CHARACTER
METDW1: PUSHJ P,SAVE4## ;PRESERVE OUR DISPATCH REGISTERS
PUSHJ P,DELPRE ;TAKE CARE OF DELETE CHARACTER PREAMBLE
TLNN T1,-1 ;CAN WE ERASE TO EOL?
JRST METDW2 ;NO, LEAVE ECHO DISPATCH ALONE
MOVEI P2,METDWE ;YES, USE DIFFERENT ECHO ROUTINE
PUSHJ P,SETFLC ;GET OUR FILLER CLASS
MOVE P3,FILLHP(T2) ;KEEP ITS FILL POINTER AROUND
METDW2: PUSHJ P,DELSFX ;ZAP ANY TRAILING NIS CHARACTERS
JRST METDWX ;NOTHING TO DELETE
CAIE T3,11 ;IS IT A TAB
CAIN T3,40 ;OR A SPACE?
JRST [PUSHJ P,DELONE ;YES, ZAP THE CHARACTER
JRST METDW2] ;AND LOOP OVER TRAILING WHITESPACE
TLNE T1,CHPUNC ;IS IT ALPHANUMERIC?
JRST METDW4 ;NO, GO TEST TERMINATION
METDW3: PUSHJ P,DELONE ;DELETE THE CHARACTER
PUSHJ P,DELSFX ;TRIM ANY NIS CHARACTERS
JRST METDWX ;NOTHING MORE TO DELETE
TLNN T1,CHPUNC ;IF IT'S STILL ALPHANUMERIC,
JRST METDW3 ;THEN KEEP DELETING FROM WORD
METDW4: MOVSI T2,LDLVDC ;VISIBLE DELETE CHARACTER FLAG
TDNE T2,LDBTTW(U) ;STILL ON?
PUSHJ P,DELONE ;YES, SO HAVEN'T DONE ANYTHING YET, GET THIS ONE
METDWX: CAIE P2,METDWE ;DID ECHO DELETION USE OUR SPECIAL ROUTINE?
PJRST DELFIN ;NO, GO FINISH UP
PUSHJ P,TTVID ;YES, GET CHARACTERISTICS AGAIN
TDZA T2,T2 ;CLEAR AC IF NONE
HRRZ T2,T1 ;OTHERWISE GET EOL TABLE ADDRESS
MOVE T2,3(T2) ;GET KILL TO EOL BYTE POINTER
PUSHJ P,SETFLE ;STORE IN ECHO/FILL STREAM
PJRST DELFIN ;NOW GO FINISH UP
;HERE TO DELETE A CHARACTER (BACKSPACE)
METBS: MOVEI T3,CK.NIS+"H"-100 ;GET A USED BACKSPACE
PUSHJ P,METBS1 ;CALL WORKHORSE ROUTINE
JRST XMTCH1 ;AND TRY FOR MORE CHARACTERS TO OUTPUT
METBS1: PUSHJ P,SAVE4## ;PRESERVE OUR DISPATCH REGISTERS
PUSHJ P,DELPRE ;SETUP DELETE ROUTINE
MOVEI P2,METDWE ;USE BACKSPACING ECHO ROUTINE
PUSHJ P,SETFLC ;GET OUR FILL CLASS
MOVE P3,FILLHP(T2) ;AND SET BACKSPACE STRING FOR ECHO ROUTINE
PJRST METDC2 ;NOW ACT LIKE RUBOUT
;HERE TO DELETE A CHARACTER (RUBOUT)
METDC: MOVEI T3,CK.NIS+177 ;GET A USED RUBOUT
PUSHJ P,METDC1 ;CALL WORKHORSE ROUTINE
JRST XMTCH1 ;AND TRY FOR MORE CHARACTERS TO OUTPUT
METDC1: PUSHJ P,SAVE4## ;PRESERVE OUR DISPATCH REGISTERS
PUSHJ P,DELPRE ;SETUP DELETE AND ECHO ROUTINES
METDC2: PUSHJ P,DELSFX ;ZAP ANY NIS CHARACTERS
PJRST DELFIN ;NOTHING TO DELETE
PUSHJ P,DELONE ;GOT ONE, DELETE IT
PJRST DELFIN ;CLEAN UP
;ECHO ROUTINES FOR DELETE WORD/CHARACTER
;SUBROUTINE TO USE BACKSPACES, MUST EVENTUALLY BE FOLLOWED BY AN ERASE TO EOL
METDWE: MOVEI T3,010 ;LOAD A BACKSPACE
PUSHJ P,SETFCE ;SET FOR CHARACTER ECHO
MOVE T2,P3 ;GET OUR BACKSPACE FILLER
PUSHJ P,SETFLE ;PUT INTO FILL/ECHO STREAM
SOJG P4,METDWE ;LOOP FOR WIDTH OF CHARACTER
POPJ P, ;RETURN TO DELONE
;SUBROUTINE TO USE TCRTAB BACKSPACE TABLE
METDCT: HRRZI T2,8(P3) ;COPY TABLE POINTER
SUB T2,P4 ;POINT TO RIGHT ENTRY
MOVE T2,(T2) ;PICK UP BYTE POINTER
PJRST SETFLE ;PUT INTO FILL/ECHO STREAM AND RETURN
;SUBROUTINE TO ECHO DELETION FOR HARDCOPY TERMINALS
METDCR: MOVSI T1,L2LDEL ;BIT FOR DELETION IN PROGRESS
TDNN T1,LDBBY2(U) ;FIRST DELETION ECHO?
JRST [IORM T1,LDBBY2(U) ;YES, SET BIT
MOVE T2,FLLBSP ;GET BACKSLASH POINTER
PUSHJ P,SETFLE ;SEND A BACKSLASH
JRST .+1] ;REJOIN
PUSHJ P,SETFCE ;OUTPUT CHARACTER VIA ECHO STREAM
SOJG P4,.-1 ;LOOP FOR WIDTH OF CHARACTER
POPJ P, ;RETURN TO DELONE
;SPECIAL ROUTINES FOR DELETE WORD/CHARACTER
;SUBROUTINE TO SET UP FOR DELETE WORD/CHARACTER
DELPRE: SCNOFF ;MUSN'T LET ANYONE ELSE IN
MOVSI T1,LDLDIP ;DELETE-IN-PROGRESS FLAG
IORM T1,LDBDCH(U) ;LIGHT FOR TYICC4
DPB T3,LDBECT(U) ;SAVE ALTERED CHARACTER FOR READERS
SKIPE LDBTIC(U) ;MAKE SURE THERE'S STILL A STREAM
AOS LDBIIC(U) ;COUNT ANOTHER INVISIBLE CHARACTER
MOVEI P1,DELMID ;ROUTINE TO DELETE FROM THE MIDDLE
MOVE T1,LDBECT(U) ;SEE WHERE WE ARE
CAME T1,LDBTIP(U) ;ARE WE AT THE END?
JRST DELPR1 ;NO, WE GUESSED RIGHT
MOVEI T1,L1RMIF ;YES, GET THE RECINT INTERLOCK FLAG
TDNE T1,LDBBYT(U) ;IS IT IN USE?
JRST DELPR1 ;YES, STILL CAN'T DELETE FOR REAL
IORM T1,LDBBYT(U) ;NO, OBTAIN IT
MOVEI P1,DELEND ;AND USE ROUTINE TO DELETE FROM THE END
DELPR1: SCNON ;ALLOW OTHERS IN AGAIN
PUSHJ P,STOPCM ;STOP COMCON FROM INTERFERING
MOVSI T1,LDLVDC ;VISIBLE DELETE CHARACTER BIT
IORM T1,LDBTTW(U) ;LIGHT IT FOR LATER
PUSHJ P,TTVID ;SEE IF VIDEO TERMINAL
TRN ;IGNORE NON-SKIP FOR A MOMENT
MOVEI P2,METDCR ;ASSUME HARDCOPY ECHO
TLNN T1,-1 ;DO WE HAVE A DELETE SEQUENCE?
POPJ P, ;NO, WE'RE ALL DONE
MOVEI P2,METDCT ;YES, USE THE TABLE TO DELETE
HLRZ P3,T1 ;AND COPY THE TABLE ADDRESS
POPJ P, ;NOW WE'RE DONE
;SUBROUTINE TO BACK UP OVER ANY NOT-IN-STREAM CHARACTERS
;ON SKIP RETURN, HAS CHAR TO BE DELETED IN T3 AND CHTABL BITS IN T1
;ON NON-SKIP, THERE ARE NO MORE CHARACTERS AVAILABLE TO DELETE
DELSFX: SKIPN LDBTIC(U) ;ANY MORE TO BE DELETED?
JRST [PUSHJ P,INPCHK ;MAYBE NOT, DO SANITY CHECK
JRST DELSFX ;THERE'S ANOTHER
POPJ P,] ;NO, GIVE DEPLETION RETURN
LDB T3,LDBECT(U) ;YES, GET CHARACTER TO ZAP
TRNE T3,CK.NIS ;IF NOT A REAL CHARACTER
JRST [PUSHJ P,DELONE ;DELETE IT
JRST DELSFX] ;AND LOOK FOR NEXT
PUSHJ P,SPCHEK ;SEE IF SPECIAL TO SOMEONE
JFCL ;OK IF NOT
TLNE T1,CHBRK ;IF A BREAK,
POPJ P, ;WE CAN'T DELETE IT
TRC T3,CK.IMG!CK.MET ;IMAGE OR META
TRCN T3,CK.IMG!CK.MET ;IS IT BOTH?
JRST DELSF1 ;YES, GET DIFFERENT BITS
TRZ T3,CK.FDE!CK.IMG ;CLEAR MISLEADING BITS
TRNE T3,CK.MET ;META CHARACTER?
SKIPA T1,METABL-CK.MET(T3) ;YES, GET META BITS
MOVE T1,CHTABL(T3) ;NO, GET ALL ITS BITS
JRST CPOPJ1## ;AND RETURN GOODNESS
DELSF1: TRZ T3,CK.FDE ;CLEAR BIT WE DON'T CARE ABOUT
JRST CPOPJ1## ;RETURN GOODNESS
;SUBROUTINE TO DELETE ONE CHARACTER FROM THE END OF THE INPUT STREAM
;PRESERVES T3
;CALLED UNDER SCNOFF
DELEND: PUSH P,T3 ;AS ADVERTISED
PUSHJ P,DELCHR ;REMOVE A CHARACTER
PUSHJ P,RCDSTP ;SHOULDN'T GET THIS FAR IF NO CHARACTER IN STREAM
JRST T3POPJ## ;RESTORE CHARACTER JUST DELETED AND RETURN
;SUBROUTINE TO DELETE ONE CHARACTER FROM THE MIDDLE OF THE INPUT STREAM
;PRESERVES T3 MODULO THE CK.NIS BIT
;CALLED UNDER SCNOFF
DELMID: SOSGE LDBTIC(U) ;ONE LESS ECHOED CHARACTER
PJRST RCDSTP ;SHOULDN'T GET THIS FAR IF NONE
TROE T3,CK.NIS ;WE'RE MAKING AN INVISIBLE CHARACTER
SOSA LDBIIC(U) ;IF WAS, IS ONE LESS ECHOED
DPB T3,LDBECT(U) ;ELSE UPDATE IN CHUNKS
AOS LDBECC(U) ;ONE MORE TO ECHO
AOS LDBIEC(U) ;AND IT'S INVISIBLE
SETO T1, ;AMOUNT TO BACKSPACE ECHO TAKER
ADJBP T1,LDBECT(U) ;GET A BACKSPACED POINTER
HRRZI T2,CK.BDY##(T1) ;SEE IF BACKED INTO HEADER WORD
TRNE T2,CK.BDY## ;DID WE?
JRST DELMD1 ;NO, ALMOST DONE
SSX T2,MS.SCN ;YES, SET SCNSER DATA SECTION
HLRZ T1,CK.BTH##(T2) ;GET BACK POINTER
JUMPE T1,DELMD2 ;BETTER BE THERE
ADD T1,[POINT CK.WID,CK.BDY##,35] ;POINT TO END OF PREVIOUS CHUNK
DELMD1: MOVEM T1,LDBECT(U) ;STORE BACKSPACED POINTER
POPJ P, ;DONE WITH DELETION
;HERE TO CHECK IF DELETING TOO FAR
DELMD2: MOVE T1,LDBTIT(U) ;GET TYPEIN TAKER
IBP T1 ;BUMP IT
CAME T1,LDBECT(U) ;ARE WE BACKING UP TO A PLACE WE UNDERSTAND?
STOPCD CLRSTP,DEBUG,DELMBD, ;++DELMID WENT BAD
MOVE T1,LDBTIT(U) ;YES, GET POINTER AGAIN
JRST DELMD1 ;AND GO FOR IT
;CLEAN UP AFTER DELETION
DELFIN: PUSHJ P,DELSFX ;MAKE SURE OF SUFFIX
TRN ;DON'T CARE IF NO MORE
MOVSI T1,LDLVDC ;VISIBLE DELETE CHARACTER FLAG
TDNE T1,LDBTTW(U) ;IS IT ON?
CAIE P2,METDCR ;AND WAS THIS HARDCOPY DELETION?
JRST DELFN1 ;NO TO EITHER, PRESS ON
MOVE T2,FLLBSC ;YES, GET POINTER TO BACKSLASH - CRLF
MOVSI T1,L2LDEL ;BIT FOR DELETION SEQUENCE
TDNN T1,LDBBY2(U) ;OPENING BACKSLASH TYPED?
IBP T2 ;NO, SO DON'T TYPE A CLOSING ONE
PUSHJ P,SETFLE ;TYPE END OF DELETION STRING
ANDCAM T1,LDBBY2(U) ;CLEAR BACKSLASH FLAG FOR NEXT TIME
DELFN1: MOVSI T1,LDLDIP ;DELETE-IN-PROGRESS FLAG
ANDCAM T1,LDBDCH(U) ;NOT ANY MORE
MOVEI T3,MC.CHP ;THE SETCHP CHARACTER
PUSHJ P,SETFCE ;TELL FE'S ABOUT HPOS CHANGE AFTER WE'RE DONE
CAIE P1,DELEND ;DID WE GET THE "MIC" INTERLOCK?
POPJ P, ;NO, WE'RE DONE
PJRST RECINU ;YES, GIVE UP THE INTERLOCK AND RETURN
;SUBROUTINE TO DELETE ONE CHARACTER, COMPLETE WITH ECHO/FILL
;CALLED WITH CHARACTER TO BE DELETED IN T3
DELONE: SCNOFF ;DELETION ROUTINES NEED THIS
SKIPG LDBTIC(U) ;DID TSETBI SNEAK IN?
JRST SONPPJ ;YES, WE HAVE NOTHING LEFT TO DO
TRNE T3,CK.NIS ;IF ALREADY A NON-CHARACTER,
JRST [PUSHJ P,(P1) ;DELETE IT FROM THE CHUNKS
JRST SONPPJ] ;AND WE'RE DONE
PUSHJ P,(P1) ;REAL CHARACTER, REMOVE IT FROM THE STREAM
SCNON ;ALLOW OTHERS AGAIN
MOVSI T2,LDLVDC ;VISIBLE DELETE CHARACTER FLAG
ANDCAM T2,LDBTTW(U) ;NOTE WE DELETED SOMETHING REAL
TRC T3,CK.MET!CK.IMG ;QUOTE BITS
TRCN T3,CK.MET!CK.IMG ;IS IT QUOTED?
JRST DEL1Q ;YES, HANDLE DELETION OF QUOTED CHARACTER
ANDI T3,CK.CHR ;TRIM FUNNY BITS
CAIN T3,11 ;IS IT A TAB?
JRST DEL1T ;YES, TABS GET SPECIAL HANDLING
MOVEI P4,1 ;ASSUME A WIDTH OF ONE
CAIL T3,40 ;IS IT A PRINTING
CAIL T3,177 ; CHARACTER?
JRST DEL1C ;NO, CONTROL CHARACTERS ARE DIFFERENT
DEL1A: PUSH P,T3 ;SAVE CHARACTER TO ECHO
MOVE T2,P4 ;COPY WIDTH
PUSHJ P,BACKUP ;ADJUST HPOS
POP P,T3 ;RESTORE CHARACTER
DEL1EX: MOVE T2,LDBDCH(U) ;GET CHARACTERISTIC BITS
TLNE T2,LDLNEC ;IF USER SAID NO ECHO,
TLNE T2,LDLCOM ;AND AT USER LEVEL,
PJRST (P2) ;NO, SIMPLE CASE, JUST CALL ECHOER AND RETURN
POPJ P, ;YES, DON'T ECHO THIS
DEL1C: TRNE T3,CK.PAR ;REGULAR CONTROL CHARACTER?
JRST DEL1E ;NO, GO HANDLE EIGHT-BIT
MOVE T1,CHTABL(T3) ;GET CONTROL BITS
MOVE T2,LDBDCH(U) ;GET CHARACTERISTICS
CAIE T3,STDALT ;UNLESS IT'S ESCAPE,
TLZ T1,CHALT ;IT'S NOT AN ALTMODE
TLNE T2,LDLDLR ;USER SUPPRESSING THIS CRUFT?
TLZ T1,CHUAE!CHALT!CHCRE ;YES, CLEAR IT OUT
TLNN T1,CHUAE!CHCRE!CHALT ;EITHER FORM OF UPARROW ECHO INVOLVED?
POPJ P, ;NO, DIDN'T ECHO BEFORE, SO DON'T NOW
DEL1C1: PUSH P,T3 ;SAVE ACTUAL CHARACTER
MOVEI T2,2 ;THIS HAS A WIDTH OF TWO,
TLNE T1,CHALT ;UNLESS IT'S ESCAPE
MOVEI T2,1 ;THEN IT HAS A WIDTH OF ONE
PUSHJ P,BACKUP ;SO ADJUST HPOS THAT MANY
TLNE T1,CHALT ;IF THIS IS ESCAPE,
JRST DEL1CE ;ECHO AS DOLLAR
MOVEI T3,"^" ;GET AN UPARROW TO ECHO
PUSHJ P,DEL1EX ;SHOW ITS DELETION
POP P,T3 ;RESTORE CONTROL CHARACTER
TRC T3,100 ;CONVERT TO PRINTABLE FORM
MOVEI P4,1 ;WIDTH OF ONE
PJRST DEL1EX ;ECHO THIS AND RETURN
DEL1CE: POP P,T3 ;RESTORE THE ESCAPE
MOVEI T3,"$" ;GET ITS DOLLARSIGN
PJRST DEL1EX ;ECHO IT AND RETURN
DEL1T: SCNOFF ;FIGHT RACES
SKIPN T4,LDBBKU(U) ;START FROM LAST BREAK
MOVE T4,LDBTIT(U) ;CLOSE ENOUGH
LDB P4,LDPPRP ;ASSUME THIS WAS THE PROMPT
EXCH T4,LDBECT(U) ;STORE NEW START POINTER, REMEMBER END
DEL1T1: CAMN T4,LDBECT(U) ;HIT THE END YET?
JRST DEL1T3 ;YES, QUIT COUNTING
LDCHK T3,LDBECT(U),DEL1T3 ;GET ANOTHER CHARACTER
TRNE T3,CK.NIS ;REAL CHARACTER?
JRST DEL1T1 ;NO, IGNORE
ANDI T3,CK.CHR ;TRIM FUNNY BITS
CAIE T3,11 ;A TAB?
JRST DEL1T2 ;NO, GO COUNT NORMAL CHARACTER
TRZ P4,7 ;YES, CLEAR FRACTIONAL TAB STOP
ADDI P4,10 ;BUMP TO NEXT TAB STOP
JRST DEL1T1 ;LOOP OVER LINE CONTENTS
DEL1T2: MOVE T1,CHTABL(T3) ;GET CONTROL BITS OF NORMAL CHARACTER
TRNE T1,CHUAE ;IF ^X FORM
ADDI P4,1 ;THEN COUNT THE UPARROW
AOJA P4,DEL1T1 ;COUNT ANOTHER COLUMN AND LOOP
DEL1T3: SCNON ;ALLOW OTHERS AGAIN
MOVEI T2,10(P4) ;GET NEXT TAB STOP VALUE
TRZ T2,7 ;BACK OFF TO TAB STOP
SUBB T2,P4 ;GET COUNT FOR BACKSPACING
PUSHJ P,BACKUP ;ADJUST HPOS THAT MANY
MOVEI T3," " ;LOAD A SPACE FOR ECHO ROUTINES
PJRST DEL1EX ;ECHO DELETION OF (P4) SPACES AND RETURN
DEL1E: MOVE T1,CHTABL(T3) ;GET CHARACTER BITS
MOVSI T2,LDL8BI ;8-BIT INPUT MODE (DUE TO PROGRAM)?
TDNN T2,LDBDCH(U) ;TEST IT
TLNN T1,CH2PC ;OR NOT AN EXPANDABLE CHARACTER?
JRST DEL1A ;YES, BACK TO NORMAL CASE AFTER ALL
MOVE T2,CHREQV-200(T3) ;GET CHARACTER EXPANSION STRING
TLNN T2,-1 ;THREE CHARACTER EXPANSION?
AOJA P4,DEL1E1 ;NO, IT'S EXACTLY TWO
TRNN T2,767000 ;YES, IS ITS MIDDLE A BACKSPACE?
JRST [HLRZ T3,T2 ;YES, THE LAST CHARACTER IS ALL WE ECHOED,
JRST DEL1A] ;SO PRETEND THAT'S WHAT WE'RE DELETING
ADDI P4,2 ;NO, IT'S A THREE-WIDE CHARACTER
DEL1E1: MOVE T2,P4 ;COPY THE WIDTH
PUSH P,T3 ;SAVE THE CHARACTER
PUSHJ P,BACKUP ;ADJUST HPOS
POP P,T3 ;RESTORE CHARACTER
CAIN P2,METDCR ;IF HARDCOPY ECHO,
MOVEI P4,1 ;THEN ONLY TYPE THE CHARACTER ONCE (IT EXPANDS)
PJRST DEL1EX ;ECHO A (P4) WIDTH DELETION AND RETURN
DEL1Q: CAIE P2,METDCR ;IF NOT HARDCOPY ECHO,
JRST DEL1Q1 ;THEN JUST DELETE BY WIDTH
MOVE T2,LDBDCH(U) ;GET CHARACTERISTICS BITS
PUSH P,T3 ;SAVE THE REAL CHARACTER
MOVEI T3,26 ;GET AN ^V
SETZ T1, ;THIS IS NOT ESCAPE
TLNN T2,LDLDLR ;UNLESS USER SUPPRESSED UPARROW ECHO,
PUSHJ P,DEL1C1 ;ECHO THE ^V
POP P,T3 ;RESTORE OUR CHARACTER
PUSHJ P,SPCHEK ;GET ITS BITS
TRZ T3,CK.MET ;CLEAR THE META BIT
MOVEI P4,1 ;ASSUME A WIDTH OF ONE
TLNN T1,CHUAE ;IS IT A CONTROL CHARACTER?
JRST DEL1A ;NO, HANDLE LIKE A NORMAL CHARACTER
MOVE T2,LDBDCH(U) ;YES, GET DOLLAR BIT AGAIN
TLNE T2,LDLDLR ;ARE WE DOING UPARROW ECHO?
PJRST DEL1C1 ;YES, DO IT
POPJ P, ;NO, DON'T BOTHER ME
DEL1Q1: SETZ P4, ;ASSUME IT WAS INVISIBLE
MOVE T2,LDBDCH(U) ;GET CHARACTERISTICS WORD
TLNN T2,LDLDLR ;DID THE ^V ECHO?
ADDI P4,2 ;YES, COUNT TWO CHARACTERS
PUSHJ P,SPCHEK ;GET BITS FOR OUR CHARACTER
TLNN T1,CHUAE ;IS IT A CONTROL CHARACTER?
AOJA P4,DEL1A ;NO, JUST DELETE (P4) CHARACTERS AND RETURN
TLNE T2,LDLDLR ;YES, DID IT ECHO?
POPJ P, ;NO, NOTHING DID, DON'T BOTHER ME
ADDI P4,2 ;YES, WE ECHOED 4 WIDE
PJRST DEL1A ;DELETE (P4) CHARACTERS AND RETURN
;SUBROUTINE TO HANDLE AUTO-CRLF
XMTACR: MOVSI T1,LDLCOM ;SEE IF USER AT COMMAND LEVEL
TDNE T1,LDBDCH(U) ;AND IF SO,
POPJ P, ;IGNORE ACR
LDB T4,LDPACR ;GET AUTO-CRLF SETTING
JUMPE T4,CPOPJ## ;DO NOTHING IF NOT SET
PUSHJ P,HPOS ;GET CURRENT HPOS
CAIGE T2,(T4) ;SEE IF HIT MARGIN
POPJ P, ;NO, IGNORE
MOVEI T1,40 ;GET A SPACE AGAIN
PUSHJ P,TOPGCB ;READ OUR STATUS BYTE
TRNE T2,CC.NSA ;IF NO SPECIAL ACTION,
POPJ P, ;IGNORE
TRC T3,040^!015 ;CONVERT TO CR
DPB T3,LDBECT(U) ;STUFF BACK FOR READERS
POPJ P, ;RETURN AFTER MUNGING
;ROUTINE TO CHECK IDLENESS WHEN OUT OF CHARACTERS TO ECHO
ZAPECH: SETZM LDBECC(U) ;FIX UP
MOVE T2,LDBTIP(U) ;MESSED UP
CAME T2,LDBECT(U) ;CHECK POINTERS
PUSHJ P,RCDSTP ;SOMETHING IS WRONG
JRST XMTIDL
;SUBROUTINE TO CHECK IF WAKEUP SHOULD OCCUR BECAUSE OF NUMBER OF CHARS
CHKTIB: CAILE T2,TTIBRK## ;EXCEEDED ARBITRARY MAX?
JRST CPOPJ1## ;YES, ALWAYS BREAK
CHKTIF: SKIPL LDBBKB(U) ;BREAK SET SPECIFIED?
POPJ P, ;NO, DON'T BREAK BECAUSE OF NUMBER OF CHARS
PUSH P,T2 ;SAVE POSITION
LDB T2,LDPFWD ;GET FIELD WIDTH
SKIPN T2 ;WIDTH SET?
MOVEI T2,1 ;NO, USE ONE
CAMG T2,(P) ;AT END OF FIELD
AOS -1(P) ;YES, WAKEUP
JRST T2POPJ## ;RETURN
ECHBRK: PUSHJ P,COMQ ;IS LINE AT COMMAND LEVEL?
PJRST RCVWAK ;NO. WAKE JOB IF ANY.
PJRST COMSET ;YES. SET COMMAND REQUEST.
RCVWKQ: PUSHJ P,COMQ ;IS LINE AT COMMAND LEVEL?
PJRST RCVWAK ;NO. WAKE JOB.
POPJ P,0 ;YES. DON'T MAKE COMMAND FOR LDLBKA
;ROUTINE TO QUEUE FOR A CHANGE HARDWARE PARAMETER MESSAGE
SETCH1: AOS (P) ;SKIPPING SETCHP
SETCHP::SE1ENT ;ENTER SECTION 1
MOVEI T1,L1RCHP
IORM T1,LDBBYT(U) ;MARK THAT ISRCHP MUST BE CALLED
PJRST TOPOKE ;ADD TO QUEUE
CLRIRM::SE1ENT ;ENTER SECTION 1
MOVSI T1,LPLIRM ;IRMA BIT
ANDCAM T1,LDBPAG(U) ;CLEAR IN LDB
POPJ P, ;RETURN
TOREQ:: SE1ENT ;ENTER SECTION 1
MOVSI T1,LDLIDL
IORM T1,LDBDCH(U)
;; PJRST TOPOKE
;ROUTINE TO PLACE AN LDB INTO THE START OUTPUT QUEUE. SCANNED
;AT CLOCK LEVEL ONCE PER TICK.
;CALL
; MOVEI U,LDB ADDRESS
; PUSHJ P,TOPOKE
; <RETURN HERE ALWAYS>
;USES T1,T2
TOPOKE::SE1ENT ;ENTER SECTION 1
MOVEI T1,LDRPTY ;PTY BIT
TDNE T1,LDBDCH(U) ;IS THIS A PTY?
PJRST PTYPE## ;YES, DON'T QUEUE OUTPUT
MOVSI T1,LPLPOK ;OUTPUT BEING STARTED BIT
TDNE T1,LDBPAG(U) ;CHECK BEFORE WE GET THE INTERLOCK
POPJ P, ; JUST FOR EFFICIENCY'S SAKE
SCNOFF ;NO INTERRUPTS
TDNE T1,LDBPAG(U) ;...
JRST SONPPJ ;YES, BY SOMEONE ELSE
MOVSI T2,LTLUSE ;IN-USE FLAG
TDNN T2,LDBTTW(U) ;IS THIS A REAL LINE?
JRST SONPPJ ;NOT YET--IGNORE THIS REQUEST
SKIPL LDBDCH(U) ;LINE ALREADY ACTIVE?
JRST [MOVEI T2,L1RCHP ;YES, DON'T QUEUE UNLESS
TDNN T2,LDBBYT(U) ;A HARDWARE PARAMETER HAS CHANGED
JRST SONPPJ
JRST .+1]
IORM T1,LDBPAG(U) ;NO. INDICATE LDB IS GOING INTO THE QUEUE
HLRZ T1,LDBQUH(U) ;GET THE QUEUE HEADER ADDRESS
SKIPN T2,1(T1) ;LAST ENTRY OF CURRENT QUEUE
MOVEI T2,-LDBQUE(T1) ;POINT TO QUEUE HEADER WORD IF NULL QUEUE
MOVEM U,LDBQUE(T2) ;STORE ADDRESS OF ARGUMENT LDB AT END
MOVEM U,1(T1) ;UPDATE LATEST ENTRY
SETZM LDBQUE(U) ;MAKE SURE LIST TERMINATES
JRST SONPPJ ;ALLOW INTERRUPTS AND RETURN
;ROUTINE TO TAKE AN LDB OUT OF THE 'START OUTPUT' QUEUE
;CALLED FROM DEVICE DRIVERS TO FIND LINES THAT ARE WAITING TO DO OUTPUT.
;CALL
; MOVE T1,ADDRESS OF LIST HEADER
; PUSHJ P,TOTAKE
; <IF EMPTY QUEUE>
; <LDB ADDRESS IN U>
;
;USES T2.
TOTAKE::SE1ENT ;ENTER SECTION 1
SKIPN 0(T1) ;IF QUEUE IS EMPTY NOW
POPJ P, ; AVOID INTERLOCK
SCNOFF
TOTAK1: MOVSI T2,LPLPOK ;HAS OUTPUT BEEN STARTED?
MOVE U,0(T1) ;POINT TO FIRST LDB IN LIST
JUMPE U,SONPPJ ;IF NONE
ANDCAM T2,LDBPAG(U) ;CLEAR 'IN QUEUE' BIT
SKIPN T2,LDBQUE(U) ;NEXT LDB IN LIST, END OF LIST?
SETZM 1(T1) ;YES, CLEAR TAIL POINTER TOO
MOVEM T2,0(T1) ;ADVANCE LIST
SKIPGE LDBDCH(U) ;IS OUTPUT ALREADY GOING?
JRST SONPJ1 ;LINE IDLE, GIVE GOOD RETURN
MOVEI T2,L1RCHP
TDNN T2,LDBBYT(U) ;NEED TO SEND CHANGE PARAMETER MESSAGE?
JRST TOTAK1 ;NO, SKIP TO NEXT
; JRST SONPJ1 ;YES, RETURN THE LINE
;
;ROUTINE TO ALLOW SCANNER INTERRUPTS AGAIN AND SKIP RETURN
SONPJ1::AOSA 0(P) ;SKIP RETURN
SONTPJ::POP P,T1 ;ADJUST THE STACK (RESTORE T1?)
SONPPJ::SCNON ;ALLOW SCANNER INTERRUPTS
POPJ P, ;AND RETURN
SUBTTL RECEIVE INTERRUPT ROUTINE
;HERE FROM DEVICE-DEPENDENT INTERRUPT ROUTINE ON A RECEIVE INTERRUPT.
;AT THIS POINT, T3(28-35) HAS RECEIVED CHARACTER, U HAS PHYSICAL LINE #
;AS INDEX INTO LINTAB
RECINT::SE1ENT ;ENTER SECTION 1
MOVE U,LINTAB##(U) ;LOAD LDB ADDRESS
RECPTY::MOVEI T2,L1RMIF ;MIC INTERLOCK FLAG
SCNOFF ;LOCK OTHER CPU
TDNE T2,LDBBYT(U) ;IS MIC TYPING ON THIS LINE?
JRST RECQUE ;LINE INTERLOCKED, QUEUE THE CHARACTER
IORM T2,LDBBYT(U) ;SET THE INTERLOCK BIT
SCNON ;ALLOW INTERRUPTS
PUSHJ P,RECINI ;PROCESS THE INTERRUPT
RECINU: SCNOFF ;SIGH. GOTTA DO THIS INTERLOCKED
SKIPE RCQCNT ;ANY CHARACTERS QUEUED UP?
PJRST RECUNQ ;YES, TRY TO UN-QUEUE THEM
MOVEI T2,L1RMIF ;"MIC" INTERLOCK FLAG
ANDCAM T2,LDBBYT(U) ;CLEAR INTERLOCK
JRST SONPPJ ;RELEASE SCNSER AND DISMISS INTERRUPT
;RECQUE - QUEUE UP AN INPUT CHARACTER FOR A LINE THAT IS INTERLOCKED
;
;CALLED WITH CHAR IN T3 AND SCNSER INTERLOCK
RECQUE: AOS RCQHIT ;COUNT TOTAL INTERLOCKS HIT
AOS T2,RCQPTR ;ADVANCE THE QUEUE PUTTER
CAIG T2,RCQEND ;FALLEN OFF THE END?
JRST .+3 ;NO, STILL WITHIN THE QUEUE BUFFER
MOVEI T2,RCQBEG ;YES, WRAP THE PUTTER AROUND TO THE START
MOVEM T2,RCQPTR ;OF THE QUEUED CHARACTER BUFFER
CAMN T2,RCQTKR ;HIT THE TAKER YET?
JRST RECQU9 ;YES, BUTTS, GO FALL OVER
HRRZM T3,(T2) ;NO, STILL ROOM, STASH THE CHARACTER
HRLM U,(T2) ;AND THE LDB WHICH OWNS IT
AOS RCQCNT ;COUNT UP CHARACTERS QUEUED
JRST SONPPJ ;AND GET OUT OF HERE
;CHARACTER QUEUE FULL
RECQU9: SOS RCQPTR ;BACK UP THE PUTTER
AOS T2,RQFCNT ;COUNT OF TIMES HERE
CAIE T2,1 ;FIRST TIME HERE
JRST SONPPJ ;NO, DON'T CLUTTER UP THE DISK SPACE
STOPCD SONPPJ,DEBUG,RQF;++ RECINT QUEUE FULL
;RECUNQ - UN-QUEUE THE QUEUED CHARACTERS FROM RECINT
;
;CALLED WITH BOTH SCNSER AND MIC (L1RMIF) INTERLOCK SET
RECUNP: SCNOFF ;GET SCNSER INTERLOCK
SKIPG RCQCNT ;REALLY ANYTHING QUEUED?
JRST RECUSZ ;NAW, NOTHING TO DO
;TRY TO PROCESS CHARACTER QUEUE
RECUNQ: MOVE T2,RCQTKR ;COPY OF QUEUE TAKER
ADDI T2,1 ;ADVANCE TO NEXT ENTRY
CAILE T2,RCQEND ;FALLEN OFF OF END YET?
MOVEI T2,RCQBEG ;YES, WRAP THE TAKER BACK TO THE BEGINING
SKIPN T1,(T2) ;GET FIRST ENTRY IN CHARACTER QUEUE
JRST RECUNX ;EMPTY, TOSS IT AND LOOK FOR MORE
HLRZ T1,T1 ;POSITION LDB ADDRESS
CAIE T1,(U) ;THE LDB WE'RE INTERESTED IN?
JRST RECUSQ ;NO (BLETCH) SCAN THE QUEUE THEN
PUSH P,T3 ;SAVE ORIGINAL CALLER'S CHARACTER
HRRZ T3,(T2) ;GET QUEUED CHARACTER
SETZM (T2) ;CLEAR OUT SO WE NEVER SEE IT AGAIN
MOVEM T2,RCQTKR ;ADVANCE THE QUEUE TAKER
SOS RCQCNT ;ONE LESS CHARACTER IN THE QUEUE
;PROCESS THE QUEUED CHARACTER (L1RMIF STILL SET)
RECUNT: SCNON ;WE CAN SAFELY ALLOW INTERRUPTS NOW
PUSHJ P,RECINI ;PROCESS QUEUED CHARACTER
POP P,T3 ;RESTORE STACK
JRST RECUNP ;AND CHECK REST OF THE QUEUE
;HERE WHEN THE QUEUE STARTS OFF WITH A HOLE
RECUNX: MOVEM T2,RCQTKR ;ADVANCE THE QUEUE TAKER
SOSE RCQCNT ;COUNT DOWN THE CHARACTERS QUEUED
JRST RECUNQ ;AND CHECK THE REST OF THE QUEUE
MOVEI T2,L1RMIF ;"MIC" INTERLOCK
ANDCAM T2,LDBBYT(U) ;CLEAR LINE INTERLOCK
MOVE T2,RCQPTR ;THE QUEUE PUTTER
CAIGE T2,RCQBEG ;SOSED AT UNFORTUNATE MOMENT?
MOVEI T2,RCQEND ;YES, REALLY STILL AT END THEN
CAMN T2,RCQTKR ;PUTTER MATCH TAKER?
JRST SONPPJ ;YES, ALL SET, JUST GO AWAY
STOPCD .+1,DEBUG,RQD ;++ RECINT QUEUE DISCREPANCY
MOVE T2,RCQTKR ;GET THE TAKER
MOVEM T2,RCQPTR ;AND MAKE THE PUTTER MATCH
JRST SONPPJ ;AND SEE WHAT HAPPENS
;STILL SCNOFF'ED
;HERE WHEN FIRST ENTRY IN RECINT'S QUEUE IS NOT FOR THIS LINE. THE
;QUEUE MUST BE SCANNED FOR CHARACTERS WHICH DO BELONG TO THIS LINE
;IN ORDER TO PRESERVE CHARACTER SYNCHRONY.
RECUSQ: PUSH P,RCQCNT ;COUNT OF CHARACTERS QUEUED UP
RECUSS: SOSG 0(P) ;MORE TO CHECK?
JRST RECUSY ;NO, NOTHING FOR THIS LINE, GET OUT
ADDI T2,1 ;YES, ADVANCE TAKER TO NEXT CANDIDATE
CAILE T2,RCQEND ;FALLEN OFF THE END YET?
MOVEI T2,RCQBEG ;YES, WRAP AROUND TO THE FRONT
SKIPN T1,(T2) ;FETCH COPY OF THIS QUEUE ENTRY
JRST RECUSS ;EMPTY ENTRY, CHECK REST OF QUEUE
HLRZ T1,T1 ;POSITION ADDRESS OF LDB
CAIE T1,(U) ;OUR LDB?
JRST RECUSS ;NOPE, SKIP THIS ENTRY THEN TOO
;AN EMBEDDED QUEUE ENTRY FOR THIS LINE, GET AND DELETE IT
MOVEM T3,0(P) ;SAVE REAL T3 FOR CALLER
HRRZ T3,(T2) ;FETCH QUEUED CHARACTER TO BE RECINT'ED
SETZM (T2) ;NOTE THE CHARACTER PROCESSED
JRST RECUNT ;PROCESS QUEUED CHARACTER
;NOTHING TO DO, RELEASE INTERLOCK AND DISMISS "INTERRUPT"
RECUSY: POP P,T1 ;UNWIND THE STACK BY 1
RECUSZ: MOVEI T2,L1RMIF ;THE "MIC" INTERLOCK FLAG
ANDCAM T2,LDBBYT(U) ;CLEAR THE INTERLOCK
JRST SONPPJ ;AND RELEASE SCNSER INTERLOCK
;RECINI - DO THE ACTUAL INPUT CHARACTER PROCESSING
RECINI: ;PROCESS ONE INPUT CHARACTER
AOS LDBICT(U) ;COUNT INPUT CHARACTERS THIS LINE
AOS %SCNRI ;AND INPUT CHARACTERS FOR THE SYSTEM
IFN FTRSP,<AOS .CPNRI##> ;PER CPU AS WELL
RECINM: ANDI T3,CK.CHR!CK.FDE ;JUST 8 BITS OF CHARACTER.
; CLEAR ANY DEVICE DEPENDENT BITS
IFN FTNET,< ;IF NETWORK
SKIPGE LDBREM(U) ;IF THIS IS AN ACTIVE VTM LINE,
JRST VTMREC## ; GO HANDLE NVT CHARS SPECIAL
>
MOVSI T1,L1LOFL ;PUT TERMINAL ON LINE
ANDCAM T1,LDBOFL(U) ;SINCE SOMEONE IS THERE
MOVE T1,LDBDCH(U) ;GET LINE CHARACTERISTICS
SKIPL LDBTTW(U) ;ANF-10 KNOWS WHAT IT IS DOING, PROCESS CHAR
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
TRNN T1,LDRDSD ;IS IT A DATASET LINE?
JRST RECINN ;NO. PROCESS CHARACTER
LDB T1,LDPDSC ;GET DATASET TABLE INDEX
MOVE T1,DSCTAB##(T1) ;GET DATASET DATA
TLNE T1,DSCBLI ;WANT TO IGNORE INTERRUPTS?
POPJ P, ;YES, DO SO
RECINN:
MOVEI T1,ST.NRT ;THE STAND ALONE (NO REMOTE) BIT
TDNE T1,STATES## ;IS THE SYSTEM STAND ALONE?
JRST [HRR T1,LDBDCH(U) ;YES, GET CHARACTERISTICS
TRNN T1,LDRDSR ;IS THE TERMINAL REMOTE/DATASET?
JRST RECIN1 ;NO, LOCAL, ALLOW IT
HRRZ T1,LDBDDB(U) ;REMOTE, BUT IS IT ALREADY IN USE?
JUMPN T1,RECIN1 ;YES, ALLOW IT TO CONTINUE TO WORK
JRST BEATIT] ;NO, DUMP IT
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
RECIN1: SKIPN LDBIST(U) ;ARE WE DOING SOMETHING SPECIAL?
JRST RECIN2 ;NO, SKIP OVERHEAD
PUSHJ P,RECDCS ;YES, HANDLE IT
POPJ P, ;DON'T STORE
RECIN2: MOVE T1,LDBOST(U) ;GET STATE BITS IN LH.
TLNE T1,LOLPIM ;PIM MODE?
JRST REPIM ;YES, GO TO PIM CODE
MOVE T1,LDBDCH(U) ;CARRY DEVICE BITS IN LH.
SKIPG TTFREN## ;ANY SPACE FOR CHARACTERS?
JRST RCHLT1 ;NO. SHUT IT DOWN.
TLNN T1,LDLIMI ;IN IMAGE INPUT MODE?
JRST RECIN3 ;NO.
MOVEI T1,IMGTIM ;YES. RESET TIMEOUT FIELD TO MAX
DPB T1,LDPTIM ; ..
TRO T3,CK.IMG ;MARK IN NINTH BIT.
JRST RECINA ;AND GO STORE IN BUFFER. NO BREAK.
RECIN3: SKIPL LDBBY3(U) ;NEED TO TOGGLE DEFERRED ECHO?
.CREF L3LDMC ;SHOW BIT WE TESTED
JRST RECIN4 ;NO, GO CHECK FOR SPECIAL CHARACTERS
PUSH P,T3 ;YES, SAVE INCOMING CHARACTER
MOVEI T3,L1RDEM ;THE CURRENT (DESIRED) STATE OF L1LDEM
TDNN T3,LDBBYT(U) ;IS IT ON?
SKIPA T3,[MC.DEF] ;NO, SET TO TURN IT OFF
MOVEI T3,MC.DEN ;YES, SET TO TURN IT ON
PUSHJ P,RECINA ;STORE IN INPUT BUFFER
MOVSI T3,L3LDMC ;THE FLAG THAT GOT US HERE
ANDCAM T3,LDBBY3(U) ;CLEAR IT TO AVOID THIS CODE NEXT TIME THROUGH
POP P,T3 ;RESTORE CHARACTER TO BE PROCESSED
RECIN4: SKIPL LDBATR(U) ;EIGHT-BIT TERMINAL?
TRZ T3,CK.PAR ;NO, CLEAR PARITY FOR SEVEN-BIT ASCII
PUSHJ P,RECMAP ;MAP CHARACTERS IF NECESSARY
POPJ P, ;DON'T STORE
PUSHJ P,RECOOB ;SEE IF AN OUT-OF-BAND CHARACTER OF SOME SORT
POPJ P, ;YES, AND COMPLETELY PROCESSED
RECIN5: PUSHJ P,SPCHEK ;SEE IF IT'S SPECIAL. SET T1 UP.
JRST RECINA ;NON-SPECIAL. GO STORE
TLNE T1,CHRIA ;DOES THIS CHAR NEED SPECIAL RCV HANDLING?
TLNN T1,CHNDFR ;CAN CHARACTER BE DEFERRED?
JRST RECINA ;YES, JUST STORE NORMALLY FOR NOW
PUSHJ P,(T1) ;CALL CHARACTER'S SPECIAL PROCESSOR
POPJ P, ;DON'T STORE RETURN
;FALL INTO ORDINARY CHAR HANDLER
;HERE WITH T1=CHARACTER BITS (LH=0 IF NONE), T3=CHARACTER + CK.??? BITS
RECINA: MOVE T2,LDBTIC(U) ;COUNT CHARACTERS LINE HAS INPUT
ADD T2,LDBECC(U) ;PLUS LEFT TO ECHO
PUSH P,T1 ;SAVE CHARACTER BITS
CAIG T2,TTIWRN## ;TIME TO WARN HIM?
JRST RWARNX ;NO, STUFF CHARACTER INTO CHUNKS
CAIGE T2,TTIMAX## ;IF HE IS WAY OVER, OR
SKIPG TTFREN## ;WE ARE OUT OF CHUNKS
JRST RECHLT ;THROW AWAY THE INPUT CHARACTER
PUSHJ P,PTBTCH## ;CHECK IF OLD PTY OR BATCH
JRST RWARNX ; CAN'T SEND XOFF
PUSHJ P,SNDXOF ;SEND XOFF
RWARNX: SCNOFF
STCHK T3,LDBTIP(U),RECINE ;STORE CHARACTER
AOS LDBECC(U) ;COUNT CHARACTER TO ECHO
POP P,T1 ;RESTORE T1
TLNE T1,CHBRK!CHCRET ;BREAK CHARACTER (OR LIKELY TO BECOME ONE)?
PUSHJ P,SETBKI ;YES, NOTE PLACE FOR RIDLN
SCNON
SETZ S, ;FOR RECIN6
RECIN6: TLNN T1,CHCNC ;IS THIS CHARACTER A CONTROL C?
TLO S,L2LCCS ;NO. PREPARE TO CLEAR L2LCCS BIT
TRNN T3,CK.IMG ;IF NOT A QUOTED CHARACTER,
TRNN T3,CK.MET ;SKIP THIS IF A META CHARACTER
ANDCAM S,LDBBY2(U) ;CLEAR DELETE AND CONTROL C FLAGS
PUSHJ P,TORCCT ;GET INPUT COUNT
CAIE T1,1 ;ONLY DO THE FOLLOWING IF IT JUST WENT NON-ZERO
PJRST TOPOKE ;OTHERWISE JUST GET ECHO STARTED
HRRZ F,LDBDDB(U) ;GET DDB POINTER
JUMPE F,TOPOKE ;SKIP PSI IF NONE
SKIPE DEVPSI(F) ;IF WANTING INTERRUPTS,
PUSHJ P,PSIAVL## ;WARN THAT INPUT IS AVAILABLE
PJRST TOPOKE ;QUEUE TO GET ECHO STARTED
RECINE: POP P,T1 ;ADJUST STACK
SCNON ;RELEASE TERMINAL SERVICE INTERLOCK
MOVSI S,L2LCCS ;CRUFTY BIT
JRST RECIN6 ;RETURN, CLEARING CRUFTY BIT
;ROUTINE TO REMEMBER THE BREAK CHARACTER POSITION IN LDBBKU
SETBKU: MOVE T2,LDBECT(U) ;LOCATION OF INPUT PUTTER
MOVEM T2,LDBBKU(U) ;SAVE IT
POPJ P,
;ROUTINE TO REMEMBER THE BREAK CHARACTER POSITION IN LDBBKI
SETBKI: MOVE T2,LDBTIP(U) ;LOCATION OF INPUT PUTTER
MOVEM T2,LDBBKI(U) ;SAVE IT
POPJ P,
;HERE TO SEE IF ANY INPUT CHARACTERS NEED TO BE MAPPED
RECMAP: MOVSI T2,LMLSSE ;SWITCH-SEQUENCE ENABLED BIT
TDNN T2,LDBCHM(U) ;IS IT?
JRST RECMP1 ;NO, DON'T COMPARE AGAINST IT
MOVEI T2,LISSWI ;PRE-SET INPUT STATE FOR SWITCH SEQUENCE
LDB T1,LDPSW1 ;GET SWITCH-SEQUENCE ONE
XOR T1,T3 ;FORM DIFFERENCES
TRNN T1,CK.CHR ;IS THIS IT?
PJRST SETDCS ;YES, SET FOR RECDCS AND GIVE DON'T-STORE RETURN
RECMP1: AOS (P) ;NO, FROM HERE ON WE'LL SKIP-RETURN
MOVE T1,T3 ;GET A COPY OF THE CHARACTER
ANDI T1,CK.CHR ;KEEP ONLY USEFUL BITS
LDB T2,LDPUNP ;GET THE UNPAUSE CHARACTER
CAMN T2,T1 ;IS THIS IT?
JRST RECMPQ ;YES, STORE AS ^Q
LDB T2,LDPESC ;NOT UNPAUSE, GET THE ESCAPE CHARACTER
CAMN T2,T1 ;IS THIS IT?
JRST RECMPA ;YES, STORE AS ESCAPE
;ADD ANY NEW MAPPED CHARACTER TESTS HERE
POPJ P, ;NOT TO BE MAPPED, RETURN IT UNCHANGED
RECMPQ: SKIPA T1,["Q"-100] ;UNPAUSE == ^Q
RECMPA: MOVEI T1,STDALT ;ESCAPE == STDALT
DPB T1,[POINT 8,T3,35] ;UPDATE RECEIVED CHARACTER
POPJ P, ;RETURN THE MAPPED VERSION
;HERE TO CHECK OUT THE POSSIBILITY OF HAVING AN OUT-OF-BAND CHARACTER
RECOOB: TRNN T3,CK.MET ;IS IT NOT A FUNCTION CHARACTER?
SKIPL LDBBKB(U) ;AND IS SPECIAL-CHARACTER MODE ENABLED?
JRST CPOPJ1## ;NO, GIVE CONTINUE RETURN
MOVE T1,T3 ;YES, COPY THE CHARACTER
ANDI T1,CK.CHR ;KEEP ONLY RELEVANT BITS
PUSHJ P,TOPGCB ;GET THE CORRESPONDING BITS IN T2
TRNN T2,CC.OOB ;IS IT AN INTERRUPT CHARACTER?
JRST CPOPJ1## ;NO, GIVE CONTINUE RETURN
TRNN T2,CC.CLR ;IS IT A 'CLEAR' CHARACTER?
JRST RECOB2 ;NO, DON'T HANDLE AS ONE
TRNN T2,CC.DFR ;IS IT DEFERRED CLEAR?
JRST RECOB1 ;NO, HANDLE IMMEDIATE CLEAR
MOVEI T2,LISDCI ;LINE INPUT STATE=DEFERRED-CLEAR INTERRUPT
PJRST SETDCS ;SETUP DEFERRED CHARACTER STATE AND RETURN
; (NON-SKIP RETURN BECAUSE DONE WITH THIS
; CHARACTER FOR NOW)
RECOB1: PUSHJ P,TSETI1 ;CLEAR TYPEAHEAD
JRST RECOB4 ;GO ENTER CHARACTER IN OOB STREAM AND RETURN NON-SKIP
RECOB2: TRNE T2,CC.DFR ;IS THIS A 'HELLO' OOB?
AOS (P) ;YES, GIVE SKIP RETURN AS WELL AS OOB PSI
RECOB4: SCNOFF ;MUST HAVE INTERLOCK
HRRZ T1,LDBDDB(U) ;GET DDB (IF ANY)
JUMPE T1,SONPPJ ;IT WENT AWAY
EXCH T1,F ;FOR BYTE POINTER
PUSH P,J ;PRESERVE FOR CALLER
LDB J,PJCHN## ;GET THE TARGET TO SIGNAL
EXCH T1,F ;RESTORE F
JUMPE J,JPOPJ## ;GIVE UP IF NO JOB/JCH FOR PSI
STCHK T3,LDBOOP(U),RECOB5 ;STORE THE CHARACTER FOR PSISER
AOS LDBOOC(U) ;COUNT IT UP
SCNON ;RETURN INTERLOCK
SIGNAL C$OOB ;RAISE THE INTERRUPT FOR THE USER
TRNA ;DON'T UNREAD IF DOESN'T WANT
PUSHJ P,SETUNR ;LIGHT UNREAD BIT
JRST JPOPJ## ;RESTORE J AND RETURN TO RECIN3
;HERE IF AN ERROR OCCURS TRYING TO STORE THE OOB CHARACTER
RECOB5: POP P,J ;RESTORE J
JRST SONPPJ ;GIVE UP
;HERE TO HANDLE DEFERRED CHARACTERS ON NEXT RECEIVE
RECDCS: LDB T2,LDPDCS ;GET THE REASON CODE
JUMPE T2,RECDC1 ;PROCEED WITH CHARACTER IF NONE
SETZ T4, ;GET A ZERO
DPB T4,LDPDCS ;CLEAR STATUS (IN CASE IT NEEDS TO BE SET AGAIN)
PUSHJ P,@DCSDSP(T2) ;CALL THE ROUTINE APPROPRIATE TO OUR STATE CODE
POPJ P, ;RETURN BLINDLY ON IGNORE RETURN
JRST RECDCS ;CHECK FOR NEW STATUS ON CONTINUE RETURN
RECDC1: SETZM LDBIST(U) ;CLEAR TO SPEED UP RECINT
JRST CPOPJ1## ;GIVE CONTINUE RETURN
DCSDSP: IFIW CPOPJ## ;STATE ZERO NEVER USED
IFIW DCSDCI ;DEFERRED CLEAR INTERRUPT
IFIW DCSQOT ;QUOTED CHARACTER
IFIW DCSSWI ;SWITCH SEQUENCE
IFIW DCSFND ;FIND A CHARACTER IN THE BUFFER
DCSDCI: LDB T2,LDPDTC ;GET THE PREVIOUS CHARACTER
XOR T2,T3 ;SEE WHAT'S DIFFERENT
SKIPL LDBATR(U) ;CHECK 8-BIT
.CREF LAL8BT ;SYMBOLIC REFERENCE
TRZ T2,CK.PAR ;IGNORE PARITY IF 7-BIT
TRNN T2,CK.CHR ;ARE THEY THE SAME?
PJRST RECOB1 ;YES, THIS IS NOW A CLEAR OOB
XOR T2,T3 ;NO, RESTORE PREVIOUS
PUSH P,T3 ;AND THE CHARACTER
MOVE T3,T2 ;MOVE PREVIOUS CHARACTER
PUSHJ P,RECIN5 ;RECEIVE AS SOMETHING OTHER THAN OOB
POP P,T3 ;RESTORE NEW CHARACTER
JRST CPOPJ1## ;GIVE SKIP RETURN
DCSQOT: LDB T2,LDPDTC ;GET THE PREVIOUS CHARACTER
ANDI T2,CK.FDE ;WANT ONLY THIS BIT
AND T2,T3 ;KEEP ONLY IF BOTH WERE ECHOED
ANDI T3,CK.CHR ;MASK DOWN TO CHARACTER ALONE
TRO T3,CK.IMG!CK.MET(T2) ;TURN ON QUOTING BITS (AND MAYBE CK.FDE)
PJRST RECIN5 ;STORE AND RETURN
DCSSWI: LDB T2,LDPDTC ;GET THE PREVIOUS CHARACTER
XOR T2,T3 ;SEE WHAT'S DIFFERENT
SKIPL LDBATR(U) ;IF 7-BIT,
.CREF LAL8BT
TRZ T2,CK.PAR ;TRUNCATE
TRNN T2,CK.CHR ;ARE THEY THE SAME?
PJRST DCSSW2 ;YES--GIVE IT UNLESS OTHERWISE SPECIAL
LDB T2,LDPSW2 ;NO, GET SEQUENCE'S SECOND CHARACTER
XOR T2,T3 ;SEE WHAT'S DIFFERENT
SKIPL LDBATR(U) ;IF 7-BIT,
.CREF LAL8BT
TRZ T2,CK.PAR ;TRUNCATE
TRNN T2,CK.CHR ;ARE THEY THE SAME?
JRST DCSSW1 ;YES, WE HAVE A BINGO
PUSH P,T3 ;NO, MUST DELIVER BOTH. SAVE CURRENT
LDB T3,LDPDTC ;GET FIRST PORTION AGAIN
PUSHJ P,DCSSW2 ;DELIVER IT AS APPROPRIATE
POP P,T3 ;RESTORE CURRENT
JRST CPOPJ1## ;GIVE CONTINUE RETURN
DCSSW1: PUSH P,T3 ;PRESERVE ACTUAL SW2 RECEIVED
MOVEI T3,CK.MET ;META FLAG USED FOR NXTOOB
PUSHJ P,RECOB4 ;STORE AS HELLO OOB
LDB T3,LDPDTC ;GET ACTUAL CHARACTER DEFERRED
PUSHJ P,SPCHEK ;GET ITS BITS
TRN ;IGNORE SKIP RETURN
PUSHJ P,RECINA ;STORE AS NORMAL
POP P,T3 ;RESTORE RECEIVED CHARACTER
PUSHJ P,SPCHEK ;GET ITS BITS
TRN ;IGNORE SPECIAL RETURN
PJRST RECINA ;STORE THIS ONE TOO AND RETURN
DCSSW2: PUSHJ P,RECMP1 ;MAP IF NECESSARY
TRNA ;PROPAGATE DON'T STORE RETURN
PUSHJ P,RECOOB ;SEE IF IT'S OUT-OF-BAND
TRNA ;DON'T STORE
PUSHJ P,RECIN5 ;STORE AS NORMAL
POPJ P, ;RETURN TO HANDLE NEXT CHARACTER
DCSFND: SKIPL LDBATR(U) ;IF 7-BIT
.CREF LAL8BT ;(NOTE BIT TESTED)
TRZ T3,CK.PAR ;CLEAR JUNK BIT
CAIN T3,3 ;CONTROL C?
JRST RICC ;YES, CAN'T LOOK FOR IT THEN
PUSHJ P,SAVE1## ;GET A COUPLE OF SCRATCH REGS
MOVE P1,T3 ;AND SAVE THE CHARACTER TO SEARCH FOR
ANDI P1,CK.CHR ;IGNORE RANDOM BITS
DCSFN1: ILDB T3,@LDBEDT(U) ;GET A CHARACTER
JUMPE T3,DCSFN2 ;NULL MEANS WE'RE DONE
TRNE T3,CK.IMG ;IF IMAGE,
TRO T3,CK.MET ;ASSUME QUOTED (9-BIT TRUNCATION PROBLEM)
PUSHJ P,SPCHEK ;GET BITS FOR CHARACTER
TRN ;IGNORE SPECIAL RETURN
PUSHJ P,RECINA ;STORE THE CHARACTER INTO THE LINE
XOR T3,P1 ;COMPARE CHARACTERS
TRNE T3,CK.CHR ;DID THEY MATCH?
JRST DCSFN1 ;NO, SO KEEP LOOPING
POPJ P, ;YES, GIVE DONE RETURN
DCSFN2: SETO T1, ;ADJUST BYTE POINTER TO THE NULL
ADJBP T1,@LDBEDT(U)
MOVEM T1,@LDBEDT(U) ;STORE IT BACK
POPJ P, ;GIVE DONE RETURN
;HERE TO SET UP DEFERRED CHARACTER STATUS FOR SWITCH SEQUENCE, QUOTING, AND OOB
SETDCS: DPB T2,LDPDCS ;STORE REASON CODE
DPB T3,LDPDTC ;DEFERRING THIS CHARACTER (IN CASE NEEDED)
POPJ P, ;RETURN
;HERE ON RECEIVE INTERRUPT OF A CONTROL-A CHARACTER
IFN FTMIC,< ;IF UNDER MIC CONTROL THEN ^A = ^C
RICA: SKIPE LDBMIC(U) ;GIVE NORMAL RETURN IF NOT UNDER MIC CONTROL
PUSHJ P,MICCHK ;DOES MIC WANT TO HEAR FROM US?
JRST CPOPJ1## ;NO, GIVE 'NORMAL' RETURN
;PJRST RICC ;YES, FALL INTO ^C ACTION ROUTINE
> ;END IFN FTMIC
;HERE ON RECEIVE INTERRUPT OF A CONTROL-C CHARACTER
RICC: PUSH P,T1 ;SAVE CHARACTER BITS
IFN FTMIC,< ;IF MIC
SKIPE T1,LDBMIC(U) ;IS MIC RUNNING FOR US?
PUSHJ P,MICRIC ;YES - EXTRA GOODIES
> ;END OF IFN MIC
PUSH P,T3 ;RIDLN CLOBBERS T3
PUSHJ P,RIDLN ;DO THE CONTROL-U FUNCTION
POP P,T3 ;RECOVER ^C FOR ECHO
HRRZ F,LDBDDB(U)
JUMPE F,RICC2
LDB J,PJOBN##
LDB T1,LDPDEB ;DEFERRED ECHO BITS
DPB T1,JBYDEB## ;SAVE IN JOB TABLE
RICC2: MOVSI T1,L2LCCS ;SEE IF SECOND CONTROL C
TDNN T1,LDBBY2(U) ; ..
JRST RICC1 ;NO
MOVSI T1,LOLSTP+LOLSSO;YES - CLEAR STOP BIT
ANDCAM T1,LDBOST(U)
IFN FTKL10,<
HRRZ T1,LDBISR(U) ;GET ISR DISPATCH
CAIE T1,TTDDSP## ;IS THIS A -20F LINE
JRST RICC2B ;NO
MOVSI T1,LTLXFF ;YES, SET BIT TO INFORM -20F
IORM T1,LDBTTD(U) ;
JRST RICC2A ;SKIP REMOTE CHECK
>;END IFN FTKL10
RICC2B:
IFN FTNET,<
SKIPL LDBTTW(U) ;ANF NETWORK VIRTUAL TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST RICC2A ; NO, DON'T SET LRRXFF
MOVEI T1,LRRXFF ;TELL FE ABOUT XON/XOFF STATUS
IORM T1,LDBREM(U) ;
>;END IFN FTNET
RICC2A: PUSHJ P,CNCCHK ;YES. AM I ALLOWED TO BELIEVE THE CONTROL-C?
JRST RICC1 ;SLAVE, OR NOT SECOND. JUST STORE
PUSHJ P,TTHALT ;JACCT AND TWO ^C^C
HRRZ F,LDBDDB(U) ;GET ATTACHED JOB
JUMPE F,RICC3 ;MAKE SURE THERE IS ONE
MOVE T1,DEVMOD(F) ;IS OWNING JOB ATTACHED TO TERMINAL,
TLNE T1,TTYATC ;OR JUST USING TERMINAL AS IO DEVICE?
JRST RICC3 ;ATTACHED. OK TO DO CONTROL C
MOVEI S,IODERR ;NOT ATTACHED
IORB S,DEVIOS(F) ;GIVE JOB AN ERROR BIT
PUSHJ P,TTWAKE ;AND WAKE IT UP
SETZM DEVNAM(F) ;MAKE IT INVISIBLE TO DEVSRC
PUSH P,U ;SAVE U IN CASE DDB IS KILLED
PUSHJ P,PTYDET ;GET LINE FREE OF DDB
POP P,U ;RESTORE U
RICC3: POP P,T1 ;RESTORE STACK LEVEL
PUSHJ P,TSETI1 ;FORCE ACTION. CLEAR BUFFERS
PUSHJ P,TSETBO ;BOTH INPUT AND OUTPUT. COMCON HAS
; BEEN FLAGGED BY CNCCHK
MOVEI T1,JS.NTO ;PARTIAL BUFFER REMAINING
SKIPE F ;MAKE SURE THERE WAS A DDB (ELSE JOB# IS JUNK)
ANDCAM T1,JBTSTS##(J) ;CLEAR BIT
MOVE T2,FILXCP ;GET ^C ECHO
PUSHJ P,SETFLE ;PUT INTO ECHO STREAM NOW (SO TYPES BEFORE DOT)
POPJ P, ;DISCARD CHARACTER
RICC1: MOVSI T1,L2LCCS ;SET "^C LAST IN" BIT
IORM T1,LDBBY2(U) ;NOT SECOND. STORE BIT.
RICC5: POP P,T1 ;RESTORE CHARACTER FLAGS
JRST CPOPJ1## ;AND TREAT AS RECEIVED CHARACTER
;HERE ON RECEIPT OF A ^D CHARACTER
RICD: MOVEI T1,JS.BPT ;GET THE BREAKPOINT ENABLED BIT
LDB T2,LDPLNO ;GET LINE NUMBER
IFE FTMP,<CAIE T2,TCONLN##>
IFN FTMP,<
CAILE T2,FRCLIN## ;IS IT A CTY?
CAILE T2,TCONLN## ;...
>
JRST RICD1 ;NO
TDNN T1,JBTSTS##+0 ;AND SOMEONE TYPE A "SET EDDT ON" COMMAND?
JRST RICD1 ;NO
SKIPE F,LDBDDB(U) ;GET DDB
PUSHJ P,INTLVL## ;CHECK FOR LEGALITY OF SVEUF CALL
TRNA ;NO DDB OR UUO LEVEL--PUNT THE UBR CHANGE
PUSHJ P,SVEUF## ;MAP JOB IF ANY
MOVEM 17,CDSAV+17 ;SAVE 17
MOVEI 17,CDSAV ;PLACE TO SAVE ACS
BLT 17,CDSAV+16 ;SAVE THEM
XCT .CPDDT## ;ENTER EDDT (MAYBE)
MOVSI 17,CDSAV ;RESTORE ALL ACS
BLT 17,17 ;AND
CDPAT:: POPJ P, ;PATCH TO JFCL TO PASS ^D TO COMCON
;HERE FOR RANDOM "TIMESHARING" ^D - TRY TO FORCE A .BPT COMMAND
RICD1: MOVE F,LDBDDB(U) ;GET DDB
JUMPE F,CPOPJ1## ;MAKE SURE THERE IS ONE
LDB T2,PJOBN## ;GET JOB NUMBER
JUMPE T2,CPOPJ1## ;CAN'T BE THE NULL JOB
TDNN T1,JBTSTS##(T2) ;IS JS.BPT TURNED ON?
JRST CPOPJ1## ;NO
MOVEI T1,TTFCXB ; FORCE A .BPT COMMAND
PJRST TTFORC ;AND LET COMCON WORRY ABOUT IT
$LOW ;MAKE CD ADDRESSABLE BEFORE HIGHIN REACHED
CDSAV: BLOCK 20 ;PLACE TO SAVE ACS AT CD BREAKPOINT
$HIGH
;HERE ON RECEIPT OF CONTROL F. IF EDITING TURNED ON, SET UP TO
;PROCESS THE NEXT CHARACTER, ELSE WE JUST TREAT IT AS USUAL.
RICF: SKIPE LDBEDT(U) ;DO WE HAVE EDIT MODE ON?
PUSHJ P,FULLCQ ;BKA OR FCS?
JRST CPOPJ1## ;YES. STORE FOR READER
MOVEI T2,LISFND ;LINE INPUT STATE=FINDING
PJRST SETDCS ;SET DEFERRED CHARACTER STATUS
;HERE ON RECEIPT OF A CARRIAGE RETURN (CONTROL M)
RICM: MOVEI T2,L2RXON ;IS XON TRUE?
TDNE T2,LDBBY2(U) ;...
JRST CPOPJ1## ;YES. NOTHING SPECIAL. STORE.
TRC T3,15^!MC.NL ;NO. CHANGE IT TO A NEWLINE
PJRST RICRET ;GET NEW BITS AND GIVE CONTINUE RETURN
;HERE ON RECEIVE INTERRUPT OF A CONTROL O
RICO: MOVEI T1,LDROSU ;COMPLEMENT STATE OF OUTPUT SUPPRESS BIT
XORM T1,LDBDCH(U) ;IN LINE DATA BLOCK
PUSHJ P,TSETBO ;CLEAR OUTPUT BUFFER
MOVE T2,FILXOP ;GET ^O ECHO
PUSHJ P,SETFLE ;SET TO ECHO
PJRST TOPOKE ;DISCARD CHARACTER BUT QUEUE THE LINE
;HERE ON RECEIVE INTERRUPT OF A CONTROL Q (XON)
RICQ: MOVSI T2,L2LTAP ;HAS TERMINAL TAPE COMMAND BEEN TYPED?
TDNE T2,LDBBY2(U) ; ..
JRST RICQ7 ;YES, HANDLE PAPER TAPE MODE
MOVE T2,LDBPAG(U) ;GET TERMINAL PAGING CONTROL
TLNN T2,LPLXNF ;PROCESSING XON/XOFF?
PJRST CPOPJ1## ;NO, DON'T DO ANYTHING SPECIAL WITH ^Q
TLNN T2,LPLSST ;IS TTY SSTOP SET?
JRST RICQ2 ;NO, ALWAYS CLEAR STOP COUNTER ON ^Q
MOVSI T2,LOLSTP ;YES, BE PICKY ABOUT CURRENT STATE
TDNE T2,LDBOST(U) ;IS THE LINE STOPPED BY ^S?
JRST RICQ3 ;YES, JUST CLEAR XOFF, LEAVE STOP COUNTER ALONE
MOVSI T2,LOLSSO ;NO. GET STOPPED-BY-SCNSER BIT
TDNN T2,LDBOST(U) ;IS TERMINAL OUTPUT "STOP"PED?
JRST RICQ4 ;NO, IGNORE THE XON
RICQ2: PUSHJ P,CLRPCT ;RESET STOP COUNTER
MOVSI T2,LOLSTP+LOLSSO;CLEAR STOP BIT(S) FOR TERMINAL OUTPUT
RICQ3: ANDCAM T2,LDBOST(U) ;..
MOVEI T1,ISRCHP ;TELL REMOTE STATION ABOUT ^Q
PUSHJ P,@LDBISR(U)
RICQ4: PJRST TOPOKE ;AND GO START OUTPUT AGAIN
RICQ7: MOVEI T1,L2RXON ;TURN ON BIT IN LINE CHAR WORD
IORM T1,LDBBY2(U) ; ENTER HERE FOR OTHER BITS TOO
MOVEI T1,ISRCHP
PUSHJ P,@LDBISR(U) ;TELL REMOTE STATION ABOUT THE ^Q.
PJRST CHKXN1
IFN FTMIC,< ;IF MIC
;HERE ON RECEIVE INTERRUPT OF CONTROL P (PROCEED)
RICP: SKIPN T2,LDBMIC(U) ;IS MIC RUNNING FOR US?
JRST CPOPJ1## ;NO - JUST RETURN
TLO T2,LDLCHK!LDLMCP;YES - SET UP ^P FLAG
RICB2: MOVEM T2,LDBMIC(U) ;PUT WORD BACK
RICB3: PJRST MICWAK ;WAKE UP MIC
;HERE ON RECEIVE INTERRUPT OF CONTROL B (BREAK)
RICB: SKIPN T2,LDBMIC(U) ;IS MIC RUNNING FOR US?
JRST CPOPJ1## ;NO TREAT AS ORDINARY CHAR
TLO T2,LDLCHK!LDLMCB;YES - SET UP ^B FLAG
JRST RICB2 ;AND TREAT AS ^P
> ;END OF IF MIC
;HERE ON A CONTROL T
RICT: PUSHJ P,DOCTLT ;PROCESS THE CONTROL-T
JRST CPOPJ1## ;WE WANT TO STORE IT
JRST [PUSHJ P,CLRPCT
JRST TTFORC] ;WE WANT TO DO USESTAT
JRST RIBUSY ;LINE ALREADY HAS A COMMAND
DOCTLT: LDB T2,LDPRTC ;GET BIT FOR TERMINAL RTCOMPAT
JUMPN T2,CPOPJ## ;IF IT IS =1 GIVE NON-SKIP RETURN
MOVE T2,LDBDCH(U) ;GET DEVICE FLAGS
TLNE T2,LDLSLV ;SLAVE?
POPJ P, ;YES--DO NOT FORCE CONTROL-T
MOVE F,LDBDDB(U) ;GET LINKED DDB ADDRESS
JUMPE F,RICT1 ;FORCE COMMAND IF ZERO
MOVE T2,DEVMOD(F) ;GET DEVICE BITS
TLNN T2,TTYATC ;CONTROLLING TERMINAL?
JRST CPOPJ## ;NO--JUST STORE THE CONTROL-T
RICT1: MOVEI T1,TTFCXW ;FORCE USESTAT
SKIPL LDBCOM(U) ;COMMAND ALREADY PENDING?
JRST CPOPJ1## ;NO--GIVE SINGLE SKIP
JRST CPOPJ2## ;YES--GIVE DOUBLE SKIP
;HERE ON A CONTROL R
RICR: LDB T2,LDPRTC ;RTCOMPATABILITY IN EFFECT?
JUMPN T2,CPOPJ1## ;JUMP IF SO, STORE CHARACTER IN THE INPUT BUFFER
PUSHJ P,FULLCQ ;COMMAND OR FULL CHARACTER SET?
JRST CPOPJ1## ;YES, STORE CHARACTER
TRC T3,<"R"-100>^!MC.RTS ;CHANGE INTO .TYPE BEGIN FUNCTION
PJRST RICRET ;GET NEW BITS AND GIVE CONTINUE RETURN
;HERE ON RECEIVE INTERRUPT OF CONTROL S (XOFF)
RICS: MOVSI T2,L2LTAP ;HAS TERMINAL TAPE COMMAND BEEN TYPED?
TDNE T2,LDBBY2(U) ; ..
JRST RICS7 ;YES, HANDLE PAPER TAPE MODE
PUSH P,T1 ;SAVE CHARACTER BITS (FOR RICC5)
MOVSI T1,LOLSTP ;GET THE "STOPPED BY ^S BIT"
PUSHJ P,STPOIS ;STOP OUTPUT (BUT DON'T RESET STOP COUNTER YET)
JRST RICC5 ;TTY NO XONXOF - TREAT AS NORMAL CHARACTER
MOVE T1,LDBPAG(U) ;GET PAGING CONTROL
TLNN T1,LPLSST ;"TTY SSTOP" SET?
PUSHJ P,CLRPCT ;NO, RESET STOP COUNTER (IF ANY)
JRST TPOPJ##
RICS7: MOVEI T1,L2RXON ;THE "XON IS TRUE" FLAG
ANDCAM T1,LDBBY2(U) ;CLEAR IT
MOVEI T1,ISRCHP
PJRST @LDBISR(U) ;TELL REMOTE STATION ABOUT THE ^S.
STPOIP: ;STOP OUTPUT IN PROGRESS
PUSHJ P,CLRPCT
STPOIS: MOVSI T2,LPLXNF ;HAS "TTY XONXOF" BEEN ENABLED?
TDNN T2,LDBPAG(U) ;...
POPJ P, ;NO, DON'T DO ANYTHING SPECIAL
IORM T1,LDBOST(U) ;NO MORE OUTPUT UNTIL XON IS TYPED
PJRST SETCH1 ;SKIP & TELL FE'S TO STOP NOW
BEATIT: SKIPA T2,[POINT 9,GAWTXT]
RIBUSY: MOVE T2,[POINT 9,BSYTXT]
PJRST SETNNP
BSYTXT: BYTE (9)102,165,163,171,FLLFLG
GAWTXT: BYTE (9)123,164,141,156,144,040,141,154,157,156,145,FLLFLG
;HERE ON RECEIVE INTERRUPT OF CONTROL V (QUOTE)
RICV: LDB T2,LDPQOT ;IS QUOTING ENABLED?
JUMPE T2,CPOPJ1## ;NO, JUST STORE NORMALLY
MOVEI T2,LISQOT ;LINE INPUT STATE=QUOTING
PJRST SETDCS ;SET DEFERRED CHARACTER STATUS
;ROUTINES TO IMPLEMENT 'TERMINAL PAGE N'
CLRPCT::SE1ENT ;ENTER SECTION 1
LDB T2,LDPSTB ;BASIC "STOP" SIZE
CAIN T2,1 ;IF "TTY STOP 1",
MOVEI T2,2 ;THEN ALLOW AT LEAST ONE LINE TO PRINT
MOVNI T2,-1(T2) ;NEGATIVE SO COUNTER COUNTS UP TO 0
; ALSO OFFSET BY ONE TO ALLOW TIME TO STOP
; FURTHER, IF NO VALUE SET (I.E., "0")
; THEN THIS GIVES US ^D254 LINES BEFORE
; WE MUST CHECK AGAIN
ANDI T2,377 ;MASK TO ONLY 8-BIT'S WORTH
DPB T2,LDPSTC ;RESET "STOP" COUNTER
POPJ P,
INCPCT: MOVSI T2,LDLPPS ;PROMPT-POS-SET BIT
ANDCAM T2,LDBDCH(U) ;CLEAR WHEN GOING TO A NEW LINE
MOVEI T2,001001 ;TWO NINE-BIT INCREMENTS
ADDB T2,LDBLSW(U) ;INCREMENT LENGTH AND STOP COUNTERS
TRNN T2,LPRLC0!LPRSC0;EITHER COUNTER "OVERFLOW"?
POPJ P, ;NO, NOTHING SPECIAL HERE THEN
;EITHER TOP OF NEW FORM, OR TIME TO AUTOMATICALLY STOP OUTPUT
LDB T1,LDPLNB ;BASIC "LENGTH" SIZE
MOVNI T1,-1(T1) ;NEGATIVE SO COUNTER COUNTS UP TO 0
ANDI T1,377 ;MASK TO ONLY 8-BIT'S WORTH
TRNE T2,LPRLC0 ;LENGTH COUNTER HIT 0?
DPB T1,LDPLNC ;YES, RESET LENGTH COUNTER
TRNN T2,LPRSC0 ;STOP COUNTER HIT 0?
POPJ P, ;NO, JUST LENGTH COUNTER, NOTHING SPECIAL
;TIME TO AUTOMATICALLY STOP OUTPUT
MOVE T1,LDBPAG(U) ;GET THE PAGING CONTROL FLAGS
LDB T2,LDPSTB ;AND THE BASIC STOP SIZE
TLNE T1,LPLSTP ;USER WANT TO AUTOMATICALLY STOP OUTPUT?
CAIG T2,0 ;YES, A STOP SIZE SPECIFIED?
PJRST CLRPCT ;NO, IGNORE THEN
IFN FTNET,<
SKIPL T1,LDBREM(U) ;IF VTM + SET HOST
.CREF LRLVTM ;(PUT TESTED BIT IN CREF)
>
PUSHJ P,PTBTCH## ;CHECK FOR BATCH PTY
PJRST CLRPCT ;DISABLE AUTO STOP FOR BATCH OR VTM LINES
MOVSI T1,LOLSSO ;GET "SCNSER STOPPED OUTPUT" BIT
PUSHJ P,STPOIP ;IF AT LIMIT, STOP OUTPUT, CLEAR COUNT
PJRST CLRPCT ;STPOIP NON-SKIPS IF TERMINAL NO PAGE
MOVSI T2,LOLNBS ;NEED BELL SENT STATE BIT
MOVE T1,LDBPAG(U) ;GET PAGE CONTROL
TLNN T1,LPLSBL ;WANT BELL ON AUTO STOP?
POPJ P, ;NO BELL
IORM T2,LDBOST(U) ;SET THE STATE BIT
PJRST TOPOKE ;ENSURE OUTPUT WILL BE DONE
;PACKED IMAGE MODE (PIM) RECEIVE CHARACTER PROCESSING
REPIM: MOVSI T2,LPLXNF ;THE PROCESS XON/XOFF BIT
TDNN T2,LDBPAG(U) ;HAS SET TERMINAL XONXOF BEEN SET?
JRST REPIM0 ;NO, DON'T LOOK FOR XON/XOFF
MOVE T2,T3 ;SAVE CHARACTER
ANDI T3,CK.CHR ;CLEAR POSSIBLE JUNK BITS
SKIPL LDBATR(U) ;8-BIT TERMINAL?
ANDI T3,CK.CH7 ;NO, ONLY 7 VALID DATA BITS
CAIN T3,21 ;IS CHARACTER AN XON?
JRST RICQ ;YES, TREAT AS NON PIM XON
CAIN T3,23 ;IS CHARACTER AN XOFF?
JRST RICS ;TREAT AS NON PIM XOFF IF SO
MOVE T3,T2 ;RESTORE CHARACTER AS RECEIVED
REPIM0: MOVE T2,LDBTIC(U) ;# OF CHARS INPUT
CAIL T2,TTPWRN## ;TIME TO WARN HIM?
JRST [CAIL T2,TTPMAX## ;YES, OVER MAXIMUM LIMIT?
JRST RCHLT1 ;YES, PIM LIMIT EXCEEDED
PUSHJ P,SNDXOF ;NO, STILL HOPE, SEND XOFF
PUSHJ P,RCVWAK ;AND GET USER'S ATTENTION
JRST REPIM2] ;ACCEPT THIS CHARACTER
CAIL T2,TTPBRK## ;TIME TO WAKE UP USER?
PUSHJ P,RCVWAK ;YES, NUDGE HIM
REPIM2: MOVE T2,TTFREN## ;COUNT OF FREE CHUNKS IN SYSTEM
CAIGE T2,5 ;STILL WITHIN REASONABLE LIMITS?
JRST RCHLT1 ;NO, SHUT IT DOWN
TRO T3,CK.IMG ;MARK IMAGE-CHARACTER BIT
SCNOFF ;NO INTERRUPTS
STCHK T3,LDBTIP(U),SONPPJ ;PLACE CHARACTER IN BUFFER
AOS LDBTIC(U) ;INCREMENT COUNT
MOVE T2,LDBTIP(U)
MOVEM T2,LDBECT(U) ;MAKE CHAR LOOK ECHOED
SCNON ;ALLOW INTERRUPTS
SKIPN T2,LDBPBK(U) ;GET AND TEST BREAK CHARACTER WORD
JRST RCVWAK ;NOTHING SPECIFIED, BREAK ON ALL
ANDI T3,CK.CHR ;CLEAR IMAGE-CHARACTER BIT FOR TEST
REPIM5: LSHC T1,9 ;GET TEST CHARACTER
XOR T1,T3 ;XOR WITH RECEIVED CHAR
TRNE T1,400 ;7 OR 8 BIT COMPARE?
TRNE T1,177 ;7 BIT, MATCH?
TRNN T1,377 ;8 BIT, MATCH?
JRST RCVWAK ;YES, BREAK CHAR, WAKE AND DISMISS
JUMPN T2,REPIM5 ;NO, TRY NEXT
JRST CPOPJ## ;DONE, DISMISS INTERRUPT.
SNDXOF::SE1ENT ;ENTER SECTION 1
MOVSI T1,LPLXOF ;GET THE "XOFF HAS BEEN SENT" BIT
TDNN T1,LDBPAG(U) ;HAVE WE SENT ONE?
JRST SNDXF2 ;NO, ALWAYS SEND THE FIRST XOFF
MOVE T1,LDBTIC(U) ;INPUT CHARACTER COUNT
ADD T1,LDBECC(U) ;PLUS THOSE NOT-QUITE-FULLY-INPUT
IDIVI T1,TTYMIC## ;ROUGHLY-MODULO TTYMIC?
JUMPN T2,CPOPJ## ;NO, DON'T SEND GOBS OF XOFFS
MOVSI T1,LPLXOF ;YES, SEND ANOTHER XOFF
; (IN CASE THE UGLY RACE BIT US THE FIRST
; TIME AND THE PREVIOUS XOFF(S) GOT LOST)
SNDXF2: IORM T1,LDBPAG(U) ;SET THE BIT SO WE DON'T SEND TOO MANY
PUSH P,T3 ;ISR WILL CLOBBER THIS
MOVEI T3,IRRCSL ;CODE TO SAY BUFFER LOW
MOVEI T1,ISRREM ;
PUSHJ P,@LDBISR(U) ;NOW CALL ISR
SKIPA T2,FLPPXF ;ISR DID'T SEND IT. WE MUST
JRST T3POPJ## ;XOFF SENT, POP T3 AND RETURN
PUSHJ P,SETXNP ;SET FILLER
PUSHJ P,TOPOKE ;MAKE SURE IT GETS OUT
JRST T3POPJ## ;RESTORE T3 AND RETURN
;HERE ON A CONTROL U AT INTERRUPT LEVEL ONLY
RICU: PUSHJ P,FULLCQ ;BREAK ON ALL CHARACTERS?
JRST CPOPJ1## ;YES. STORE THE ^U IN BUFFER
TRC T3,<"U"-100>^!MC.DL ;CONVERT TO DELETE-LINE
PJRST RICRET ;GET NEW BITS AND GIVE CONTINUE RETURN
RIDLN: PUSHJ P,STOPCM ;STOP COMCON
SKIPE LDBEDT(U) ;DOES USER HAVE EDITING ENEBLED?
CAIE T3,3 ;ARE WE HERE ON CTRL/C
JRST RIDLN2 ;NOT ENABLED, CONTINUE
PUSHJ P,EDTINI ;REINIT THE BUFFER
JRST RIDLN4 ;AND GO CONTINUE
RIDLN2: MOVEI T1,L2RECS ;TURN ON THE EAT LINE BIT
IORM T1,LDBBY2(U) ;IN THE LDB
PUSHJ P,TYIEAT ;GO EAT THE LINE
RIDLN4: SCNOFF ;NO INTERRUPTS
RIDLN1: SKIPN T1,LDBBKI(U) ;ANY BREAK POSITION SAVED?
JRST RIDLN3 ;NONE THERE. CHECK FOR ECHOED CHARS
CAME T1,LDBTIP(U) ;ANYTHING TO DELETE ?
PUSHJ P,DELCHR ;DELETE 1 CHAR
JRST SONPPJ ;NOTHING LEFT TO DELETE
JRST RIDLN1 ;LOOP OVER LINE
RIDLN3: SKIPN T1,LDBBKU(U) ;ANY BREAK POSITION SAVED?
JRST TSETI2 ;NONE THERE. JUST CLEAR THE BUFFER
CAME T1,LDBTIP(U) ;ANYTHING TO DELETE?
PUSHJ P,DELCHR ;DELETE 1 CHAR
JRST SONPPJ ;NOTHING LEFT
JRST RIDLN3 ;LOOP OVER LINE
DELCHR: SOSGE T3,LDBECC(U) ;ANY LEFT TO ECHO?
JRST [SETZM LDBECC(U) ;CLEAR ECHO COUNT
MOVSI T1,L3LEHD!L3LEPD ;BITS THAT MIGHT BE ON FOR OUR CHAR
ANDCAM T1,LDBBY3(U) ;MAKE SURE THEY'RE NOT
SOSL LDBTIC(U) ;CHECK FOR ECHOED INPUT
JRST [SETO T4, ;SET VISIBILITY FLAG
JRST DELCH3] ;ERASE THESE TOO
SETZB T3,LDBTIC(U) ;CLEAR INPUT COUNT
SETZM LDBIIC(U) ;CLEAR INVISIBLE COUNT
SETZM LDBIEC(U) ;FOR BOTH SIDES
MOVE T1,LDBTIP(U)
MOVEM T1,LDBECT(U) ;ENSURE EMPTY ECHO STREAM
PUSHJ P,INPCHI ;MAKE SURE IT'S CONSISTENT
JRST DELCHR ;TRY SOME MORE IF NOT
POPJ P,] ;RETURN
DELCH3: LDB T1,LDBTIP(U) ;GET CHARACTER TO BE WIPED
TRNE T1,CK.NIS ;IF INVISIBLE CHARACTER
JRST [SKIPL T3 ;YES, DOING ECHO STREAM?
SOSA LDBIEC(U) ;YES, DECREMENT INVISIBLE CHAR COUNT
SOS LDBIIC(U) ;NO, INPUT, DECREMENT ITS COUNT
JRST DELCH4] ;REJOIN
TRNE T1,CK.FDE ;NOT INVISIBLE, NEED TO ECHO?
SETO T4, ;ECHOED CHARACTER, SET FLAG
DELCH4: SETO T1, ;AMOUNT TO BACK UP
ADJBP T1,LDBTIP(U) ;GET NEW COPY OF BYTE POINTER
MOVEI T2,CK.BDY##(T1) ;SEE IF HIT HEADER WORD
TRNN T2,CK.BDY## ;WELL...
JRST [SSX T2,MS.SCN ;SET SECTION NUMBER
HLRZ T1,CK.BTH##(T2) ;BACKUP
JUMPE T1,DELCH6 ;TEST FOR ERROR ON ZERO POINTER
ADD T1,[POINT CK.WID,CK.BDY##,35] ;MAKE INTO BYTE POINTER
JRST .+1]
DELCH5: MOVEM T1,LDBTIP(U) ;STORE ADJUSTED POINTER
JUMPG T3,CPOPJ1## ;IF NO ECHO STREAM INTACT
MOVEM T1,LDBECT(U) ;NO, MAKE SURE IT STARTS CORRECTLY
JRST CPOPJ1##
DELCH6: SKIPG T3 ;IF ECHO STREAM IS OK,
SKIPA T1,LDBTIT(U) ;NO, GET TYPEIN TAKER
MOVE T1,LDBECT(U) ;YES, GET ECHO TAKER
MOVE T2,T1 ;COPY IT
IBP T2 ;GET BUMPED COPY
CAME T2,LDBTIP(U) ;BACKING UP TO A PLACE WE UNDERSTAND?
STOPCD CLRSTP,DEBUG,DELCBD, ;++DELCHR WENT BAD
JRST DELCH5 ;YES, GO FOR IT
RECHLT: POP P,T1 ;RESTORE T1
RCHLT1::SE1ENT ;ENTER SECTION 1
MOVEI T3,IRRCNS ;CODE FOR CHAR NOT STORED
MOVEI T1,ISRREM
PUSHJ P,@LDBISR(U) ;TELL THE ISR CHAR NOT STORED
TRNA ;FE WANTS BELL SENT
JRST RCHLT2 ;FE WANTS NO BELL
MOVSI T2,LOLNBS ;NEED BELL SENT FLAG
IORM T2,LDBOST(U) ;LIGHT STATUS FLAG (LEAVE POSSIBLE XOFF POINTER ALONE)
RCHLT2: PUSHJ P,TOPOKE ;START TYPING IF NEEDED (USUALLY NOT NEEDED)
PJRST ECHBRK ;TRY TO WAKE JOB, THEN
;DISMISS INTERRUPT, JUNKING CHARACTER
;HERE ON A RUBOUT, BACKSPACE, OR CONTROL W AT INTERRUPT LEVEL
RICW: PUSHJ P,FULLCQ ;BKA OR FCS?
JRST CPOPJ1## ;YES. STORE FOR READER
TRC T3,<"W"-100>^!MC.DW ;CONVERT TO DELETE-WORD
PJRST RICRET ;GET NEW BITS AND GIVE CONTINUE RETURN
RIBSP: LDB T2,LDPAPL ;APL MODE
JUMPE T2,RIDEL ;TREAL LIKE RUBOUT IF NOT IN APL MODE
PUSHJ P,COMQ ;WE ARE IN APL MODE--DO WE CARE?
JRST CPOPJ1## ;NOT AT COMMAND LEVEL--OBEY .TOAPL SETTING
;IGNORE APL MODE AT COMMAND LEVEL
RIDEL: PUSHJ P,FULLCQ ;BKA OR FCS?
JRST CPOPJ1## ;YES. STORE FOR READER
MOVEI T2,L2RXON ;PAPER TAPE IN EFFECT?
TDNE T2,LDBBY2(U) ;YES, DISCARD RUBOUT
POPJ P, ;YES. DISCARD RUBOUT
MOVE T1,T3 ;COPY CHARACTER THAT BROUGHT US HERE
ANDI T1,CK.CHR ;MASK OFF CRUFTY BITS
CAIE T1,010 ;WAS IT BACKSPACE?
TRCA T3,177^!MC.DC ;NO, MAKE IT META-RUBOUT
TRC T3,010^!MC.BS ;YES, MAKE IT META-BS
JRST RICRET ;MUST DEFER TO XMTECH
;SUBROUTINE TO ADJUST HORIZONTAL POSITION WHEN ERASING CHARACTERS
;CALL WITH T2 = NUMBER OF POSITIONS TO BACKUP, RETURNS CPOPJ, T2 INTACT
BACKUP: PUSH P,T2 ;SAVE T2
MOVEI T3,10 ;BACKSPACE
BACKU1: PUSHJ P,ADJHP ;BACKUP 1 CHARACTER
SOJG T2,BACKU1 ;LOOP FOR ALL
JRST T2POPJ ;RESTORE T2 AND RETURN
;SUBROUTINE TO DETERMINE IF THE CURRENT TERMINAL IS A VIDEO TERMINAL
; I.E., SPECIFIED AS SUCH BY THE USER TYPING A TTY TYPE COMMAND
; RETURNS CPOPJ IF NOT, CPOPJ1 IF SO, T1 POINTS AT CHARACTERISTICS TABLE
; ENTRY FOR THE TERMINAL TYPE
TTVID: MOVSI T1,LDLLCP ;LOCAL COPY BIT
TDZE T1,LDBDCH(U) ;LINE DOING OWN ECHOING
POPJ P, ;YES, AVOID VIDEO STUFF (T1=0)
LDB T1,LDPTTT ;GET TERMINAL TYPE AS SET BY COMMAND
HLRZ T1,CTATAB##(T1) ;AND ASSOCIATED CLASS INDEX
SKIPE T1,CCBTAB##(T1) ;SKIP IF NOT A VIDEO TERMINAL
AOS (P) ;IT IS!
POPJ P, ;RETURN
;HERE ON ANY OF THE THREE ALTMODES, TO DECIDE ON CONVERSION TO STDALT
RIALT: PUSHJ P,RIALTO
JRST CPOPJ1##
RIALTO: PUSH P,T2 ;SAVE T2
MOVEI T2,(T3) ;GET A COPY OF THE CHAR.
ANDI T2,CK.CHR ;ISOLATE CHAR (REMOVE IMAGE/ECHO BITS)
CAIN T2,STDALT ;CHECK FOR TRUE ESC
JRST T2POPJ## ;DON'T ALTER
MOVEI T1,0 ;NO, ASSUME DATA CHAR
MOVSI T2,LPLALT ;CONVERT OLD ALTMODES?
TDNN T2,LDBPAG(U) ;TEST IT
JRST RIALT2 ;YES, SO GO DO IT
MOVE T2,LDBDCH(U) ;LINE FLAG BITS
TLNE T2,LDLLCT ;NO, BUT SHOULD WE CONVERT TTY UC?
TRC T3,040 ;YES, SO CHANGE IT
JRST T2POPJ## ;ALL DONE
RIALT2: MOVEI T3,STDALT ;YES USE THE STANDARD ALTMODE
MOVE T1,CHTABL(T3) ;NOW A BREAK, SO GET ITS BITS
JRST T2POPJ## ;STORE WHATEVER THIS DECIDED ON
;RECEIVE INTERRUPT ROUTINE FOR LINE CONTROL TRANSACTIONS
;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH
; TRANSACTION CODE IN T3,
; PHYSICAL LINE # IN U (IDX FOR LINTAB, LDBDCH, ETC)
; U'S RANGE CHECKED BY INTERRUPT ROUTINE
; AC'S & PDL SETUP
LNCREC::SE1ENT ;ENTER SECTION 1
MOVE U,LINTAB##(U)
CAIN T3,LNTEHC ;DISPATCH ON CHARACTER CODE IN T3
JRST LNREHC ;ENABLE HUNG CHECK
CAIE T3,LNTDHC
POPJ P, ;ILLEGAL CODE--IGNORE
MOVEI T3,LDRSHC ;DISABLE HUNG CHECK
IORM T3,LDBDCH(U) ; TURN ON LDRSHC
POPJ P,
LNREHC: MOVEI T3,LDRSHC ;TURN OFF LDRSHC
ANDCAM T3,LDBDCH(U)
POPJ P,
;RECEIVE INTERRUPT ROUTINE FOR DATASET TRANSACTIONS
;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH TRANSACTION CODE IN
; T3, DSCTAB INDEX IN U, RANGE ALREADY CHECKED BY INTERRUPT
; ROUTINE, AC'S AND PDL SET UP.
DSCREC::SE1ENT ;ENTER SECTION 1
MOVE T2,DSCTAB##(U) ;GET TABLE ENTRY FIRST
TLNE T2,DSCBLI ;IGNORE INTERRUPTS?
POPJ P,0 ;YES. DO SO.
PUSHJ P,SIGDSC ;SIGNAL, DATA SET STATUS CHANGE
CAIN T3,DSTRNG ;DISPATCH ON CODES
JRST DSRRNG ;RING FROM DATAPHONE
CAIN T3,DSTON ;CARRIER ON?
JRST DSRON ;YES.
CAIN T3,DSTPND ;DIALLER WANT ANOTHER DIGIT
JRST DSRPND ;YES
CAIN T3,DSTOFF ;OFF INTERRUPT?
TLNN T2,DSCHWC ;YES. DID I THINK HE WAS ON?
POPJ P,0 ;NO. FORGET IT.
TLNN T2,DSCSWC ;DO I THINK HE SHOULD BE ON?
JRST DSROF1 ;NO. JUST GO CLEAR HIM OUT.
MOVEI T1,5 ;YES. TIME OUT IN CASE OF BRIEF FAILURE
DPB T1,DSTMPL ;STORE IN TIME BYTE.
MOVSI T1,DSCHWC ;CLEAR THE CARRIER BIT
ANDCAM T1,DSCTAB##(U) ; ..
MOVSI T1,DSCFAI ;AND FLAG POSSIBLE FAILURE CONDITION
IORM T1,DSCTAB##(U) ; ..
POPJ P,0 ;LET CLOCK TIME HIM OUT NOW.
DSROF1::SE1ENT ;ENTER SECTION 1
MOVSI T1,DSCHWC!DSCSWC!DSCIC2
ANDCAM T1,DSCTAB##(U) ;CLEAR ALL THESE BITS IN TABLE
HRRZ T1,DSCTAB##(U) ;GET TERMINAL NUMBER FOR THIS MODEM
CAMN T1,DSDUNI## ;DIALLER CODE USED BY IT?
SETOM TTYDDL## ;YES. CLEAR INTERLOCK TO FREE IT.
MOVEI T3,DSTOFF ;AND SEND OFF-COMMAND TO DEVICE
DSCCAL::SE1ENT ;ENTER SECTION 1
HRRZ T2,DSCTAB##(U) ;T2 := LINE NUMBER
MOVEI T1,ISRDSC ;DATASET CONTROL FUNCTION
MOVE T2,LINTAB##(T2) ;LDB ADDRESS
PJRST @LDBISR(T2) ;DISPATCH TO INTERRUPT SERVICE
;SUBROUTINE TO SIGNAL DATA SET STATUS CHANGE
; ENTER T3=TRANSACTION CODE
SIGDSC::SE1ENT ;ENTER SECTION 1
HRRZ T1,T2 ;T1 := LINE NUMBER
MOVE T1,LINTAB##(T1) ;GET LDB ADDRESS
HRRZ F,LDBDDB(T1) ;GET ADDRESS OF DDB
MOVE T4,J ;SAVE J
JUMPE F,SIGDS1 ;ALL DONE IF ZERO
LDB J,PJOBN## ;GET JOB NUMBER
JUMPE J,SIGDS1 ;JUMP IF JOB 0 (CAN THAT HAPPEN?)
HRROI T1,C$DSET ;GET CONDITION TO SIGNAL
PUSHJ P,PSIJOB## ;NOTIFY ENTIRE JOB OF CONDITION (EACH JCH)
SIGDS1: MOVE J,T4 ;RESTORE J
POPJ P, ;RETURN
;STILL IN FTMODM
DSRON:
TLNN T2,DSCDLW ;IN DIALLER WAIT?
JRST DSRON1 ;NO.
MOVSI T1,DSCDLW!DSCEON ;YES. CLEAR FLAGS FOR DIALLER
ANDCAM T1,DSCTAB##(U) ;IN TABLE IN CORE
SETOM TTYDDL## ;FREE UP DIALLER CODE
MOVSI T1,DSCDLC ;SET SUCCESSFUL COMPLETION BIT
IORB T1,DSCTAB##(U) ;IN DATASET CONTROL TABLE
PUSH P,T2 ;SAVE OLD STATUS
PUSHJ P,DSCWAK ;WAKE THE JOB, IF ANY STILL THERE.
POP P,T2 ;RESTORE OLD BITS
DSRON1:
; LOCAL LINES. THIS ALLOWS USER TO GET SIGN ON MESSAGE
HRRZ T1,DSCTAB##(U) ;GET REAL LINE NUMBER
MOVE T1,LINTAB##(T1) ;GET ADDRESS OF LDB
MOVE T1,LDBDCH(T1) ;GET DEVICE BITS
TRNN T1,LDRDSD ;IS THIS A REAL DATASET LINE?
JRST DSRON2 ;NO--LOCAL TERMINAL JUST CAME UP
TLNE T2,DSCHWC ;HE CAME ON. IS THAT NEWS TO ME?
POPJ P,0 ;I THOUGHT HE WAS ON. FORGET IT.
TLNN T2,DSCSWC ;DO I WANT HIM ON?
JRST DSROF1 ;NO. GO FORCE HIM OFF.
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
MOVSI T1,DSCTMM+DSCFAI;YES. CLEAR TIME AND FAILURE BITS
ANDCAM T1,DSCTAB##(U) ;IN THE TABLE (STILL IN T2)
MOVSI T1,DSCHWC ;MARK THAT HE CAME ON
IORM T1,DSCTAB##(U) ;IN TABLE
TLNE T2,DSCFAI+DSCDLW;WAS ALL THIS A BRIEF FAILURE?
POPJ P,0 ;YES. JUST DISMISS, HE'S BACK.
MOVSI T1,DSCBLI+DSCNCR;NO. NEW GUY. SET BLIND AND DELAY BITS
HRRZ F,T2 ;GET JUST LINTAB INDEX
MOVE F,LINTAB##(F) ;LDB
HRRZ F,LDBDDB(F) ;DDB
JUMPE F,DSRN1A ;GO IF NO DDB
MOVE T4,DEVMOD(F) ;CHARACTERS
TLNN T4,TTYATC ;IF CONSOLE
TRNN T4,ASSCON!ASSPRG;AND NOT ASSIGNED
DSRN1A: TLO T1,^D60 ;SET TIME OUT
IORM T1,DSCTAB##(U) ;IN DATASET CONTROL TABLE
DSRON2: HRRZ U,T2 ;GET JUST LINTAB INDEX
MOVE U,LINTAB##(U) ;GET LDB ADDRESS FOR LINE
PUSHJ P,TSETBI ;CLEAR INPUT BUFFER
IFN FTNET,<
SKIPGE LDBREM(U) ;IF THIS IS A VTM LINE,
PUSHJ P,VTMDSO## ; TURN CARRIER AND QUEUE LINE FOR SERVICE
>
MOVSI T1,L1LOFL
ANDCAM T1,LDBOFL(U)
SKIPGE DEBUGF##
POPJ P,
HRRZ F,LDBDDB(U) ;GET DDB
JUMPN F,CPOPJ## ;DO NOT RUN INITIA IF THERE IS A
; JOB ON THE LINE
MOVEI T1,TTFCXH ;GET HELLO COMMAND INDEX
JRST TTFORC ;FORCE HELLO COMMAND
DSRRNG: MOVE T1,STATES## ;PHONE RINGING. MAY I ANSWER?
TRNE T1,ST.NRL ;CHECK THE SCHEDULE COMMAND WORD
POPJ P,0 ;NOT ALLOWED. IGNORE.
PUSH P,U ;SAVE PTR TO DSCTAB
HRRZ U,DSCTAB##(U) ;GET REAL LINE NUMBER
MOVE U,LINTAB##(U) ;GET ADR OF LDB
MOVE T1,LDBDCH(U) ;GET DEVICE BITS
TRNN T1,LDRDSD ;IS THIS A DATASET LINE?
JRST UPOPJ## ;NO
HRRZ F,LDBDDB(U) ;DDB PTR
JUMPE F,DSRRN2 ;NO JOB, ALL OK
MOVE T1,DEVMOD(F) ;DEVICE BITS
TLNN T1,TTYATC ;CONTROLLING TTY?
JRST DSRRN2 ;NO, SO NO JOB
;IF WE GET HERE, WE HAVE RING ON LINE
; WITH A JOB, WHICH IS NOT SUPPOSED TO
; HAPPEN. TO PREVENT SECURITY PROBLEMS,
; WE DETATCH THE JOB
PUSHJ P,DSCDET ;DETACH OR KILL IF NOT LOGGED IN.
DSRRN2: POP P,U ;RESTORE DSCTAB PTR
MOVEI T3,0 ;CLEAR VARIOUS
DPB T3,DSTMPL ; TIMERS
MOVSI T1,DSCFAI+DSCTMM;CLEAR THE MOMENTARY FAILURE BIT
ANDCAM T1,DSCTAB##(U) ; ..
MOVSI T1,DSCSWC+^D30 ;TURN ON ALLOW BIT, AND TIME.
DSRRN1: IORM T1,DSCTAB##(U) ;IN DATASET CONTROL TABLE
MOVEI T3,DSTON ;SEND A TURN-ON COMMAND TO DEVICE-
PJRST DSCCAL ; DEPENDENT ROUTINE, AND DISMISS
DSCDET: MOVEI T1,TTFCXD ;DO THE DETACH BY
PJRST TTFORC ; FORCING A .BYE
DSRPND: TLNE T2,DSCEON ;SENT ALL DIGITS?
POPJ P,0 ;YES. IGNORE REQUEST
MOVEI T1,^D60 ;ONE MINUTE FROM SENDING DIGIT
DPB T1,DSTMPL ;INTO TIME-OUT OF DATASET
MOVSI T1,DSCEON ;FLAG END OF NUMBER SENT, IF TRUE.
ILDB T3,TTYDDA## ;GET ANOTHER DIGIT
CAIN T3,17 ;END OF NUMBER CODE?
JRST DSRPN1 ;YES
ADDI T3,DSTPND ;CONVERT TO TRANSACTION CODE FOR XXXINT
PJRST DSCCAL ;AND SEND IT OUT
DSRPN1: IORM T1,DSCTAB##(U) ;SET FLAG IN TABLE
POPJ P,0 ;DON'T SEND NUMBER
SUBTTL KS10 CTY AND KLINIK TERMINAL SERVICE
IFN FTKS10,<
CT0INT::SKIPN .CPFEF## ;HAS FRONT END INTERRUPTED ?
JRST .-1 ;ON THROUGH SKIP CHAIN
WRPI CLRCTY## ;CLEAR THE INTERRUPT
SETZM .CPFEF## ;CLEAR THE FLAG
JSR SCNSAV## ;SAVE AC'S ETC.
MOVE T3,KLIIWD ;GET KLINIK INPUT WORD
TRNN T3,KLIIVL ;IS THERE INPUT?
JRST CTYIN1 ;NO--PROCEED
SETZM KLIIWD ;YES--CLEAR IT
MOVEI U,KLILIN## ;GET KLINIK LINE NUMBER
PUSHJ P,RECINT ;PASS TO SCNSER
CTYIN1: MOVE U,LINTAB+KLILIN## ;LDB FOR KLINIK LINE
SKIPL LDBDCH(U) ;IS KLINIK OUTPUT ACTIVE?
SKIPE KLIOWD ;YES--IS OUTPUT WORD AVAILABLE?
JRST CTYIN2 ;NO--PROCEED
MOVEI U,KLILIN## ;KLINIK LINE NUMBER
PUSHJ P,XMTINT ;SEE IF MORE TO TYPE
CTYIN2: SKIPN T3,CTYIWD ;ANY CTY INPUT?
JRST CTYIN3 ;NO--PROCEED
SETZM CTYIWD ;YES--CLEAR IT
MOVEI U,CTYLIN## ;CTY LINE NUMBER
PUSHJ P,RECINT ;PASS TO SCNSER
CTYIN3: MOVE U,LINTAB+CTYLIN## ;GET LDB ADR FOR CTY
SKIPL LDBDCH(U) ;IS CTY TYPING ?
SKIPE CTYOWD ;AND IS OUTPUT WORD FREE ?
JRST CTYIN4 ;NOT TYPING OR STILL BUSY
MOVEI U,CTYLIN## ;LINE NUMBER FOR CTY
PUSHJ P,XMTINT ;TRY TO TYPE MORE STUFF
CTYIN4: POPJ P, ;RETURN
>;END IFN FTKS10
SUBTTL FILLERS AND SIMULATION ROUTINES
;ROUTINE TO SET UP FILLERS FOR OUTPUT CHARACTERS
;CALL WITH
; MOVE T3,CHARACTER
; MOVE T1,CHTABL(T3)
; PUSHJ P,SETFLO
; <CHARACTER NEEDS FILLERS, ALREADY SETUP>
; <CHARACTER NEEDS NO FILL>
SETFLO: TLZ T1,CHUAE+CHALT+CHCRE ;THESE ECHO MODES NOT USED ON OUTPUT
TLO T1,CHFILO ;FLAG OUTPUT-FILLER REQUEST
JRST SETFL2 ;REST OF ROUTINE SAME AS ON INPUT
;ROUTINE TO SET FILLER POINTER FOR INPUT CHARACTERS (ECHOING)
SETFLI: TLNE T1,CHALT ;IS THIS A POSSIBLE ALTMODE?
PUSHJ P,RIALTO ;YES, SEE IF IT IS A REAL ALTMODE
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;COMMON CODE FOR SETFLI/SETFLO
SETFL2: MOVSI T2,L2LDEL ;BACKSLASH BIT
TDNE T2,LDBBY2(U) ;NEED ONE?
JRST [ANDCAM T2,LDBBY2(U) ;YES, CLEAR BIT
MOVE T2,FLLBSP ;GET BACKSLASH POINTER
PUSHJ P,SETFLE ;PUT INTO ECHO/FILL STREAM
AOS LDBHPS(U) ;COUNT UP FOR HPOS
JRST .+1] ;REJOIN
MOVE T2,LDBHPS(U) ;GET HORIZONTAL POSITION COUNTER
MOVE T4,LDBDCH(U) ;GET DEVICE BITS
TLNE T4,LDLDLR ;USER WANT DOLLAR SUPPRESSED?
TLZ T1,CHALT+CHUAE+CHCRE ;YES. DO SO.
TLNE T1,CHUAE ;WILL ^X BE ADDED?
ADDI T2,2 ;YES. ADD 2 TO HPOS
TLNE T1,CHALT ;IS IT GETTING A DOLLARSIGN?
ADDI T2,1 ;YES. COUNT IT.
JUMPLE T2,SETFI1 ;IF NOT AT END OF SCREEN
PUSHJ P,PTBTCH## ;CHECK FOR REGULAR PTY
JRST SETFI1 ;IT IS, NO FREE CRLF
MOVE T2,LDBDCH(U) ;GET THE CHARACTERISTICS WORD
TLNE T2,LDLNFC ;USER WANT FREE <CR><LF>?
JRST SETFI1 ;NO. FORGET IT.
; PJRST SETCRF ;YES, FALL INTO SETCRF
;SETCRF -- ROUTINE TO SETUP A FREE CRLF POINTER
SETCRF: PUSHJ P,SCNBOL ;RESET LINE COUNTERS IN ANY CASE
SKIPGE LDBTTW(U) ;IS THIS AN ANF NETWORK VIRTUAL TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST SETCR5 ;YES, THEN NO FILLER (THE REMOTE COMPUTER
; WILL SUPPLY THE FREE <CR><LF>, WE NEED
; MERELY NOTE THAT A NEW LINE IS STARTING)
MOVE T2,FLLCRF ;GET CRLF FILL POINTER
SETCR3: PUSHJ P,SETFLE ;SETUP THE APPROPRIATE FILLER POINTER
MOVSI T2,LDLLCP ;DON'T ECHO INPUT CHARACTER AFTER FREE CRLF
TLNN T1,CHFILO ; BUT IF OUTPUT, DON'T EAT A CHARACTER
TDNN T2,LDBDCH(U) ;IF LOCAL COPY IS SET
PUSHJ P,REEAT ;YES, RE-EAT THIS CHARACTER
POPJ P, ;NON-SKIP RETURN (NEEDED CRLF)
SETCR5: MOVE T2,T3 ;SCRATCH COPY OF CHARACTER
ANDI T2,CK.CH7 ;JUST SEVEN-BIT ASCII
CAIL T2,40 ;IS CHARACTER A
CAIL T2,177 ; NORMAL PRINTING ASCII GRAPHIC?
TLNE T1,CHALT!CHUAE ;NO, CONTROL, IF EITHER "$" OR "^X" FORM
AOS LDBHPS(U) ;THEN COUNTS AS A PRINTING CHARACTER
TLNE T1,CHUAE ;IN ADDITION, IF "^X" FORM
AOS LDBHPS(U) ; THEN COUNTS AS TWO PRINTING CHARACTERS
PUSHJ P,INCPCT ;COUNT LINES OUTPUT FOR TTY PAGE N
MOVE T4,LDBOST(U) ;GET LEFT-HALF CHARACTERISTICS
TLNN T4,LOLSSO ;DID INCPCT HIT A PAGE BREAK?
JRST CPOPJ1## ;NO, JUST OUTPUT THE FIRST CHARACTER
;HERE IF THE FREE <CR><LF> THAT WE KNOW THE REMOTE IS ABOUT TO OUTPUT
;(AS SOON AS IT SEES THE CHARACTER IN T3) WILL ALSO BREAK THE PAGE LIMIT.
;WE MUST SUPPLY THE FREE <CR><LF> AND THEN STOP IN ORDER TO MAKE THE
;REMOTE BEHAVE THE SAME AS LOCALLY-OWNED TERMINALS. THIS RELYS ON THE
;FACT THAT XMTSPC WILL FORCE OUT THE FILLER POINTER EVEN IF THE LINE
;IS XOFFED - A DUBIOUS FEATURE AT BEST.
PUSHJ P,SCNBOL ;OOPS - RE-CLEAR HORIZONTAL POSITION
;TECHNICALLY, INCPCT SHOULD BE UNDONE, SINCE THE <CR><LF> COMING WILL
;LEAVE IT OFF BY ONE, BUT THE XON NEEDED TO GET OUT OF THE STUCK STATE
;WILL RESET THE PAGE COUNTER, SO . . .
MOVE T2,FLLCRP ;WANT JUST A <CR><LF> - THE
; -11 WILL PROVIDE ANY FILL NEEDED.
JRST SETCR3 ;GO OUTPUT A NEW LINE
;HERE TO FORCE THE RE-EAT OF A CHARACTER AFTER FREE CRLF
REEAT: TLNN T1,CHFILO ;WAS THIS FOR OUTPUT?
JRST REEATE ;NO--DIFFERENT FOR ECHO
DPB T3,LDPREO ;YES--SAVE THE CHARACTER
MOVSI T2,LOLREO ;GET THE STATE BIT
IORM T2,LDBOST(U) ;SET FOR AFTER WE COME BACK
POPJ P, ;AND RETURN TO CALLER
REEATE: DPB T3,LDPREE ;SAVE CHARACTER FOR XMTREE
MOVSI T2,LOLREE ;GET THE STATE BIT
IORM T2,LDBOST(U) ;SET FOR AFTER WE COME BACK
POPJ P, ;AND RETURN TO CALLER
SETFI1: TLNN T1,CHFIL ;THIS CHAR NEED FILLERS?
JRST SETFI2 ;NO.
MOVE T2,T3 ;SAVE CHARACTER
ANDI T2,CK.CHR ;MASK DOWN
MOVE T2,CHTABL(T2) ;ORIGINAL BITS
TLNN T2,CHFIL ;CHARACTER REALLY NEED FILL?
PJRST SETFCE ;NO, JUST TYPE VIA FILL/ECHO STREAM AND RETURN
PUSH P,T3 ;SAVE THE CHARACTER
;*** CHAR MUST BE AT 0(P) FOR SIMULATORS ***
;*** EVEN THOUGH THIS IS BAD PRACTICE
ANDI T3,CK.CHR ;TRIM FUNNY BITS
MOVE T4,LDBDCH(U) ;GET DEVICE BITS (USED BY MOST FILL ROUTINES)
CAIG T3,15 ;NEED TO CALL ROUTINE FOR IT?
JRST @SETFLD-10(T3) ;YES. GO DO IT.
CAIL T3,21 ;CONTROL Q THRU T?
JRST SETFI6 ;YES. THEY HAVE SPECIAL HANDLERS TOO
PUSHJ P,SETFLC ;GET FILL CLASS
JUMPE T2,ZFLPOP ;NO. USER WANT FILLER SUPPRESSED?
SKIPA T2,FILLP1 ;NO. ASSUME ONE FILLER IS ENOUGH
ZFLPOP: MOVEI T2,0 ;POINTER FOR NO FILLERS
FLLPOP: PUSHJ P,FLLCHO ;CHARACTER TO TYPE BEFORE STRING
SCCHPJ: POP P,T3 ;RESTORE CHARACTER (MAYBE WITHOUT TYPING IT)
PJRST SETFLE ;TYPE THE FILLER POINTER AND RETURN NON-SKIP
; TO SHOW FILL WAS NEEDED
SETFI2: TLNN T1,CHUAE+CHALT+CHCRE ;ECHO AS ^X OR $ ?
JRST CPOPJ1## ;NO. NOTHING SPECIAL. JUST SEND.
TLNE T1,CHALT ;ALTMODE?
JRST SETFI3 ;YES.
MOVE T2,FLLUPA ;GET POINTER TO UPARROW CONST
PUSHJ P,SETFLE ;TYPE IT
TRC T3,100 ;CONVERT TO PRINTABLE FORM
MOVEI T2,2 ;WIDTH OF ^X
ADDM T2,LDBHPS(U) ;UPDATE HPOS
TLNN T1,CHCRE ;ALSO NEED <CR><LF>?
PJRST SETFCE ;NO, JUST TYPE ADJUSTED CHARACTER
PUSHJ P,SETFCE ;YES, TYPE MODIFIED CHARACTER
PJRST METNLF ;TYPE CRLF FILL AND RETURN
SETFI3: MOVE T2,FLLDLR ;GET POINTER TO DOLLARSIGN GRAPHIC
AOS LDBHPS(U) ;ADVANCE HORIZONTAL POSITION
PJRST SETFLE ;SET FILLER POINTER AND RETURN
SETFI6: TLNN T4,LDLDLR ;ECHOING GRAPHICS INHIBITED?
TLNE T1,CHFILO ;IS THIS FOR INPUT OR OUTPUT OF ^Q-^T?
JRST SETFI7 ;NO GRAPHICS. JUST THROW ON A RUBOUT.
MOVEI T2,2 ;LENGTH OF PRINT REPRESENTATION
ADDM T2,LDBHPS(U) ;ADD TO HORIZONTAL POSITION COUNTER
MOVE T2,STFLT2-21(T3);GET ECHO POINTER FOR CONTROL Q-T
JRST FLLPOP ;STORE FILLER AND RETURN
SETFI7: PUSHJ P,SETFLC ;GET FILL CLASS
SKIPE T2 ;FILL 0?
MOVE T2,FILLP1 ;NO, USE A FILLER
PJRST FLLPOP ;STORE FILLER AND GO HOME
FLLCHO: TLNE T1,CHFILO ;IS THIS FOR OUTPUT?
PJRST SETFCE ;YES, ALWAYS TYPE IT
PUSH P,T1 ;NO, SAVE FLAGS
MOVE T1,-2(P) ;GET PREVIOUS CHARACTER
ANDI T1,CK.IMG!CK.FDE;KEEP ONLY BITS WE CARE ABOUT
IOR T3,T1 ;MERGE INTO OUR CHARACTER
PUSHJ P,ECHTST ;DOES CHARACTER NEED ECHO?
PUSHJ P,SETFCE ;YES, TYPE IT
JRST TPOPJ## ;AND RETURN, RESTORING FLAGS
;SETFLC -- ROUTINE TO SETUP THE FILLER CLASS FOR A LINE
SETFLC:
IFN FTNET,<
SKIPL LDBTTW(U) ;ANF NETWORK TERMINAL DOES ITS OWN FILL
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
>
PUSHJ P,PTBTCH## ;ELSE, CHECK FOR REGULAR PTY
TDZA T2,T2 ;IT IS, USE FILLER CLASS 0
LDB T2,LDPFLC ;ELSE GET FILL CLASS FROM LDB
POPJ P, ; AND RETURN
;ROUTINE TO SETUP AN "XON CLASS" FILLER POINTER
;CALL
; MOVE T2,FILL POINTER
; PUSHJ P,SETXNP
; <ALWAYS RETURN HERE>
SETXNP::SE1ENT ;ENTER SECTION 1
SCNOFF ;GET SCNSER INTERLOCK
IFN FTXMON,<
TLNE T2,-1 ;IF REAL BYTE POINTER
TLO T2,(1B12) ;INDICATE EXTENDED BYTE POINTER
HLLZM T2,LDBXNP(U) ;STORE FIRST WORD
HRRZM T2,LDBXNP+1(U) ;STORE SECOND WORD TO ACCESS SECTION 0
>
IFE FTXMON,<
MOVEM T2,LDBXNP(U) ;JUST STORE
>
JUMPE T2,SONPPJ ;IGNORE IF NULL
MOVSI T2,LOLXFP ;XOFF PENDING BIT
IORM T2,LDBOST(U) ;SET IN STATES WORD
JRST SONPPJ ;RELEASE INTERLOCK AND RETURN
;ROUTINE TO SETUP A FILLER POINTER. SETS LOLFSP IF APPROPRIATE.
;CALL
; MOVE T2,FILLER POINTER
; PUSHJ P,SETFLP
; <ALWAYS RETURNS HERE>
;ENTER AT SETFPT IF SCNOFF
SETFLP::SCNOFF
SETFPT::SE1ENT ;ENTER SECTION 1
IFN FTXMON,<
TLNE T2,-1 ;IF REAL BYTE POINTER
TLO T2,(1B12) ;INDICATE EXTENDED BYTE POINTER
HLLZM T2,LDBFLP(U) ;STORE FIRST WORD
HRRZM T2,LDBFLP+1(U) ;STORE SECOND WORD TO ACCESS SECTION 0
>
IFE FTXMON,<
MOVEM T2,LDBFLP(U) ;JUST STORE
>
JUMPE T2,SONPPJ ;CLEARED WORD, JUST RETURN
SETFP1: MOVSI T2,LOLFSP
IORM T2,LDBOST(U) ;SET FLAG FOR XMTCHR
JRST SONPPJ ;NON-SKIP RETURN, TO FORCE OUT
;ROUTINE TO SETUP A 'NOT NOW' POINTER. SETS LOLNNP IF APPROPRIATE.
;CALL
; MOVE T2,FILLER POINTER
; PUSHJ P,SETNNP
; <ALWAYS RETURNS HERE>
SETNNP: SCNOFF
SE1ENT ;ENTER SECTION 1
IFN FTXMON,<
TLNE T2,-1 ;IF REAL BYTE POINTER
TLO T2,(1B12) ;INDICATE EXTENDED BYTE POINTER
HLLZM T2,LDBNNP(U) ;STORE FIRST WORD
HRRZM T2,LDBNNP+1(U) ;STORE SECOND WORD TO ACCESS SECTION 0
>
IFE FTXMON,<
MOVEM T2,LDBNNP(U) ;JUST STORE
>
JUMPE T2,SONPPJ ;CLEARED WORD, JUST RETURN
MOVSI T2,LOLNNP
IORM T2,LDBOST(U) ;SET FLAG FOR XMTCHR
SCNON ;ALLOW OTHERS AGAIN
PJRST TOPOKE ;MAKE SURE OUTPUT WILL HAPPEN
;ROUTINE TO OUTPUT A CHARACTER VIA ECHO/FILL STREAM
SETFCE: PUSHJ P,SAVT## ;PRESERVE REGISTERS
SCNOFF ;FOR STCHK
STCHK T3,LDBEOP(U),SETFE4 ;STUFF IN ECHO OUTPUT STREAM
AOS LDBEOC(U) ;COUNT SPECIAL OUTPUT CHARACTER
SCNON ;ALLOW INTERRUPTS AGAIN
JRST SETFE3 ;SET LOLESP AND RETURN
;ROUTINE TO OUTPUT A FILL SEQUENCE
;CALLED LIKE SETFLP, BUT WRITES INTO THE ECHO OUTPUT STREAM
SETFLE: JUMPE T2,CPOPJ## ;IGNORE NON-POINTERS
PUSHJ P,SAVT## ;PRESERVE THESE FOR CALLERS (EXCEPT T2)
SETFE1: ILDB T3,-2(P) ;GET NEXT CHARACTER OF SEQUENCE
CAIG T3,FLLFLG ;TERMINATOR? (NULL OR CRLF)
JRST SETFE2 ;YES, TERMINATE
SCNOFF ;NO, DISALLOW INTERRUPTS
STCHK T3,LDBEOP(U),SETFE4 ;STUFF IN ECHO OUTPUT STREAM
AOS LDBEOC(U) ;COUNT SPECIAL OUTPUT CHARS
SCNON ;ALLOW INTERRUPTS AGAIN
JRST SETFE1 ;LOOP UNTIL EXHAUST POINTER
;HERE WHEN POINTER EXHAUSTED FOR CRLF CHECK
SETFE2: JUMPE T3,SETFE3 ;NULL MEANS REALLY DONE
PUSHJ P,SCNBOL ;ELSE IS CRLF, SO BE SURE AT LEFT MARGIN
PUSHJ P,SETFLC ;GET OUR FILLER CLASS
MOVE T2,FLLCRP(T2) ;GET MATCHING CRLF POINTER
MOVEM T2,-2(P) ;SAVE AS CALLER'S BYTE POINTER
JRST SETFE1 ;AND REENTER LOOP
SETFE3: MOVSI T2,LOLESP ;ECHO STREAM PENDING
IORM T2,LDBOST(U) ;SET IN STATES WORD
POPJ P, ;RETURN TO CALLER
;HERE WHEN NO MORE ROOM IN CHUNKS FOR ECHO STREAM
SETFE4: SCNON ;INTERRUPTS AGAIN
PUSHJ P,ECHBRK ;WAKE UP THE OWNER
PUSHJ P,SNDXOF ;STOP INPUT UNTIL ROOM IN CHUNKS
MOVSI T2,LOLNBS!LOLESP;SEND BELL+XOFF, ECHO STREAM PENDING
IORM T2,LDBOST(U) ;SET IN STATES WORD
POPJ P, ;RETURN TO CALLER
;DISPATCH TO SET FILLERS FOR SOME CHARACTERS
SETFLD: IFIW FILLH ;010 BACKSPACE
IFIW FILLI ;011 HORIZONTAL TAB
IFIW FILLJ ;012 LINEFEED
IFIW FILLK ;013 VERTICAL TAB
IFIW FILLL ;014 FORMFEED
IFIW FILLM ;015 CARRIAGE RETURN
;POINTERS, CODE AND DATA FOR FILLER CHARACTERS
;HERE FOR A BACKSPACE AND HARDWARE VERTICAL TAB
FILLH:
FILLK2: PUSHJ P,SETFLC ;GET FILLER CLASS FOR LINE
MOVE T2,FILLHP(T2) ;GET FILLER BYTE POINTER
JRST FLLPOP ;GO STORE AND RETURN.
;HERE TO GENERATE FILLERS OR SIMULATION FOR HORIZONTAL TAB
;PHPOS IS UPDATED ALREADY, BUT POHPOS HAS THE PREVIOUS POSITION,
;LOW ORDER THREE BITS, SO THE TAB SIMULATION CAN BE DONE FROM IT.
FILLI:
IFN FTNET,<
SKIPGE LDBTTW(U) ;ANF NETWORK TERMINAL DOES ITS OWN FILL
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST ZFLPOP ;SO NO FILLERS
>
PUSHJ P,SETFLC ;GET FILLER CLASS
TLNN T4,LDLTAB ;USE TAB, OR MAKE IT OUT OF SPACES?
JRST FILLI1 ;SPACES.
TRNN T2,1 ;FILL CLASS 0 OR 2?
JRST ZFLPOP ;YES, NO FILLERS
LDB T1,POHPOS ;GET OLD POSITION ON LINE.
MOVE T2,FILLP2 ; ASSUME UNDER HALFWAY TO TAB STOP
TRNE T1,4 ;TRUE?
MOVE T2,FILLP1 ;NO. NEED JUST ONE FILLERS.
JRST FLLPOP ;GO STORE FILLER POINTER, SEND
; TAB, AND RETURN.
;HERE TO MAKE A TAB OUT OF SOME SPACES.
FILLI1: MOVEI T3,CK.IMG+040 ;WILL USE SPACES. DISCARD SAVED
; TAB ON STACK.
; IMAGE BIT BECAUSE HPOS NOW RIGHT
LDB T1,POHPOS ;GET LOW 3 BITS OF OLD HPOS
MOVE T2,FILLIP(T1) ;GET CORRESPONDING POINTER TO SPACES
JRST SCCHPJ ;TYPE FILLERS AND RETURN
;HERE TO HANDLE LINE FEED
FILLJ: PUSHJ P,SETFLC ;GET FILLER CLASS
MOVE T2,FILLJP(T2) ;GET THE CORRESPONDING FILLERS
JRST FLLPOP ;FOR A LINEFEED, AND RETURN.
;HERE TO HANDLE VERTICAL TAB
FILLK: TLNE T4,LDLFRM ;THIS LINE HAVE FORM MOTION?
JRST FILLK2 ;YES. USE SAME FILLERS AS BACKSPACE
PUSHJ P,SETFLC ;GET FILLER CLASS
MOVE T2,FLLKSP(T2) ;GET SIMULATION POINTER
PJRST SCCHPJ ;TYPE STRING BUT NOT CHARACTER
;HERE TO HANDLE FORM FEED
FILLL: TLNE T4,LDLFRM ;THIS LINE HAVE FORM MOTION?
JRST FILLL1 ;YES. GO SET FILLERS.
PUSHJ P,SETFLC ;GET FILLER CLASS
MOVE T2,FLLLSP(T2) ;GET POINTER TO LINEFEEDS AND FILLERS
PJRST SCCHPJ ;GO TO COMMON CODE
FILLL1: PUSHJ P,SETFLC ;GET FILLER CLASS
MOVE T2,FILLLP(T2) ;AND FILLER POINTER
JRST FLLPOP ;GO STORE THIS POINTER AND RETURN
FILLM: TLNE T1,CHFILO ;NO, IS THIS FOR IN OR OUTPUT?
JRST FILLM1 ;OUTPUT.
MOVEI T2,L2RXON ;XON BIT
TDNE T2,LDBBY2(U) ;XON IN EFFECT?
JRST ZFLPOP ;NO LOCAL, OR XON TRUE. THEREFORE,
MOVE T2,LDBDCH(U) ;GET DCH BITS BACK
TLNN T2,LDLLCP ;LOCAL COPY?
; NO FREE CRLF, OR IT WILL BE ECHOED
JRST FILLM1 ;NO LOCAL COPY
PUSHJ P,SETFLC ;GET FILL CLASS
MOVE T2,FLLCRP(T2) ;NEED A FREE LINEFEED.GET CRLF
IBP T2 ;AND COUNT IT PAST CR
JRST FLLPOP ;AND GO STORE RESULT
FILLM1: PUSHJ P,SETFLC ;GET FILLER CLASS
MOVE T2,FLLCOP(T2) ;GET FILLERS FOR CR OUTPUT
JRST FLLPOP ;GO STORE AND RETURN
;HERE FOR CONTROL-R COMMAND
RETYPE::SE1ENT ;ENTER SECTION 1
IFN FTNET,< ;IF WE HAVE THE NETWORK, WE
SKIPGE LDBREM(U) ; BETTER MAKE SURE THAT THIS ISN'T A VTM
POPJ P, ; CAUSE IF IT IS, THE CHUNKS ARE ALL
> ; MESSED UP AND WE WILL "RCC"
MOVEI T1,L1RMIF ;WE WANT THE 'MIC' (RECINT) INTERLOCK
MOVSI T2,LOLPIM ;BIT THAT MEANS THIS WON'T WORK
SCNOFF ;ONLY ONE AT A TIME...
TDNE T1,LDBBYT(U) ;CAN WE HAVE IT?
JRST [SCNON ;NO, ALLOW OTHERS
JRST DLYCM1##] ; AND WAIT UNTIL WE CAN HAVE THE INTERLOCK
TDNE T2,LDBOST(U) ;YES, BUT ARE WE IN PACKED IMAGE MODE?
JRST SONPPJ ;OOPS, THIS WON'T WORK, JUST PRETEND
IORM T1,LDBBYT(U) ;IT'S OK, GET IT
SCNON ;SAFE TO ALLOW OTHERS NOW
MOVEI T3,MC.RTS ;GET THE FUNCTION CHARACTER TO START IT GOING
SETZ T1, ;PRETEND IT HAS NO FLAGS
PUSHJ P,RECINA ;STORE IT IN THE INPUT CHUNKS
PJRST RECINU ;GIVE AWAY THE INTERLOCK AND RETURN
STOPCM: PUSH P,T1 ;SAVE T1
MOVEI T1,0 ;GET A ZERO AND USE IT TO
SCNOFF ;INTERLOCK W.R.T. CCTYI
PUSHJ P,CTISBP ; SAY THERE IS NO COMMAND ON THIS LINE
MOVSI T1,L1LQCC ;COMMAND CHARACTER QUOTE BIT
ANDCAM T1,LDBBYT(U) ;CLEAR IT
MOVSI T1,L3LCHD!L3LCPD ;8-BIT TRANSLATION BITS
ANDCAM T1,LDBBY3(U) ;NO MORE EXPANSION IN PROGRESS
SCNON ;RETURN INTERLOCK
JRST TPOPJ## ;RESTORE T1 AND RETURN
SUBTTL FILL CHARACTER DATA
FILLER: BYTE (9) 177,177,177,177 ;BLOCK OF 23 RUBOUTS
BYTE (9) 177,177,177,177
FILLRX: BYTE (9) 177,177,177,177
BYTE (9) 177,177,177,177
FILLRY: BYTE (9) 177,177,177,177
FILLRZ: BYTE (9) 177,177,177,0 ;ZERO TERMINATES THE STRING
KSPACE: BYTE (9) 040,040,040,040 ;BLOCK OF 8 SPACES.
BYTE (9) 040,040,040,040
BYTE (9) 0
FILLIP: POINT 9,KSPACE ;POINTERS FOR TAB SIMULATION
POINT 9,KSPACE,8
POINT 9,KSPACE,17
POINT 9,KSPACE,26
POINT 9,KSPACE,35
POINT 9,KSPACE+1,8
POINT 9,KSPACE+1,17
POINT 9,KSPACE+1,26
FLSLD0: BYTE (9) 12,12,12,12 ;LINEFEEDS W/O FILLERS.
FLSKD0: BYTE (9) 12,12,12,12 ; ..
BYTE (9) 0
FLSLD1: BYTE (9) 177,177,12,177 ;LINEFEEDS WITH 2 FILLERS.
BYTE (9) 177,12,177,177
BYTE (9) 12,177,177,12
FLSKD1: BYTE (9) 177,177,12,177
BYTE (9) 177,12,177,177
BYTE (9) 12,177,177,12
BYTE (9) 177,177,0
FLLKSP: POINT 9,FLSKD0 ;POINTERS TO SIMULATE ^K
POINT 9,FLSKD0
POINT 9,FLSKD1
POINT 9,FLSKD1
FLLLSP: POINT 9,FLSLD0 ;POINTERS TO SIMULATE ^L
POINT 9,FLSLD0
POINT 9,FLSLD1
POINT 9,FLSLD1
FLBLXF: BYTE (9) 007,023,177,0 ;DATA - BELL,XOFF,RUBOUT
FLPBEL::POINT 9,FLBLXF ;POINTER TO BELL-XOFF-RUBOUT
FLBPXF: BYTE (9) 023,0,0,0 ;DATA - XOFF SANS FILL
FLPPXF::POINT 9,FLBPXF ;POINTER TO XOFF WITH NO FILL
FLLXON: BYTE (9) 21,177,0 ;DATA - XON,RUBOUT
FLPXON: POINT 9,FLLXON ;POINTER TO XON-RUBOUT
FLLFLG==:1 ;FLAG TO ADD A CRLF AFTER THIS FILLER
FILXCP: POINT 9,FILXCD ;CONTROL C ECHO
FILXCD: BYTE (9) 136,103,FLLFLG ;^C CRLF
FILXUP: POINT 9,FILXUD ;CONTROL U ECHO
FILXUD: BYTE (9) 134,136,125,FLLFLG ;BACKSLASH ^U CRLF
FILXOP: POINT 9,FILXOD ;CONTROL O ECHO
FILXOD: BYTE (9) 136,117,FLLFLG ;^O CRLF
;DISPATCH FOR ^Q TO ^T ECHOES
STFLT2: POINT 9,FILXQD
POINT 9,FILXRD
POINT 9,FILXSD
POINT 9,FILXTD
FILXQD: BYTE (9) 136,121,21,177,0 ;^Q
FILXRD: BYTE (9) 136,122,22,177,0 ;^R
FILXSD: BYTE (9) 023,136,123,0 ;^S
FILXTD: BYTE (9) 24,136,124,0 ;^T
;POINTERS FOR BS AND VT
FILLHP: 0 ;NO FILLERS
FILLP2: POINT 9,FILLRZ,8 ;2 FILLERS
POINT 9,FILLRY,8 ;6 FILLERS
POINT 9,FILLRY,8 ;6 FILLERS
FILLLP: ;POINTERS FOR FORMFEED
0 ;NO FILLERS
POINT 9,FILLRX,26 ;12 FILLERS
POINT 9,FILLER,17 ;21 FILLERS
POINT 9,FILLER,17 ;21 FILLERS
FILLJP: ;POINTERS FOR LINEFEED
0 ;NO FILLERS
FILLP1: POINT 9,FILLRZ,17 ;1 FILLER
POINT 9,FILLRY,8 ;6 FILLERS
POINT 9,FILLRY,8 ;6 FILLERS
FLLCRP::POINT 9,FLLCR0 ;TABLE OF POINTERS FOR FREE CRLF'S
POINT 9,FLLCR1
POINT 9,FLLCR2
POINT 9,FLLCR2
FLLCR0: BYTE (9) 015,12,0 ;DATA FOR FREE CRLF'S
FLLCR1: BYTE (9) 015,015,12,177,0
FLLCR2: BYTE (9) 015,015,12,177,177,177,177,177,0
FLLUPA: POINT 9,FLLUP1 ;POINTER TO UPARROW
FLLDLR: POINT 9,FLLUP1,17 ;POINTER TO DOLLARSIGN
FLLUP1: BYTE (9) 136,0,44,0 ;UPARROW AND $
FLLBSP: POINT 9,FLLBS1 ;POINTER TO BACKSLASH
FLLBS1: BYTE (9) 134,0,134,FLLFLG ;BACKSLASH DATA
FLLBSC: POINT 9,FLLBS1,17 ;POINTER TO BACKSLASH - CRLF
FLLCRF: POINT 9,FLLBS1,26 ;POINTER FOR CRLF IN FILL STREAM
FLLCOP: 0 ;FILLERS FOR OUTPUT CR
POINT 9,FLLCO1,17 ;ONE EXTRA CR
POINT 9,FLLCO1
POINT 9,FLLCO1
FLLCO1: BYTE (9) 015,015,015,0 ;EXTRA CARRIAGE RETURNS
SUBTTL TIMING ROUTINE
;SUBROUTINE CALLED EVERY SECOND AT CLOCK LEVEL.
;CHECKS FOR IRMA. TIMES IMAGE INPUT. RUNS MODEMS.
SCNSEC::SE1ENT ;ENTER SECTION 1
MOVEI J,TCONLN## ;PREPARE TO SEARCH LINE TABLE
PUSHJ P,SAVE2##
IFN FTMP,<MOVE P2,.CPCPN##> ;CPU #
SETZM %SCNAL
SCNSIL: MOVE U,LINTAB##(J) ;GET ADR OF LDB
MOVE T1,LDBDCH(U) ;GET THE CHARACTERISTICS
IFN FTMP,< ;IF SMP, CHECK WHICH CPU WE'RE ON
LDB T2,LDPCPU ;GET # OF LINE'S OWNER
CAIN T2,PCLCP0## ;BOOT CPU?
MOVE T2,BOOTCP## ;YES, GET REAL BOOT CPU NUMBER
CAIE T2,(P2) ;ARE WE ON RIGHT CPU
JRST SCNSIS ;IF WRONG CPU, SKIP THIS LINE
>
TLNE T1,LDLIMI ;IMAGE INPUT STATE?
PUSHJ P,SCSIMG ;YES. GO TIME IT
MOVE T1,LDBDCH(U) ;SCSIMG CAN CLOBBER THIS
IFN FTKL10,<
HRRZ T2,LDBISR(U) ;GET ISR DISPATCH
CAIN T2,TTDDSP## ;RSX20F LINE?
PUSHJ P,TTDSIN## ;YES, DO HUNG CHECKING FOR -20F LINES
> ;END IFN FTKL10
JUMPL T1,SCNSIN ;IF IDLE?
AOS %SCNAL
TRNE T1,LDRSHC ;YES - HUNG CHECKING?
JRST SCNSIN ;NO
MOVSI T1,LPLIRM ;SET UP SYNC BIT
TDNE T1,LDBPAG(U) ;ON FROM 1 SECOND AGO?
JRST [PUSHJ P,TOREQ ;REQUEUE SO OUTPUT STARTS
MOVSI P1,L1LOFL
MOVEI T1,ISROFL
PUSHJ P,@LDBISR(U)
IORM P1,LDBOFL(U)
JRST SCNSIN] ;LOOK AT NEXT LINE
IORM T1,LDBPAG(U) ;TURN ON SYNC BIT FOR THIS SECOND
SCNSIN: MOVE T1,LDBTIC(U)
ADD T1,LDBECC(U)
SKIPE T1
AOS %SCNAL
SKIPL LDBOFL(U)
JRST SCNSIT
MOVSI P1,L1LOFL
MOVEI T1,ISROFL
PUSHJ P,@LDBISR(U)
SKIPA
ANDCAM P1,LDBOFL(U)
SCNSIT: PUSHJ P,TMRIDL ;IS THIS LINE IDLE?
JRST SCNSIR ;NO, RESET ADT AND LOOK AT NEXT LINE
AOS T1,LDBBY3(U) ;YES, BUMP THE COUNTER (COUNT-UP VALUE)
TRNN T1,L3RTMO ;DID IT TIME OUT?
JRST SCNSIS ;NO, JUST LOOP ON
MOVEI T3,IRRTMO ;YES, WANT TIMEOUT FUNCTION
MOVEI T1,ISRREM ;OF REMOTE HANDLER
PUSHJ P,@LDBISR(U) ;TRY TO FORCE THE DISCONNECT
JRST SCNSIR ;WE DECIDED TO RESET THE TIMER
SETZ T1, ;IT WORKED. GET A ZERO
PUSHJ P,SCNADT ;CLEAR THE TIMER SO WE DON'T KEEP TRYING
PUSHJ P,TTYOPR ;RESET DEVOPR IF NECESSARY
SCNSIS: SOJGE J,SCNSIL
IFN FTMP,<
SKPCPU (0) ;ONLY ON MASTER
PJRST @.CPISR##
>
SOSGE SNDCTR##
SETZM SNDCTR##
AOS T2,%SCNAL
CAIGE T2,20
MOVEI T2,20
MOVE T1,TTFREN##
IMULI T1,CK.CPC##
IDIV T1,T2
CAIGE T1,TTIBRK## ;AT LEAST TTIBRK MINIMUM LEVEL?
MOVEI T1,TTIBRK## ;NO, PEG IT AT TTIBRK LEVEL
MOVEM T1,TIWRNN ;STORE NEW LIMIT
;FALL THRU INTO DATASET ROUTINE
;ROUTINE TO DO ONCE-A-SECOND TIMING OF MODEMS. TIMES OUT INTERVALS
;FROM RING TO CARRIER ON, FROM CARRIER ON TO LEGAL COMMAND,
; AND FROM CARRIER OFF TO HANG UP.
;IF LINE IS IDLE (IDLE DEFINED AS NO ASSOCIATED DDB, AND NOT HOSTED AWAY)
;A DISCONNECT TIMER (IDLSEC) IS STARTED. WHEN IT TIMES OUT, THE DATASET
;IS HUNG UP
SKIPL J,DSCPTR## ;GET DATASET CONTROL POINTER
JRST DSCSC1 ;THERE ARE NONE IN THIS CONFIGURATION
HLLZS J ;CLEAR RIGHT HALF FOR INDEXING
DSCSLP: MOVE T1,DSCTAB##(J) ;GET TABLE ENTRY
TLNE T1,DSCBLI ;BLIND STILL ON?
JRST DSCSC3 ;YES.
TLNN T1,DSCHWC!DSCTMM;CARRIER OR TIMER SET?
JRST DSCSNY ;NO, SKIP SCN OFF
SCNOFF ;CAN'T ALLOW INTERRUPTS HERE
HRRZ U,T1 ;GET LINE NUMBER
MOVE U,LINTAB##(U) ;GET LDB ADDRESS
HLRZ T3,T1 ;GET CONTROL BITS
ANDI T3,DSCHWC!DSCSWC!DSCFAI!DSCNCR!DSCBLI ;MASK TO RELEVANT BITS
CAIE T3,DSCHWC!DSCSWC ;NORMAL SIGNAL STATE?
JRST DSCSL0 ;NO, DON'T CHECK FOR JOB (TIMER'S SIGNIFICANT)
HRRZ F,LDBDDB(U) ;GET DDB ADDRESS
SKIPN F ;IS THERE A DDB?
JRST DSCSL0 ;NO, CHECK TIMING
MOVE T1,DEVMOD(F) ;YES, GET MODE WORD
TRNE T1,ASSCON!ASSPRG ;THIS TTY ASSIGNED?
JRST [SETZM T3 ;YES, CLEAR TIMER,
DPB T3,DSTIMP ; STORE NEW VALUE,
SCNON ; ALLOW INTERRUPTS
JRST DSCSNY] ; AND DON'T TURN OFF DATASET
MOVE T1,DSCTAB##(J) ;NO, GET BACK TABLE ENTRY
LDB T3,DSTIMP ;GET TIMER WE'RE EXPIRING
JRST DSCSL1 ; AND CONTINUE TIMING
DSCSL0: LDB T3,DSTIMP ;GET THE TIME SINCE RING OR CARRIER FAILURE
JUMPN T3,DSCSL1 ;JUMP IF STILL TIMING
TLNN T1,DSCHWC ;SEE IF HARDWARE CARRIER
JRST DSCSL1 ;NO, KEEP GOING
IFN FTNET,<
SKIPL LDBREM(U) ;SKIP IF VTM SET HOSTED AWAY
>
MOVEI T3,M.DIDL## ;LINE IDLE, START DISCONNECT TIMER
DSCSL1: SOSL T3 ;COUNT IT DOWN. WAS IT 0?
DPB T3,DSTIMP ;NO. STORE NEW VALUE
JUMPN T3,[SCNON ;UNLESS NEWLY 0, ALLOW INTERRUPTS
JRST DSCSNY]; AND GO TO NEXT
MOVSI T3,DSCFAI+DSCSWC;CLEAR FAIL AND SOFTWARE BITS
ANDCAB T3,DSCTAB##(J) ; IN CORE
SCNON ;OK FOR INTERRUPTS NOW.
TLNE T3,DSCDLW ;IN DIALLER WAIT?
JRST DSCSDF ;YES. DIALLER HAS FAILED.
HRRZ U,T1 ;GET LINTAB INDEX
MOVE U,LINTAB##(U) ;GET THE LDB ADDRESS
; OF THE RELATED TERMINAL LINE
IFN FTNET,<
SKIPGE LDBREM(U) ;IF THIS IS A VTM LINE,
PUSHJ P,VTMDSF## ; SIGNAL CARRIER OFF TO THE REMOTE
>
PUSHJ P,LDBCLR ;CLEAR OUT LDB STATUS
MOVE F,LDBDDB(U) ;SEE IF THERE'S A JOB.
JUMPE F,DSCSC2 ;SKIP THIS IF NO JOB
MOVE T1,DEVMOD(F) ;MAY BE A JOB. GET MODE WORD.
TLNN T1,TTYATC ;CONTROLLING A JOB.
JRST DSCSC2 ;NOT A CONTROLLING TERMINAL. NO COMMAND
PUSHJ P,DSCDET ;DETACH THE GUY (.BYE)
DSCSC2: MOVEI T3,DSTOFF ;SOFTWARE CODE TO TURN OFF DATASET
MOVEI U,0(J) ;TABLE ADDRESS AS LINE NUMBER
PUSHJ P,DSCCAL ;SEND TO APPROPRIATE HARDWARE DEVICE
DSCSNY: AOBJN J,DSCSLP ;COUNT THROUGH ALL LINES
DSCSC1: PJRST @.CPISR## ;DO ISR TIMING
;STILL IN FTMODM
DSCSC3: MOVSI T3,DSCBLI ;SET FOR BLIND BIT
TLNE T1,DSCNCR ;NEW CARRIER BIT STILL ON?
MOVSI T3,DSCNCR ;YES. CLEAR IT INSTEAD
ANDCAM T3,DSCTAB##(J) ;CLEAR BIT IN TABLE
JRST DSCSNY ;AND GO ON TO NEXT MODEM
DSCSDF: SETOM TTYDDL## ;CLEAR DIALLER CODE INTERLOCK
MOVEI U,0(J) ;COPY TABLE INDEX
PUSHJ P,DSROF1 ;CLEAR OUT THE HARDWARE FOR THIS LINE.
MOVSI T1,DSCDLF ;FLAG THAT DIALLING LOST
IORB T1,DSCTAB##(J) ; ..
PUSHJ P,DSCWAK ;WAKE THE SLEEPING JOB, IF ANY
JRST DSCSNY ;LOOK FURTHER THRU DSCTAB
DSCWAK: HRRZS T1 ;TOSS JUNK
MOVE T1,LINTAB##(T1) ;GET THE LDB ADDRESS FOR THIS DATASET'S TERMINAL
MOVE F,LDBDDB(T1) ;GET THE DDB, IF ANY
SKIPE T1 ;ANY?
LDB T1,PJOBN## ;YES. GET JOB NUMBER
JUMPE T1,CPOPJ## ;ANY?
PJRST WAKJOB## ;YES. WAKE IT.
DSTIMP: POINT 9,DSCTAB##(J),17 ;POINTERS TO TIME BYTE
DSTMPL: POINT 9,DSCTAB##(U),17 ;SAME BUT DIFFERENT AC INDEX
;MUST AGREE WITH DSCTMM
;SUBROUTINE TO TIME THE IMAGE MODE INPUT STATE, SET END OF FILE IF
;IT TIMES OUT, AND FORCE CONTROL C UNLESS SLAVED ON SECOND TIME-OUT
SCSIMG: PUSH P,J ;SAVE COUNTER. WILL BE CLOBBERED.
LDB T3,LDPTIM ;GET THE IMAGE TIME BYTE
SOSL T3 ;COUNT IT DOWN. TOO LOW?
DPB T3,LDPTIM ;NO STORE NEW VALUE.
JUMPG T3,IPOPJ## ;IF NO TIMEOUT YET, GO BACK TO LOOP
MOVE F,LDBDDB(U) ;GET LINE'S JOB DATA BLOCK
JUMPE F,SCSIM2 ;NO JOB? TIME AGAIN
MOVSI S,FRCEND ;CAUSE UUO ROUTINE TO FORCE END
TDNE S,DEVIOS(F) ;ON YET?
JRST SCSIM1 ;ON ALREADY. PANIC.
IORB S,DEVIOS(F) ;NO. SET IT NOW AND TIME OUT AGAIN
SCSIM2: MOVEI T3,IMGTIM ;SET TIME TO NEXT PANIC
DPB T3,LDPTIM ;STORE IN TIME BYTE
PUSHJ P,RCVWAK ;AND WAKE UP JOB
JRST IPOPJ## ;GO RESTORE J AND RETURN
SCSIM1: MOVSI S,TTYATC ;GET A BIT
TDNE S,DEVMOD(F) ;IS THIS AN I/O DEVICE?
TLNE T1,LDLSLV ;IS THIS A SLAVE TERMINAL?
JRST SCSIM2 ;YES. CAN'T DO CONTROL C
PUSHJ P,CNCMOD ;NO. SET TO COMMAND LEVEL
MOVSI T1,LDBCMF ;FORCE COMMAND
DPB T1,LDPCMX ;CONTROL C INDEX
IORM T1,LDBCOM(U) ;AND FLAG COMMAND DECODER
PUSHJ P,COMSET ;WAKE UP COMMAND ROUTINE,
JRST IPOPJ## ;RESTORE AC AND RETURN
;ROUTINES TO HANDLE THE AUTO-DISCONNECT TIMER
SCNADT::SKIPL T1 ;IF TIMER IS OUT OF RANGE,
CAILE T1,377 ;IN EITHER DIRECTION,
MOVEI T1,377 ;JUST USE OUR MAXIMUM
DPB T1,LDPMXT ;STORE THE MAXIMUM IDLE TIME
SCNAD1: MOVNS T1 ;MAKE NEGATIVE FOR COUNT-UP LOGIN
ANDI T1,377 ;KEEP ONLY 8 BITS (9-BIT FIELD FOR OVERFLOW)
DPB T1,LDPTMR ;STORE FOR SCNSIT
POPJ P, ;RETURN TO CALLER
RSTTMR: LDB T1,LDPMXT ;GET ADT VALUE
JUMPN T1,SCNAD1 ;RE-SET COUNTER IF WE CARE
POPJ P, ;JUST RETURN IF WE DON'T
;HERE FROM SCNSIT WHEN WE WANT TO RESET THE TIMER
SCNSIR: PUSHJ P,RSTTMR ;RESET THE TIMER
JRST SCNSIS ;LOOP THROUGH LINTAB
;HERE FROM SCNSIT TO SEE IF WE WANT TO TIME THIS LINE
TMRIDL: LDB T1,LDPMXT ;GET THE ADT INITIAL VALUE
JUMPE T1,CPOPJ## ;IF NO TIMING, WE DON'T CARE
SCNOFF ;MUSN'T ALLOW OTHERS TO CONFUSE US
SKIPN F,LDBDDB(U) ;SEE IF WE HAVE A DDB
JRST TMRID1 ;SOME CHECKS DON'T APPLY IF NOT
MOVE T1,DEVMOD(F) ;YES, GET MODE BITS
TRNE T1,ASSCON!ASSPRG ;IS IT IN USE?
JRST SONPPJ ;YES, DON'T TIME IT OUT
TMRID1: MOVE T1,LDBDCH(U) ;GET CHARACTERISTICS WORD
IFN FTNET,<
SKIPL LDBREM(U) ;DON'T TIME IT IF IT'S HOSTED AWAY
.CREF LRLVTM ;NOTE BIT WE TESTED
>
TLNE T1,LDLSLV ;IS IT A SLAVE?
JRST SONPPJ ;YES, DON'T TIME IT OUT
SKIPGE LDBCOM(U) ;ANY COMMANDS PENDING?
JRST SONPPJ ;YES, IT'S NOT IDLE AFTER ALL
;ADD POSSIBLE FUTURE CHECKS HERE
JRST SONPJ1 ;NO SAVING ATTRIBUTES, TIME IT OUT
;OUTPUT SERVICE ROUTINE FOR CTY
IFN FTKS10,<
CTYSTO::MOVEI T1,.CPCTQ## ;POINT TO CTY OUTPUT QUEUE HEADER
PUSHJ P,TOTAKE ;GET A LINE NUMBER (CHECK QUEUE)
POPJ P, ;NONE WAITING
SKIPGE LDBDCH(U)
PUSHJ P,XMTCHR ;GET NEXT OUTPUT CHARACTER
POPJ P, ;LINE IS NOW IDLE
PUSHJ P,CLRIRM ;CLEAR IRMA BIT
CTYTYO: ANDI T3,377 ;REMOVE JUNK
MOVE T1,LINTAB##+KLILIN##
CAIN T1,(U) ;KLINIK LINE?
JRST KLITYO ;YES--GO TO IT
IORI T3,CTYOVL ;SET VALID FLAG
MOVEM T3,CTYOWD ;PUT IN OUTPUT WORD
CTYTY1: RDAPR T1 ;GET CPU PI LEVEL
ANDI T1,SP.PIA ; AND ONLY THE PI LEVEL
WRAPR SP.SSF+SP.IFE(T1) ;INTERRUPT THE 8080
POPJ P,0 ;AND RETURN
KLITYO: IORI T3,KLIOVL ;SET VALID BIT
MOVEM T3,KLIOWD ;PUT CHAR IN OUTPUT WORD
JRST CTYTY1 ;GO INTERRUPT 8080
>;END IFN FTKS10
;ROUTINE TO ADJUST HORIZONTAL POSITION COUNT FOR CHARACTER TO
;OUTPUT FROM BUFFER. CALL WITH T3, U SET UP.
ADJHP: PUSH P,T3 ;SAVE CHARACTER
ANDI T3,CK.CHR ;JUST CHARACTER BITS
CAIN T3,177 ;RUBOUT
JRST T3POPJ## ;DOESN'T SPACE
CAIL T3,40 ;NON-IMAGE CONTROL CHARACTER?
JRST ADJHP1 ;NO, SIZE IS ONE
PUSH P,T2
MOVE T2,-1(P) ;GET FULL CHARACTER AGAIN
TRNE T2,CK.MET ;WERE WE CALLED FOR A QUOTED CHARACTER?
JRST T23PPJ ;YES, IT'S NOT SIGNIFICANT TO US
CAIN T3,11 ;IS THIS A TAB?
JRST ADJHP2 ;YES, GO FIGURE OUT HOW BIG IT IS
CAIN T3,15 ;CARRIAGE RETURN?
JRST ADJHP3 ;SETS HPOS BACK TO START
CAIE T3,10 ;BACKSPACE?
JRST T23PPJ ;NO, OTHER DON'T CHANGE HPOS
PUSHJ P,HPOS ;GET CURRENT POSITION
JUMPE T2,T23PPJ ;IF AT START OF LINE
SOS LDBHPS(U) ;ELSE DECREMENT POSITION BY ONE
JRST T23PPJ ;AND RETURN
;HERE FOR CARRIAGE RETURN
ADJHP3: PUSHJ P,SCNBOL ;BACK TO START OF LINE
JRST T23PPJ ;AND RETURN
;HERE FOR TAB
ADJHP2: PUSHJ P,HPOS ;CURRENT HORIZONTAL POSITION
DPB T2,POHPOS ;SAVE LOW 3 BITS FOR SIMULATION
ANDI T2,7 ;ISOLATE (POSITION MOD 8)
MOVN T2,T2 ; -(POSITION MOD 8)
ADDI T2,10 ; 8-(POSITION MOD 8)
ADDM T2,LDBHPS(U) ;FIX HPOS COUNTER
JRST T23PPJ ;AND RETURN
;HERE FOR PRINTING CHARACTER
ADJHP1: AOSA LDBHPS(U) ;INCREMENT POSITION
T23PPJ: POP P,T2
JRST T3POPJ##
;HPOS -- SUBROUTINE TO FETCH THE CURRENT HORIZONTAL POSITION ON A LINE
;CALL
; PUSHJ P,HPOS
; <ALWAYS RETURN HERE>
;EXIT WITH T2 = HORIZONTAL POSITION. PRESERVES ALL OTHERS AC'S.
HPOS:: SE1ENT ;ENTER SECTION 1
LDB T2,LDPWID ;GET CARRIAGE WIDTH
ADD T2,LDBHPS(U) ;COMPUTE HORIZONTAL POSITION
POPJ P, ;AND RETURN IT
;ROUTINE TO SET A LINE BACK TO THE BEGINNING
SCNBOL: PUSH P,T2 ;SAVE ALL AC'S
LDB T2,LDPWID ;GET WIDTH
MOVNM T2,LDBHPS(U) ;INITIAL VALUE OF HORIZONTAL POS COUNTER
MOVEI T2,0
DPB T2,POHPOS ;INITIAL LOW ORDER 3 BIT COUNTER
JRST T2POPJ## ;RESTORE T2 AND RETURN
;ROUTINE TO CLEAR PROMPT POS FOR THIS LINE
CPRPOS: PUSH P,T2 ;SAVE ALL AC'S
MOVSI T2,LDLPPS ;PROMPT POS SET BIT
ANDCAM T2,LDBDCH(U) ;CLEAR IT
JRST T2POPJ## ;RESTORE T2 AND RETURN
;ROUTINE TO SUPPRESS BLANK LINES
BLSUPI: PUSHJ P,HPOS ;GET HORIZONTAL POSITION
HRLI T2,LPLSLF ; (LPLSLF BIT IN LH)
TRZE T2,-1 ;ANYTHING ON THIS LINE?
ANDCAM T2,LDBPAG(U) ;YES - CLEAR BIT TO ALLOW L.F.
PUSH P,T3 ;SAVE CHARACTER
ANDI T3,CK.CHR ;REDUCE TO ASCII
CAIL T3,12 ;IS CHARACTER LF, VT, OR FF?
CAILE T3,14 ; . . .
JRST T3POPJ## ;NO
IORM T2,LDBPAG(U) ;SET BIT TO SUPPRESS LF'S
JRST T3POPJ## ;BUT ALWAYS ECHO INPUT <CR><LF>S
BLSUPO: PUSHJ P,HPOS ;GET HORIZONTAL POSITION
HRLI T2,LPLSLF ; (LPLSLF BIT IN LH)
TRZE T2,-1 ;ANYTHING ON THIS LINE?
ANDCAM T2,LDBPAG(U) ;YES - CLEAR BIT TO ALLOW L.F.
PUSH P,T3 ;SAVE CHARACTER
ANDI T3,CK.CHR ;REDUCE TO ASCII
CAIL T3,12 ;IS CHARACTER LF, VT, OR FF?
CAILE T3,14 ; . . .
JRST [CAIN T3,15 ;IS IT A CR
TDNN T2,LDBPAG(U) ;YES, ARE WE SUPPRESSING LF'S
JRST T3POPJ## ;NO, JUST RETURN
JRST BLSUP1] ;YES, SUPPRESS CR'S TOO
CAIN T3,12 ;YES-SUPPRESS LF?
TDNN T2,LDBPAG(U)
SKIPA T3,[12] ;NO-TURN VT OR FF INTO LF
BLSUP1: MOVEI T3,0 ;YES-TURN LF INTO NULL
IORM T2,LDBPAG(U) ;SET BIT TO SUPPRESS LF'S
MOVE T1,CHTABL(T3) ;GET BITS FOR NEW CHARACTER
PJRST T2POPJ## ;DISCARD OLDE CHARACTER, RETURN
;SUBROUTINE TO WAKE UP JOB IF IT IS IN TERMINAL INPUT WAIT. CALL WITH
;LINE SET UP. IT WILL SET DDB AND S AS NEEDED.
RCVWAK: MOVE F,LDBDDB(U) ;GET ADDRESS OF ATTACHED DDB
JUMPE F,CPOPJ## ;IF NONE,SKIP THIS CODE
PUSH P,T1 ;SAVE T1
LDB T1,PJOBN## ;GET JOB NUMBER OF TERMINAL OWNER
MOVSI S,TTILCE## ;IS JOB ENABLED FOR WAKE UP
TDNE S,JBTRTD##(T1) ;DURING A HIBERNATE
JRST WAKJB ;YES, GO WAKE JOB
WAKJBR: POP P,T1 ;RESTORE T1
MOVE S,DEVIOS(F) ;GET STATUS OF TERMINAL FROM DDB
TLZ S,IO ;MAKE SURE BIT IS RIGHT
TLNE S,IOW ;JOB IN I/O WAIT FOR TERMINAL?
TLNE S,TTYOUW ;YES. FOR INPUT WAIT?
JRST PSIIOD## ;GENERATE PSI SO USER WILL KNOW I/O IS DONE
TTWAKE::SE1ENT ;ENTER SECTION 1
PUSH P,T1 ;SAVE VOLATILE AC'S
PUSH P,T2 ; ..
LDB T1,PJOBN## ;IS JOB # IN DDB ZERO?
JUMPE T1,TTWAKX ;EXIT IF ZERO
MOVE S,DEVIOS(F) ;MAKE SURE S IS CORRECT
IFN FTPSCD,<
MOVE T1,LDBDCH(U) ;LINE CHARACTERISTICS
JUMPL S,TTWAKO ;OUTPUT?
TRNE T1,LDRPTY ;INPUT. PTY?
AOSA %PISJB## ;YES
AOS %TISJB## ;NO
JRST TTWAKB
TTWAKO: TRNE T1,LDRPTY ;OUTPUT. PTY?
AOSA %POSJB## ;YES
AOS %TOSJB## ;NO
TTWAKB:>
MOVEI S,IOACT ;CLEAR I/O ACTIVE
ANDCAB S,DEVIOS(F) ;IN DDB FOR THIS JOB
PUSHJ P,STTIOD## ;CALL STTIOD FOR TERMINALS, PTYS
TTWAKX: POP P,T2 ;RESTORE AC'S
PJRST TPOPJ## ;RETURN FROM RCVWAK
;ROUTINE TO SEE IF CHARACTER SPECIAL HANDLING SHOULD BE SUPPRESSED
;PRESERVES T1
FULLCQ: PUSHJ P,COMQ ;IS LINE AT COMMAND LEVEL?
TLNN T2,LDLBKA+LDLFCS ; NO. DOES USER WANT ALL CHACTERS?
AOS (P) ;NO. COMMAND OR NOT SMART USER
POPJ P, ;SMART USER. NON-SKIP RETURN.
WAKJB: PUSH P,T2 ;SAVE AC'S
PUSH P,T3
MOVSI T2,(JS.HIB) ;IS JOB SLEEPING
TDNE T2,JBTST2##(T1) ;OR HIBERNATING?
PUSHJ P,WAKJOB## ;HIBERNATING: WAKE THE JOB
POP P,T3 ;RESTORE THE AC'S
POP P,T2
JRST WAKJBR ;RETURN TO NORMAL PROGRAM FLOW
;THE FOLLOWING ROUTINE IS CALLED BY THE HIBERNATE UUO TO
;PUT THE TERMINAL INTO CHARACTER MODE. T1 IS PRESERVED.
HIBTTY::SE1ENT ;ENTER SECTION 1
PUSH P,T1 ;SAVE T1
PUSHJ P,TTYFND ;FIND THIS JOB'S TTY
JUMPE U,TPOPJ## ;NO TERMINAL FOR THIS JOB
MOVSI T1,TTIACE## ;HIBERNATE IN CHARACTER MODE?
TDNN T1,JBTRTD##(J)
JRST HIBTTL ;NO, IT MUST BE LINE MODE
PUSHJ P,TTCCHK ;CHECK IF A CHARACTER IS ALREADY PRESENT
JRST TPOPJ## ;NO LINE, ECHO STARTED
HIBSET: MOVSI T1,WAKEB## ;LINE OR CHARACTER PRESENT
IORM T1,JBTRTD##(J) ;DON'T HIBERNATE
PJRST TPOPJ## ;RESTORE T1 AND RETURN (TO UUOCON)
HIBTTL: PUSHJ P,TTLCHK ;CHECK FOR A LINE PRESENT
JRST TPOPJ## ;NO LINE, ECHO STARTED
JRST HIBSET ;YES, DON'T GO TO SLEEP
SUBTTL CHTRN. UUO
;CALL: XMOVEI AC,LOCN
; -OR-
; MOVE AC,[IFIW LOCN]
;
; CALLI AC,223
; <ERROR>
; <SUCCESS>
;
;LOCN: XWD FLAGS,SOURCE-COUNT
; SOURCE BYTE POINTER WORD 1
; SOURCE BYTE POINTER WORD 2
; XWD MBZ,DEST-COUNT
; DEST BYTE POINTER WORD 1
; DEST BYTE POINTER WORD 2
;THE BITS THAT CAN BE IN LH(SOURCE-COUNT-WORD)
CH.FBR==(1B0) ;FALLBACK REPRESENTATION (8-TO-7-BIT)
CH.OVR==(1B1) ;OVERSTRIKING ALLOWED
CH.RAI==(1B2) ;FOLD LOWER CASE TO UPPER
CH.6BT==(1B3) ;CONVERT ASCII TO SIXBIT
CH.IGN==(1B4) ;IGNORE EXCESS BITS
CH.ESC==(1B5) ;MAP 7-BIT ESCAPE SEQUENCES TO 8-BIT
CH.X6B==(1B6) ;EXPAND FROM SIXBIT TO ASCII
CH.INV==<(1B6)>-1 ;UNKNOWN BITS
;THE ERRORS THAT CAN OCCUR
CHADC%==1 ;ILLEGAL ADDRESS ENCOUNTERED
CHBYP%==2 ;INVALID BYTE POINTER SUPPLIED
CHINV%==3 ;UNKNOWN OR RESERVED FLAG BIT SPECIFIED
CHILC%==4 ;ILLEGAL CHARACTER ENCOUNTERED DURING TRANSLATION
CHDCE%==5 ;DESTINATION COUNT EXHAUSTED
CHIBC%==6 ;INVALID BIT COMBINATION SPECIFIED
ERCODX CHTADC,CHADC%
ERCODX CHTIBP,CHBYP%
ERCODX CHTILB,CHINV%
ERCODX CHTILC,CHILC%
ERCODX CHTDCE,CHDCE%
ERCODX CHTIBC,CHIBC%
UCHTRN::PUSHJ P,SAVUM## ;PRESERVE SOME ACS THAT WE USE
PUSHJ P,SAVE4## ;AND SOME MORE
PUSHJ P,SAVR## ;AND ANOTHER
IFN FTXMON,<
PUSHJ P,SSPCS## ;PRESERVE PCS (IN CASE WE CHANGE IT)
>
MOVEI T2,6 ;OUR ARG BLOCK IS SIX WORDS LONG
PUSHJ P,ARNGE## ;VALIDATE THE ARG BLOCK
TRN ;INVALID ADDRESS AND ILLEGAL FOR I/O EQUALLY BAD
JRST CHTADC ;ADDRESS CHECK ERROR FOR THESE
PUSHJ P,SXPCS## ;SET UP FOR READING ARGUMENTS
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE M,T1 ;MOVE POINTER FOR GETEWD/GETEW1
PUSHJ P,GETEWD## ;GET THE FLAGS & SOURCE COUNT WORD
JRST CHTADC ;ADDRESS CHECK ERROR
TLNE T1,CH.INV ;ARE ANY UNKNOWN BITS SET?
JRST CHTILB ;ILLEGAL BITS ERROR
TLC T1,CH.6BT!CH.X6B ;CHECK SIXBIT BITS
TLCN T1,CH.6BT!CH.X6B ;WERE BOTH ON?
JRST CHTIBC ;YES--ILLEGAL BIT COMBINATION
TLNE T1,CH.6BT ;IF DEALING WITH SIXBIT,
TLNN T1,CH.ESC ;IT'S AN ERROR TO TRY TO COMPRESS ESCAPE
TRNA ;NOT TRYING
JRST CHTIBC ;YES--ILLEGAL BIT COMBINATION
TLNE T1,CH.6BT ;GOING TO SIXBIT?
TLO T1,CH.FBR!CH.RAI;YES, TRY TO FORCE IT TO BE IN RANGE
TLNE T1,CH.6BT ;STILL GOING TO SIXBIT?
TLZ T1,CH.OVR ;YES, EXCLUDE BACKSPACE
TLNE T1,CH.X6B ;EXPANDING FROM SIXBIT?
TLZ T1,CH.ESC ;YES, NOT COMPRESSING ESCAPES IF NO ESCAPE
MOVE U,T1 ;SAVE BITS & COUNT
PUSHJ P,GETEW1## ;GET FIRST HALF OF SOURCE BYTE POINTER
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE P1,T1 ;SAVE IT
PUSHJ P,GETEW1## ;SET SECOND HALF
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE P2,T1 ;SAVE IT
PUSHJ P,GETEW1## ;GET DESTINATION COUNT WORD
JRST CHTADC ;ADDRESS CHECK ERROR
TLNE T1,-1 ;ANYTHING IN THE RESERVED FIELD?
JRST CHTILB ;ILLEGAL BITS ERROR
MOVE R,T1 ;SAVE DEST COUNT
;HERE WHEN BITS CHECK OUT--GET BYTE POINTERS
PUSHJ P,GETEW1## ;GET FIRST HALF OF DESTINATION BYTE POINTER
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE P3,T1 ;SAVE IT
PUSHJ P,GETEW1## ;GET SECOND HALF
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE P4,T1 ;SAVE IT
LDB T1,[POINT 6,P1,5] ;GET P/P&S FIELD OF SOURCE B.P.
CAIL T1,77 ;WITHIN RANGE OF VALID P FIELDS?
JRST CHTIBP ;ILLEGAL BYTE POINTER ERROR
CAIG T1,44 ;IS IT A OWGBP?
LDB T1,[POINT 6,P1,11] ;NO, GET S FIELD
SKIPN T1 ;DON'T BOTHER ME WITH NO-OPS
JRST CHTIBP ;BE NASTY ABOUT IT
DMOVE T1,P1 ;COPY SOURCE B.P.
HRRZ T3,U ;AND SOURCE COUNT
SUBI M,3 ;UPDATE CORRECT WORD
PUSHJ P,QRNGE## ;RANGE CHECK THE ADDRESSES
JRST CHTADC ;ADDRESS CHECK ERROR
TRN ;DON'T CARE IF CAN'T WRITE THIS ONE
DMOVE P1,T1 ;GET MASSAGED B.P.
ADDI M,3 ;POINT BACK TO THE END OF THE BLOCK
LDB T1,[POINT 6,P3,5] ;GET P/P&S FIELD OF DEST B.P.
CAIL T1,77 ;WITHIN RANGE OF VALID P FIELDS?
JRST CHTIBP ;ILLEGAL BYTE POINTER ERROR
CAIG T1,44 ;IS IT A OWGBP?
LDB T1,[POINT 6,P3,11] ;NO, GET S FIELD
CAIGE T1,6 ;IS IT OF A MINIMUM REASONABLE SIZE?
JRST CHTIBP ;COMPLAIN IF NOT
DMOVE T1,P3 ;COPY DEST B.P.
HRRZ T3,R ;AND DEST COUNT
PUSHJ P,QRNGE## ;RANGE CHECK
TRN ;INVALID PAGE(S) OR ILLEGAL FOR I/O ARE BOTH BAD
JRST CHTADC ;SO GIVE ADDRESS CHECK ERROR FOR THESE
DMOVE P3,T1 ;COPY MASSAGED B.P.
TLNE U,CH.IGN ;IF WE DON'T CARE ABOUT EXTRA BITS,
JRST CHTRNQ ;DON'T CHECK BYTE SIZES
LDB T1,[POINT 6,P1,11] ;GET SOURCE BYTE SIZE
LDB T2,[POINT 6,P3,11] ;GET DEST. BYTE SIZE
CAIL T2,8 ;ALL CHARACTERS FIT INTO EIGHT BITS,
JRST CHTRNQ ;SO DON'T CHECK
TLNE U,CH.ESC ;IF COMPRESSING ESCAPES,
JRST CHTIBP ;WE NEED EIGHT BITS
CAIL T2,7 ;IF WE HAVE SEVEN,
JRST CHTRNQ ;JUST TRY IT
TLNN U,CH.6BT ;UNLESS GOING TO SIXBIT,
JRST CHTIBP ;WE NEED MORE THAN 6-BIT BYTES
CHTRNQ: PUSHJ P,CHTRNP ;PRE-FETCH THE SOURCE AND DEST WORDS
POPJ P, ;PROPAGATE ERROR
;HERE WHEN THE ARG LISTS SEEM TO CHECK OUT. TIME TO START TRANSLATING.
;TRANSLATION LOOP
CHTRN1: PUSHJ P,CHTRNR ;READ NEXT SOURCE BYTE
JRST CHTRNE ;ERROR ALREADY STORED--UPDATE BLOCK
TLNE U,CH.X6B ;EXPANDING SIXBIT?
JRST [TLNE U,CH.IGN ;YES, IGNORING EXTRA BITS?
ANDI T1,77 ;YES, DO SO
CAIL T1,0 ;IN RANGE?
CAILE T1,77 ;EITHER WAY?
JRST CHTIVC ;NO--ILLEGAL CHARACTER
ADDI T1,40 ;YES, MAKE ASCII
JRST CHTRN2] ;AND GO STORE
CHTRN6: TLNE U,CH.IGN ;IGNORE EXTRA BITS?
ANDI T1,CK.CHR ;YES, DO SO
CAIN T1,33 ;IF THIS IS ESCAPE,
TLNN U,CH.ESC ;AND WE CARE
JRST CHTRN4 ; (NO TO EITHER)
TRNN U,-1 ;IF NO MORE TO READ,
JRST CHTRN4 ;CAN'T COMPRESS
PUSHJ P,CHTRNR ;GET NEXT CHARACTER
JRST CHTRNE ;PROPAGATE ERRORS
CAIL T1,100 ;IS IT IN RANGE
CAILE T1,137 ;OF COMPRESSIBLE ESCAPES?
JRST CHTRN5 ;NO, MUST DO THIS THE HARD WAY
TRC T1,300 ;YES, FUDGE IT
JRST CHTRN4 ;AND GO STORE IT
CHTRN5: PUSH P,T1 ;SAVE NEW CHARACTER
MOVEI T1,33 ;GET THE ESCAPE
PUSHJ P,CHTRNW ;WRITE IT OUT
JRST [POP P,T1 ;BALANCE STACK
JRST CHTRNE] ;ERROR RETURN
POP P,T1 ;RETRIEVE NEW CHARACTER
JRST CHTRN6 ;AND GO STORE IT
CHTRN4: TLNE U,CH.IGN ;IGNORE EXTRA BITS?
ANDI T1,CK.CHR ;YES, DO SO
CAIL T1,0 ;IS THIS A VALID CHARACTER?
CAILE T1,CK.CHR ;EITHER WAY?
JRST CHTIVC ;INVALID CHARACTER ERROR
MOVE T2,CHTABL(T1) ;GET BITS
TLNE T2,CHINVL ;IS THIS A RESERVED CHARACTER CODE?
JRST CHTIVC ;YES, GIVE INVALID CHARACTER ERROR
TLNE U,CH.RAI ;RAISE LETTERS?
TLNE T2,CHPUNC ;AND IS THIS ONE?
JRST CHTRN8 ;NO OR NO, DON'T
TRNE T1,100 ;ONLY IF ALPHA, AND NOT NUMERIC,
TRZ T1,40 ;YES, FORCE UPPER CASE
CHTRN8: CAILE T1,CK.CH7 ;IS THIS AN 8-BIT CHARACTER AND
TLNN U,CH.FBR ;ARE WE COMPRESSING TO 7-BIT?
JRST CHTRN2 ;NO, DON'T BOTHER
MOVE T1,CHREQV-200(T1) ;YES, GET EQUIVALENCE STRING
TLNN T2,CH2PC ;IS IT MULTI-CHARACTER?
JRST CHTRN2 ;NO, DON'T CHECK FOR BACKSPACE
TLNN U,CH.OVR ;ARE WE ALLOWING OVERPRINTING?
TRNE T1,767000 ;NO, DOES THIS STRING CONTAIN BACKSPACE?
JRST CHTRN2 ;YES OR NO, PASS IT
HLRZS T1 ;NO AND YES, KEEP ONLY THE LAST CHARACTER
; PJRST CHTRN2 ;FALL INTO WRITE LOOP, NEXT PAGE
;HERE TO LOOP OVER TRANSLATION STRING, STORING IN DEST. STRING BLOCK
CHTRN2: MOVE T2,T1 ;COPY STRING
ANDI T2,CK.CHR ;KEEP ONLY CURRENT CHARACTER
HLL T2,CHTABL(T2) ;GET BITS FOR CHARACTER
TLNE U,CH.RAI ;IF UPCASING,
TLNE T2,CHPUNC ;AND THIS IS ALPHANUMERIC
JRST CHTRN7 ;(NO OR NO)
TRNE T2,100 ;ONLY IF ALPHA,
TRZ T2,40 ;YES, ENFORCE UPPER CASE
CHTRN7: ANDI T2,CK.CHR ;MASK DOWN TO CHARACTER AGAIN
TLNN U,CH.6BT ;CONVERTING TO SIXBIT?
JRST CHTRN3 ;NO, DON'T RANGE CHECK
CAIL T2,40 ;YES, IS THIS IN RANGE?
CAILE T2,137 ;EITHER WAY?
JRST CHTIVC ;NO, GIVE INVALID CHARACTER RETURN
SUBI T2,40 ;YES, MAKE IT SIXBIT
CHTRN3: PUSHJ P,CHTRNW ;WRITE CURRENT BYTE
JRST CHTRNE ;ERROR RETURN ALREADY STORED--UPDATE BLOCK
LSH T1,-9 ;GET TO NEXT CHARACTER OF STRING
JUMPN T1,CHTRN2 ;LOOP OVER ENTIRE TRANSLATION STRING
TRNE U,-1 ;DONE WITH THIS INPUT BYTE,
JRST CHTRN1 ;LOOP OVER ALL SOURCE BYTES
; PJRST CHTRNS ;FALL INTO ARG BLOCK UPDATE ROUTINE
;HERE TO STORE UPDATED BYTE POINTERS FOR THE USER
CHTRNS: SUBI M,5 ;BACK UP TO START OF ARG BLOCK
MOVE T1,U ;FLAGS AND SOURCE COUNT
PUSHJ P,PUTEWD## ;STUFF FOR USER
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T1,P1 ;SOURCE B.P. WORD 1
TLNE T1,(1B12) ;GLOBAL B.P.?
TRZA T1,-1 ;YES, CLEAR OUR JUNK
HRR T1,P2 ;NO, FORM LOCAL B.P.
PUSHJ P,PUTEW1## ;STUFF FOR USER
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T1,P2 ;SOURCE B.P. WORD 2
PUSHJ P,PUTEW1## ;STUFF INTO BLOCK
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T1,R ;DEST. COUNT
PUSHJ P,PUTEW1## ;STUFF INTO BLOCK
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T1,P3 ;DEST. B.P. WORD 1
TLNE T1,(1B12) ;GLOBAL B.P.?
TRZA T1,-1 ;YES, CLEAR OUR JUNK
HRR T1,P4 ;NO, FORM LOCAL B.P.
PUSHJ P,PUTEW1## ;PUT BACK FOR USER
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T1,P4 ;DEST. B.P. WORD 2
PUSHJ P,PUTEW1## ;WRITE TO ARG BLOCK
JRST CHTADC ;ADDRESS CHECK ERROR
PUSHJ P,CHTRW2 ;ATTEMPT TO FINISH STORING THE DEST. STRING
POPJ P, ;PROPAGATE ERROR (ALREADY STORED)
JRST CPOPJ1## ;RETURN SUCCESS TO USER
;HERE TO READ NEXT BYTE FROM USER'S ARG LIST
CHTRNR: HRRI U,-1(U) ;DECREMENT SOURCE COUNT
HLLZS P1 ;CLEAR OLD JUNK FROM BYTE POINTER
IBP P1 ;BUMP IT
TRNN P1,-1 ;DID IT FLOW INTO NEXT WORD?
JRST CHTRR1 ;NO, DON'T NEED TO FETCH
PUSHJ P,SAVUM## ;PRESERVE M
IFN FTXMON,<
PUSHJ P,SSPCS## ;AND PCS
>
AOS M,P2 ;GOING TO FETCH FROM NEXT ADDRESS
IFN FTXMON,<
PUSHJ P,SMPCS## ;SETUP FOR RETRIEVAL
JRST CHTADC ;ERROR IF CAN'T
>
PUSHJ P,GETEWD## ;FETCH FROM ARBITRARY SECTION
JRST CHTADC ;ADDRESS CHECK ERROR RETURN
MOVE T4,T1 ;PUT SOURCE WORD WHERE WE WANT IT
PUSHJ P,SCDCHK## ;AVOID KAF
CHTRR1: HRRI P1,T4 ;POINT OUR B.P. TO OUR SOURCE WORD
LDB T1,P1 ;FETCH NEXT (CURRENT) BYTE
JRST CPOPJ1## ;RETURN TO CALLER
;HERE TO WRITE NEXT BYTE TO USER'S DEST. STRING
CHTRNW: TRNN R,-1 ;IS THERE ENOUGH ROOM TO STORE?
JRST CHTDCE ;NO, GIVE APPROPRIATE ERROR
HRRI R,-1(R) ;YES, DECREMENT DEST. COUNT
HLLZS P3 ;CLEAR B.P. JUNK FROM LAST TIME
IBP P3 ;BUMP DEST. POINTER
TRNN P3,-1 ;DID WE ADVANCE TO NEXT WORD?
JRST CHTRW1 ;NO, DON'T DEAL WITH WORD
PUSHJ P,SAVUM## ;PRESERVE M
IFN FTXMON,<
PUSHJ P,SSPCS## ;PRESERVE PCS
>
MOVE M,P4 ;FOR STORING
IFN FTXMON,<
PUSHJ P,SMPCS## ;SETUP PCS
JRST CHTADC ;GIVE UP IF CAN'T
>
EXCH T3,T1 ;SETUP SOME ACS
PUSHJ P,PUTEWD## ;STORE THE WORD
JRST [EXCH T1,T3 ;RESTORE ACS
JRST CHTADC] ;ADDRESS CHECK ERROR
PUSHJ P,GETEW1## ;READ THE NEXT WORD WE'LL USE
JRST [EXCH T1,T3 ;RESTORE ACS
JRST CHTADC] ;ADDRESS CHECK ERROR
EXCH T3,T1 ;RESTORE OUR ACS
MOVE P4,M ;SAVE UPDATED DEST. POINTER
CHTRW1: HRRI P3,T3 ;POINT OUR B.P. TO OUR DEST. WORD
DPB T2,P3 ;STORE CURRENT BYTE
JRST CPOPJ1## ;RETURN TO CALLER
;HERE TO STORE THE ILLEGAL CHARACTER ERROR AND UPDATE THE BLOCK
CHTIVC: PUSHJ P,[PUSHJ P,SAVUM## ;PRESERVE M
PJRST CHTILC] ;STORE ILLEGAL CHARACTER ERROR CODE
;PJRST CHTRNE ;UPDATE THE BLOCK AND GIVE AN ERROR RETURN
;HERE TO UPDATE THE ARG BLOCK ON AN ERROR RETURN
CHTRNE: PUSHJ P,CHTRNS ;STORE THE UPDATED ARGS IN THE BLOCK
POPJ P, ;RETURN NON-SKIP
POPJ P, ;EVEN IF UPDATE SUCCEEDS
;HERE TO STORE CURRENT DEST. WORD FOR CHTRNS
CHTRW2: PUSHJ P,SAVUM## ;PRESERVE M
IFN FTXMON,<
PUSHJ P,SSPCS## ;AND PCS
MOVE T1,P4 ;GET DEST. WORD
PUSHJ P,SXPCS## ;TRY TO GET THERE
JRST CHTADC ;ADDRESS CHECK IF CAN'T
>
MOVE M,P4 ;GET DEST WORD POINTER
MOVE T1,T3 ;AND DEST. WORD
PUSHJ P,PUTEWD## ;TRY TO STORE
JRST CHTADC ;ADDRESS CHECK ERROR
JRST CPOPJ1## ;SUCCESS RETURN TO CHTRNS
;HERE WHEN THE ARGUMENTS LOOK GOOD. PRE-FETCH THE SOURCE AND DEST WORDS.
CHTRNP: PUSHJ P,SAVUM## ;PRESERVE M
IFN FTXMON,<
PUSHJ P,SSPCS## ;AND PCS
>
MOVE M,P2 ;GET ADDRESS OF SOURCE WORD
PUSHJ P,SMPCS## ;SET FOR FETCHING
JRST CHTADC ;ADDRESS CHECK ERROR
PUSHJ P,GETEWD## ;FETCH IT
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T4,T1 ;PUT IT IN OUR SOURCE WORD
MOVE M,P4 ;GET ADDRESS OF DEST. WORD
PUSHJ P,SMPCS## ;SET FOR FETCHING
JRST CHTADC ;ADDRESS CHECK ERROR
PUSHJ P,GETEWD## ;FETCH IT
JRST CHTADC ;ADDRESS CHECK ERROR
MOVE T3,T1 ;SAVE IN OUR DEST. TEMP WORD
JRST CPOPJ1## ;RETURN SUCCESS
;TABLE OF CONTROL AND META CHARACTERS - LH=BITS, RH=DISP ADDR ON RCV INT
;DEFINITION OF BITS IN THESE TABLES
CHBRK==:1 ;THIS IS A BREAK CHARACTER
CHUAE==:2 ;THIS CHARACTER ECHOES AS ^X
CHFIL==4 ;THIS CHARACTER REQUIRES FILLERS AT SOME SPEEDS
CHALT==:10 ;THIS CHARACTER IS ONE OF THE THREE ALTMODES.
CHRIA==:20 ;THIS CHARACTER REQUIRES RCV INT LEVEL ACTION
CHCRET==40 ;THIS IS A CARRIAGE RETURN (NEEDED FOR SETFLO)
CHCNC==100 ;THIS IS CONTROL C
CHINVL==:200 ;THIS CHARACTER IS INVALID (RESERVED 8-BIT GRAPHIC)
CHFILO==400 ;BIT ADDED FOR OUTPUT FILLER ROUTINE (NOT IN TABLE)
CHCRE==:1000 ;THIS CHARACTER GETS CRLF AFTER ITS ^ X ECHO
CHVPOS==2000 ;VERT. POSITIONING SIMULATED WITH FORM FEEDS
CHEPAR==:4000 ;THIS BIT SET IF CHARACTER IS EVEN PARITY
CH2PC==10000 ;THIS IS A 2-PART CHARACTER (META AND 8-BIT ONLY) (ALSO 3-PART)
CHPUNC==20000 ;THIS IS A PUNCTUATION CHARACTER
CHNDFR==:40000 ;THIS CHARACTER CANNOT BE DEFERRED (EVEN IF IN DEFERRED ECHO)
CHDEL==100000 ;THIS IS DELETE (RUBOUT)
CHOOB==:200000 ;OUT-OF-BAND CHARACTER (NOT IN TABLE)
CHSPO==400000 ;REQUIRES SPECIAL CHECKING ON OUTPUT. MUST BE THE
;SIGN BIT.
CHTABL: XWD CHSPO+CHRIA+CHEPAR+CHPUNC,CPOPJ## ;^@ NUL 000
IFN FTMIC,<
XWD CHSPO+CHRIA+CHUAE+CHPUNC+CHNDFR,RICA ;^A SOH 001
>
IFE FTMIC,<
XWD CHSPO+CHUAE+CHPUNC,0 ;^A SOH 001
>
IFN FTMIC,<
XWD CHSPO+CHRIA+CHUAE+CHPUNC+CHNDFR,RICB ;^B STX 002
>
IFE FTMIC,<
XWD CHSPO+CHUAE+CHPUNC,0 ;^B STX 002
>
XWD CHSPO+CHUAE+CHBRK+CHRIA+CHCRE+CHCNC+CHEPAR+CHPUNC+CHNDFR,RICC ;^C ETX 003
XWD CHSPO+CHUAE!CHRIA+CHPUNC+CHNDFR,RICD ;^D EOT 004
XWD CHSPO+CHUAE+CHEPAR+CHPUNC,0 ;^E ENQ 005
XWD CHSPO+CHUAE+CHRIA+CHEPAR+CHPUNC,RICF ;^F ACK 006
XWD CHSPO+CHBRK+CHPUNC,0 ;^G BEL 007
XWD CHSPO+CHBRK+CHRIA+CHPUNC,RIBSP ;^H BS 010
XWD CHSPO+CHFIL+CHEPAR+CHPUNC,0 ;^I HT 011
XWD CHSPO+CHFIL+CHBRK+CHEPAR+CHPUNC,0 ;^J LF 012
XWD CHSPO+CHFIL+CHBRK+CHVPOS+CHPUNC,0 ;^K VT 013
XWD CHSPO+CHFIL+CHBRK+CHVPOS+CHEPAR+CHPUNC,0 ;^L FF 014
XWD CHSPO+CHRIA+CHFIL+CHCRET+CHPUNC,RICM ;^M CR 015
XWD CHSPO+CHUAE+CHPUNC,0 ;^N SO 016
XWD CHSPO+CHNDFR+CHUAE+CHRIA+CHCRE+CHEPAR+CHPUNC,RICO ;^O SI 017
IFN FTMIC,<
XWD CHSPO+CHRIA+CHUAE+CHPUNC+CHNDFR,RICP ;^P DLE 020
>
IFE FTMIC,<
XWD CHSPO+CHUAE+CHPUNC,0 ;^P DLE 020
>
XWD CHSPO+CHUAE+CHFIL+CHRIA+CHEPAR+CHPUNC+CHNDFR,RICQ ;^Q XON 021
XWD CHSPO+CHUAE+CHFIL+CHRIA+CHBRK+CHEPAR+CHPUNC,RICR;^R TAPE 022
XWD CHSPO+CHUAE+CHRIA+CHFIL+CHPUNC+CHNDFR,RICS ;^S XOFF 023
XWD CHSPO+CHUAE+CHFIL+CHRIA+CHBRK+CHEPAR+CHPUNC+CHNDFR,RICT ;^T- NTAPE 024
XWD CHSPO+CHRIA+CHBRK+CHPUNC,RICU ;^U NAK 025
XWD CHSPO+CHUAE+CHRIA+CHPUNC+CHNDFR,RICV ;^V SYN 026
XWD CHSPO+CHUAE+CHRIA+CHEPAR+CHPUNC+CHBRK,RICW ;^W ETB 027
XWD CHSPO+CHUAE+CHEPAR+CHPUNC,0 ;^X CAN 030
XWD CHSPO+CHUAE+CHPUNC,0 ;^Y EM 031
XWD CHSPO+CHUAE+CHBRK+CHCRE+CHPUNC,0 ;^Z SUB 032
XWD CHSPO+CHBRK+CHALT+CHRIA+CHEPAR+CHPUNC,RIALT ;^[ ESC 033
XWD CHSPO+CHUAE+CHPUNC,0 ;^\ FS 034
XWD CHSPO+CHUAE+CHEPAR+CHPUNC,0 ;^] GS 035
XWD CHSPO+CHUAE+CHEPAR+CHPUNC,0 ;^^ RS 036
XWD CHSPO+CHUAE+CHPUNC,0 ;^_ US 037
XWD CHPUNC,0 ;SPACE 040
XWD CHEPAR+CHPUNC,0 ;! 041
XWD CHEPAR+CHPUNC,0 ;" 042
XWD CHPUNC,0 ;# 043
XWD CHEPAR+CHPUNC,0 ;$ 044
XWD CHPUNC,0 ;% 045
XWD CHPUNC,0 ;& 046
XWD CHEPAR+CHPUNC,0 ;' 047
XWD CHEPAR+CHPUNC,0 ;( 050
XWD CHPUNC,0 ;) 051
XWD CHPUNC,0 ;* 052
XWD CHEPAR+CHPUNC,0 ;+ 053
XWD CHPUNC,0 ;, 054
XWD CHEPAR+CHPUNC,0 ;- 055
XWD CHEPAR+CHPUNC,0 ;. 056
XWD CHPUNC,0 ;/ 057
XWD CHEPAR,0 ;0 060
0 ;1 061
0 ;2 062
XWD CHEPAR,0 ;3 063
0 ;4 064
XWD CHEPAR,0 ;5 065
XWD CHEPAR,0 ;6 066
0 ;7 067
0 ;8 070
XWD CHEPAR,0 ;9 071
XWD CHEPAR+CHPUNC,0 ;: 072
XWD CHPUNC,0 ;; 073
XWD CHEPAR+CHPUNC,0 ;< 074
XWD CHPUNC,0 ;= 075
XWD CHPUNC,0 ;> 076
XWD CHEPAR+CHPUNC,0 ;? 077
XWD CHPUNC,0 ;@ 100
XWD CHEPAR,0 ;A 101
XWD CHEPAR,0 ;B 102
0 ;C 103
XWD CHEPAR,0 ;D 104
0 ;E 105
0 ;F 106
XWD CHEPAR,0 ;G 107
XWD CHEPAR,0 ;H 110
0 ;I 111
0 ;J 112
XWD CHEPAR,0 ;K 113
0 ;L 114
XWD CHEPAR,0 ;M 115
XWD CHEPAR,0 ;N 116
0 ;O 117
XWD CHEPAR,0 ;P 120
0 ;Q 121
0 ;R 122
XWD CHEPAR,0 ;S 123
0 ;T 124
XWD CHEPAR,0 ;U 125
XWD CHEPAR,0 ;V 126
0 ;W 127
0 ;X 130
XWD CHEPAR,0 ;Y 131
XWD CHEPAR,0 ;Z 132
XWD CHPUNC,0 ;[ 133
XWD CHEPAR+CHPUNC,0 ;/ 134
XWD CHPUNC,0 ;] 135
XWD CHPUNC,0 ;^ 136
XWD CHEPAR+CHPUNC,0 ;_ 137
;THESE LETTERS ARE LOWER-CASE
XWD CHEPAR+CHPUNC,0 ;` 140
0 ;a 141
0 ;b 142
XWD CHEPAR,0 ;c 143
0 ;d 144
XWD CHEPAR,0 ;e 145
XWD CHEPAR,0 ;f 146
0 ;g 147
0 ;h 150
XWD CHEPAR,0 ;i 151
XWD CHEPAR,0 ;j 152
0 ;k 153
XWD CHEPAR,0 ;l 154
0 ;m 155
0 ;n 156
XWD CHEPAR,0 ;o 157
0 ;p 160
XWD CHEPAR,0 ;q 161
XWD CHEPAR,0 ;r 162
0 ;s 163
XWD CHEPAR,0 ;t 164
0 ;u 165
0 ;v 166
XWD CHEPAR,0 ;w 167
XWD CHEPAR,0 ;x 170
0 ;y 171
0 ;z 172
XWD CHEPAR+CHPUNC,0 ;{ 173
XWD CHPUNC,0 ;| 174
;THE 3 HIGH SPECIALS
XWD CHSPO+CHRIA+CHEPAR+CHALT+CHPUNC,RIALT ;} 175
XWD CHSPO+CHRIA+CHEPAR+CHALT+CHPUNC,RIALT ;~ 176
XWD CHSPO+CHBRK+CHRIA+CHPUNC+CHDEL,RIDEL ; DEL 177
;HERE WE START THE 8-BIT CHARACTER EXTENSION
;DEFINE A COMMON SET OF BITS FOR INVALID GRAPHICS
CH8INV==CHSPO+CHBRK+CHPUNC+CHINVL
;NOW, DO THE TABLE
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 200
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 201
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 202
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 203
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;IND 204
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;NEL 205
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;SSA 206
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;ESA 207
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;HTS 210
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;HTJ 211
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;VTS 212
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;PLD 213
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;PLU 214
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RI 215
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;SS2 216
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;SS3 217
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;DCS 220
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;PU1 221
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;PU2 222
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;STS 223
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;CCH 224
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;MW 225
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;SPA 226
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;EPA 227
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 230
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 231
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;RESERVED 232
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;CSI 233
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;ST 234
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;OSC 235
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;PM 236
XWD CHSPO+CHBRK+CHPUNC+CH2PC,0 ;APC 237
XWD CH8INV,0 ;RESERVED 240
XWD CHPUNC,0 ;SP03 241
XWD CHPUNC+CH2PC,0 ;SC04 242
XWD CHPUNC+CH2PC,0 ;SC02 243
XWD CH8INV,0 ;RESERVED 244
XWD CHPUNC+CH2PC,0 ;SC05 245
XWD CH8INV,0 ;RESERVED 246
XWD CHPUNC+CH2PC,0 ;SM24 247
XWD CHPUNC+CH2PC,0 ;SC01 250
XWD CHPUNC+CH2PC,0 ;SM52 251
XWD CHPUNC+CH2PC,0 ;SM21 252
XWD CHPUNC+CH2PC,0 ;SP17 253
XWD CH8INV,0 ;RESERVED 254
XWD CH8INV,0 ;RESERVED 255
XWD CH8INV,0 ;RESERVED 256
XWD CH8INV,0 ;RESERVED 257
XWD CHPUNC,0 ;SM19 260
XWD CHPUNC+CH2PC,0 ;SA02 261
XWD CHPUNC,0 ;NS02 262
XWD CHPUNC,0 ;NS03 263
XWD CH8INV,0 ;RESERVED 264
XWD CHPUNC,0 ;SM17 265
XWD CHPUNC+CH2PC,0 ;SM25 266
XWD CHPUNC,0 ;SM26 267
XWD CH8INV,0 ;RESERVED 270
XWD CHPUNC,0 ;NS01 271
XWD CHPUNC+CH2PC,0 ;SM20 272
XWD CHPUNC+CH2PC,0 ;SP18 273
XWD CHPUNC+CH2PC,0 ;NF04 274
XWD CHPUNC+CH2PC,0 ;NF01 275
XWD CH8INV,0 ;RESERVED 276
XWD CHPUNC,0 ;SP16 277
XWD 0,0 ;LA14 300
XWD 0,0 ;LA12 301
XWD 0,0 ;LA16 302
XWD 0,0 ;LA20 303
XWD 0,0 ;LA18 304
XWD 0,0 ;LA28 305
XWD CH2PC,0 ;LA52 306
XWD CH2PC,0 ;LC42 307
XWD 0,0 ;LE14 310
XWD 0,0 ;LE12 311
XWD 0,0 ;LE16 312
XWD 0,0 ;LE18 313
XWD 0,0 ;LI14 314
XWD 0,0 ;LI12 315
XWD 0,0 ;LI16 316
XWD 0,0 ;LI18 317
XWD CH8INV,0 ;RESERVED 320
XWD 0,0 ;LN20 321
XWD 0,0 ;LO14 322
XWD 0,0 ;LO12 323
XWD 0,0 ;LO16 324
XWD 0,0 ;LO20 325
XWD 0,0 ;LO18 326
XWD CH2PC,0 ;LO52 327
XWD CH2PC,0 ;LO62 330
XWD 0,0 ;LU14 331
XWD 0,0 ;LU12 332
XWD 0,0 ;LU16 333
XWD 0,0 ;LU18 334
XWD 0,0 ;LY18 335
XWD CH8INV,0 ;RESERVED 336
XWD CH2PC,0 ;LS61 337
XWD CH2PC,0 ;LA13 340
XWD CH2PC,0 ;LA11 341
XWD CH2PC,0 ;LA15 342
XWD CH2PC,0 ;LA19 343
XWD CH2PC,0 ;LA17 344
XWD 0,0 ;LA27 345
XWD CH2PC,0 ;LA51 346
XWD CH2PC,0 ;LC41 347
XWD CH2PC,0 ;LE13 350
XWD CH2PC,0 ;LE11 351
XWD CH2PC,0 ;LE15 352
XWD CH2PC,0 ;LE17 353
XWD CH2PC,0 ;LI13 354
XWD CH2PC,0 ;LI11 355
XWD CH2PC,0 ;LI15 356
XWD CH2PC,0 ;LI17 357
XWD CH8INV,0 ;RESERVED 360
XWD CH2PC,0 ;LN19 361
XWD CH2PC,0 ;LO13 362
XWD CH2PC,0 ;LO11 363
XWD CH2PC,0 ;LO15 364
XWD CH2PC,0 ;LO19 365
XWD CH2PC,0 ;LO17 366
XWD CH2PC,0 ;LO51 367
XWD CH2PC,0 ;LO61 370
XWD CH2PC,0 ;LU13 371
XWD CH2PC,0 ;LU11 372
XWD CH2PC,0 ;LU15 373
XWD CH2PC,0 ;LU17 374
XWD CH2PC,0 ;LY17 375
XWD CH8INV,0 ;RESERVED 376
XWD CH8INV,0 ;RESERVED 377
;THE META-CHARACTERS (THE IMBEDDED FUNCTIONS)
DEFINE META(NM,BITS)<
MC.'NM==CK.MET+<.-METABL>
XWD CHSPO!BITS,MET'NM
>
METABL:
META NL,CHBRK+CHPUNC+CHFIL+CHCRET+CH2PC ;ACR
;*** BE SURE THAT ALL REAL 2-PART META CHARACTERS ARE ABOVE THIS LINE
MAX2PM==.-METABL ;MAX INDEX OF REAL 2-PART METAS
META DL,CHPUNC+CHUAE+CHCRE ;^U
META DW,CHPUNC+CHUAE ;^W
META DC,CHPUNC ;DEL
META BS,CHPUNC+CHFIL ;^H
META NFC,CHPUNC+CH2PC ;.TONFC
META HPS,CHPUNC+CH2PC ;.TOHPS
META FLM,CHPUNC+CHCRET ;.TOFLM
META DEN,CHPUNC ;.TODEM ON
META DEF,CHPUNC ;.TODEM OFF
META CHP,CHPUNC ;SETCHP
META RTS,CHPUNC ;^R START
META RTE,CHPUNC ;^R END
META FRM,CHPUNC+CH2PC ;.TOFRM
META TAB,CHPUNC+CH2PC ;.TOTAB
META WID,CHPUNC+CH2PC ;.TOWID
METLEN==.-METABL ;LENGTH OF METABL (FOR VALIDITY TESTS)
;SINCE WE SHOULD NEVER BE TRYING TO DISPATCH FOR EXPANDABLE META-CHARACTERS,
; DEFINE THEM HERE TO BE STOPCODES
METNL: STOPCD .,STOP,MCCWNE, ;++ META CHARACTER CALLED WHEN NOT EXPECTED
;HERE WE START THE CHARACTER EQUIVALENCE TABLES
;DEFINE A HELPER MACRO FOR BUILDING THE REPLACEMENT STRINGS
DEFINE CHS(A,B,C,D),<BYTE (9) D,C,B,A>
;FIRST, THE TABLE FOR 'NORMAL' 8-BIT CHARACTERS (IE, TOP HALF OF ASCII SET)
CHREQV:
CHS 033,100 ;RESERVED 200
CHS 033,101 ;RESERVED 201
CHS 033,102 ;RESERVED 202
CHS 033,103 ;RESERVED 203
CHS 033,104 ;IND 204
CHS 033,105 ;NEL 205
CHS 033,106 ;SSA 206
CHS 033,107 ;ESA 207
CHS 033,110 ;HTS 210
CHS 033,111 ;HTJ 211
CHS 033,112 ;VTS 212
CHS 033,113 ;PLD 213
CHS 033,114 ;PLU 214
CHS 033,115 ;RI 215
CHS 033,116 ;SS2 216
CHS 033,117 ;SS3 217
CHS 033,120 ;DCS 220
CHS 033,121 ;PU1 221
CHS 033,122 ;PU2 222
CHS 033,123 ;STS 223
CHS 033,124 ;CCH 224
CHS 033,125 ;MW 225
CHS 033,126 ;SPA 226
CHS 033,127 ;EPA 227
CHS 033,130 ;RESERVED 230
CHS 033,131 ;RESERVED 231
CHS 033,132 ;RESERVED 232
CHS 033,133 ;CSI 233
CHS 033,134 ;ST 234
CHS 033,135 ;OSC 235
CHS 033,136 ;PM 236
CHS 033,137 ;APC 237
CHS 137 ;RESERVED 240
CHS 041 ;SP03 241
CHS 174,010,143 ;SC04 242
CHS 075,010,114 ;SC02 243
CHS 137 ;RESERVED 244
CHS 075,010,131 ;SC05 245
CHS 137 ;RESERVED 246
CHS 123,143 ;SM24 247
CHS 170,010,117 ;SC01 250
CHS 050,103,51 ;SM52 251
CHS 137,010,141 ;SM21 252
CHS 074,074 ;SP17 253
CHS 137 ;RESERVED 254
CHS 137 ;RESERVED 255
CHS 137 ;RESERVED 256
CHS 137 ;RESERVED 257
CHS 157 ;SM19 260
CHS 137,010,053 ;SA02 261
CHS 062 ;NS02 262
CHS 063 ;NS03 263
CHS 137 ;RESERVED 264
CHS 165 ;SM17 265
CHS 120,162 ;SM25 266
CHS 056 ;SM26 267
CHS 137 ;RESERVED 270
CHS 061 ;NS01 271
CHS 137,010,157 ;SM20 272
CHS 076,076 ;SP18 273
CHS 061,057,064 ;NF04 274
CHS 061,057,062 ;NF01 275
CHS 137 ;RESERVED 276
CHS 077 ;SP16 277
CHS 101 ;LA14 300
CHS 101 ;LA12 301
CHS 101 ;LA16 302
CHS 101 ;LA20 303
CHS 101 ;LA18 304
CHS 101 ;LA28 305
CHS 101,105 ;LA52 306
CHS 054,010,103 ;LC42 307
CHS 105 ;LE14 310
CHS 105 ;LE12 311
CHS 105 ;LE16 312
CHS 105 ;LE18 313
CHS 111 ;LI14 314
CHS 111 ;LI12 315
CHS 111 ;LI16 316
CHS 111 ;LI18 317
CHS 137 ;RESERVED 320
CHS 116 ;LN20 321
CHS 117 ;LO14 322
CHS 117 ;LO12 323
CHS 117 ;LO16 324
CHS 117 ;LO20 325
CHS 117 ;LO18 326
CHS 117,105 ;LO52 327
CHS 057,010,117 ;LO62 330
CHS 125 ;LU14 331
CHS 125 ;LU12 332
CHS 125 ;LU16 333
CHS 125 ;LU18 334
CHS 131 ;LY18 335
CHS 137 ;RESERVED 336
CHS 163,163 ;LS61 337
CHS 140,010,141 ;LA13 340
CHS 047,010,141 ;LA11 341
CHS 136,010,141 ;LA15 342
CHS 176,010,141 ;LA19 343
CHS 042,010,141 ;LA17 344
CHS 141 ;LA27 345
CHS 141,145 ;LA51 346
CHS 054,010,143 ;LC41 347
CHS 140,010,145 ;LE13 350
CHS 047,010,145 ;LE11 351
CHS 136,010,145 ;LE15 352
CHS 042,010,145 ;LE17 353
CHS 140,010,151 ;LI13 354
CHS 047,010,151 ;LI11 355
CHS 136,010,151 ;LI15 356
CHS 042,010,151 ;LI17 357
CHS 137 ;RESERVED 360
CHS 176,010,156 ;LN19 361
CHS 140,010,157 ;LO13 362
CHS 047,010,157 ;LO11 363
CHS 136,010,157 ;LO15 364
CHS 176,010,157 ;LO19 365
CHS 042,010,157 ;LO17 366
CHS 157,145 ;LO51 367
CHS 057,010,157 ;LO61 370
CHS 140,010,165 ;LU13 371
CHS 047,010,165 ;LU11 372
CHS 136,010,165 ;LU15 373
CHS 042,010,165 ;LU17 374
CHS 042,010,171 ;LY17 375
CHS 137 ;RESERVED 376
CHS 137 ;RESERVED 377
;AND HERE, THE ONE FOR META CHARACTERS
MCHEQV:
CHS 015,012 ;ACR MC.NL
IFN <.-MCHEQV>-MAX2PM,<PRINTX ? PHASE ERROR BETWEEN METABL AND MCHEQV>
;ROUTINES TO CHECK IF NEED TO SET UP FOR CHARACTER EXPANSION
;CALL WITH CHARACTER ABOUT TO PROCESS IN T3.
;ON RETURN, WILL LEAVE CHARACTER UNCHANGED IF NO NEED TO EXPAND,
;OR WILL LIGHT THE APPROPRIATE EXPANSION BITS (IF ANY) AND RETURN THE
;FIRST CHARACTER OF THE EXPANSION IN T3.
;HERE FOR INPUT
TPCINP: MOVSI T1,L3LIHD ;GET INPUT BIT
PUSHJ P,TPCIE1 ;SEE IF WE NEED TO DO ANYTHING
POPJ P, ;NO, WE'RE DONE HERE
SETO T1, ;YES, WE NEED TO BACK UP BY ONE
ADJBP T1,LDBTIT(U) ;BACKSPACE OUR CHARACTER POINTER
MOVEM T1,LDBTIT(U) ;STORE BACK IN LDB
AOS LDBTIC(U) ;AND THERE'S ANOTHER TO BE READ
POPJ P, ;RETURN TO TYICC5
;HERE FOR ECHO
TPCECH: PUSH P,T2 ;WE NEED T2 PRESERVED
MOVSI T1,L3LEHD ;GET ECHO BIT
PUSHJ P,TPCIE1 ;SEE IF WE NEED TO DO ANYTHING
JRST T2POPJ## ;NO, WE'RE DONE HERE
SETO T1, ;YES, WE NEED TO BACK UP BY ONE
ADJBP T1,LDBECT(U) ;BACKSPACE OUR CHARACTER POINTER
MOVEM T1,LDBECT(U) ;STORE BACK IN LDB
AOS LDBECC(U) ;THERE'S ANOTHER TO BE ECHOED
POP P,T2 ;THIS NEXT IS WHAT T2 IS FOR
SOS T2,LDBTIC(U) ;AND ONE LESS TO BE READ
POPJ P, ;RETURN TO XMTECI
TPCIE1: TDNE T1,LDBBY3(U) ;ARE WE ALREADY DOING THIS?
JRST TPCNXT ;YES, GO SEE HOW FAR ALONG
TRNE T3,CK.NIS ;NO. IF NOT IN STREAM,
POPJ P, ;THEN DON'T EXPAND IT
TRNE T3,CK.MET ;IF META CHARACTER,
JRST TPCINM ;THEN CHECK DIFFERENTLY
TRNN T3,CK.IMG ;IF IMAGE CHARACTER,
SKIPL LDBATR(U) ;OR 7-BIT TERMINAL,
POPJ P, ;THEN NO NEED TO EXPAND
TLNE T1,L3LEHD ;IF ECHOING,
TRNN T3,CK.FDE ;AND DONE BY REMOTE,
TRNN T3,CK.PAR ;OR IF 7-BIT CHARACTER,
POPJ P, ;THEN NO NEED TO EXPAND
MOVSI T4,LDL8BI ;8-BIT INPUT BY PROGRAM
TDNE T4,LDBDCH(U) ;CONVERSION NEEDED?
POPJ P, ;NO, RETURN UNCHANGED
;HERE, WE KNOW WE'RE GOING TO DO CONVERSION. IT'S ONLY A MATTER OF HOW.
TPCALT: ANDI T3,CK.CHR ;MASK OFF FUNNY BITS
MOVE T2,CHTABL(T3) ;GET BITS FROM TABLE
TLNN T2,CH2PC ;TWO-PART CHARACTER?
JRST TPCALX ;NO, RETURN JUST ONE CHARACTER
TLNE T1,L3LEHD!L3LIHD!L3LCHD ;CHECKING FOR INPUT?
JRST TPCAL0 ;YES, DON'T PASS OVERSTRIKE SEQUENCES
MOVSI T2,LALCOS ;CAN OVERSTRIKE ATTRIBUTE
TDNE T2,LDBATR(U) ;SET FOR THIS TERMINAL?
JRST TPCAL1 ;DON'T CHECK OVERSTRIKE SEQUENCE
TPCAL0: MOVEI T2,367000 ;GET MASK TO TEST FOR BACKSPACE IN THE MIDDLE
TDNN T2,CHREQV-200(T3) ;IS THIS AN OVERSTRIKE SEQUENCE?
JRST TPCALQ ;YES, GIVE THIRD CHARACTER ALONE
TPCAL1: IORM T1,LDBBY3(U) ;SET PROGRESS BITS FOR MULTI-PART CHARACTER
AOS (P) ;SKIP RETURN MEANS TO CONTINUE
TPCALX: MOVE T3,CHREQV-200(T3) ;GET EQUIVALENCE SEQUENCE
ANDI T3,CK.CHR ;MASK DOWN TO FIRST FOR THIS CALL
POPJ P, ;RETURN THE ALTERED CHARACTER
TPCALQ: HLRZ T3,CHREQV-200(T3) ;LAST OF REGULAR CHARACTER ONLY
POPJ P, ;JUST RETURN ALTERED CHARACTER
;HERE FOR COMCON
TPCCOM: MOVSI T1,L3LCHD ;COMMAND (COMCON) PROGRESS BIT
PUSHJ P,TPCCO1 ;SEE IF WE NEED TO DO ANYTHING
POPJ P, ;NO, WE'RE DONE HERE
SETO T1, ;YES, GET B.P. DECREMENT
ADJBP T1,LDBCLP(U) ;BACK UP COMMAND POINTER
MOVEM T1,LDBCLP(U) ;STORE BACK IN LDB
POPJ P, ;RETURN TO CCTYI0
TPCCO1: TDNE T1,LDBBY3(U) ;HAVE WE BEEN HERE BEFORE?
JRST TPCNXT ;YES, GET NEXT BYTE OF EXPANSION
TRNE T3,CK.MET ;IF META,
JRST TPCINM ;CHECK DIFFERENTLY
TRNN T3,CK.IMG ;NO. IF IMAGE OR
TRNE T3,CK.NIS ;IF NOT IN STREAM,
POPJ P, ;RETURN UNCHANGED
TRNN T3,CK.PAR ;IF 7-BIT CHARACTER,
POPJ P, ;THEN WE DON'T NEED CONVERSION
JRST TPCALT ;NEEDS CONVERSION, GO ALTER IT
;HERE FOR OUTPUT
TPCOUT: MOVSI T1,L3LOHD ;OUTPUT PROGRESS BIT
PUSHJ P,TPCOF1 ;SEE IF ANYTHING NEEDS TO BE DONE
POPJ P, ;NO, WE'RE ALL DONE HERE
SETO T1, ;YES, WE NEED TO BACK UP OUR POINTER
ADJBP T1,LDBTOT(U) ;SUBTRACT ONE
MOVEM T1,LDBTOT(U) ;STORE BACK IN LDB
AOS T4,LDBTOC(U) ;AND THERE'S ANOTHER TO BE TYPED
POPJ P, ;RETURN TO XMTCH1
;HERE FOR FILL
TPCFIL: MOVSI T1,L3LFHD ;FILL PROGRESS BIT
PUSHJ P,TPCOF1 ;SEE IF ANYTHING NEEDS TO BE DONE
POPJ P, ;NO, WE'RE ALL DONE HERE
SETO T1, ;YES, GET B.P. DECREMENT
ADJBP T1,LDBEOT(U) ;BACK UP OUR POINTER
MOVEM T1,LDBEOT(U) ;STORE BACK IN LDB
AOS LDBEOC(U) ;THERE'S ANOTHER TO GO
POPJ P, ;RETURN TO XMTESP
TPCOF1: TDNE T1,LDBBY3(U) ;ARE WE ALREADY DOING THIS?
JRST TPCNXT ;YES, GET NEXT BYTE FROM THE SEQUENCE
TRNN T3,CK.IMG ;NO. IF IMAGE OR
TRNE T3,CK.NIS ;IF NOT IN STREAM,
POPJ P, ;RETURN UNCHANGED
TRNE T3,CK.MET ;IF META,
JRST TPCINM ;CHECK DIFFERENTLY
SKIPL LDBATR(U) ;IF 8-BIT TERMINAL,
TRNN T3,CK.PAR ;OR 7-BIT CHARACTER,
POPJ P, ;THEN DON'T NEED CONVERSION
JRST TPCALT ;NEEDS CONVERSION, GO ALTER IT
;HERE FOR META CHARACTER IN ANY MODE
TPCINM: TRNE T3,CK.IMG ;IS THIS FOR A QUOTED CHARACTER?
JRST TPCINQ ;YES, IT'S NOT REALLY META
MOVE T2,T3 ;GET COPY OF CHARACTER
ANDI T2,CK.CHR ;MASK OFF FUNNY BITS
CAIL T2,MAX2PM ;IN RANGE OF REAL 2-PART METAS?
POPJ P, ;NO, DON'T TRANSLATE
HLL T2,METABL(T2) ;GET TABLE BITS IN LEFT HALF
TLNN T2,CH2PC ;EXPANDABLE CHARACTER?
POPJ P, ;NO, RETURN UNCHANGED
IORM T1,LDBBY3(U) ;YES, ALL TRANSLATABLE METAS ARE MULTIPLE
MOVE T2,MCHEQV(T2) ;SET PROGRESS BIT AND GET TRANSLATION
ANDI T2,CK.CHR ;MASK DOWN TO FIRST FOR THIS CALL
ANDI T3,CK.FDE ;PRESERVE ONLY THIS BIT FROM ORIGINAL
IORI T3,(T2) ;MERGE TO NEW CHARACTER TO RETURN
JRST CPOPJ1## ;GIVE BACK AN ALTERED CHARACTER
;HERE TO CHECK FOR QUOTING CHARACTER
TPCINQ: TLNN T1,L3LIHD!L3LCHD!L3LEHD ;WERE WE CALLED BY SOMEONE WHO CARES?
POPJ P, ;NO, FORGET ABOUT TRANSLATING IT
IORM T1,LDBBY3(U) ;SET FOR READING THE NEXT CHARACTER
TLNN T1,L3LEHD ;UNLESS THIS WAS FOR XMTECH,
TRZ T3,CK.MET ;CLEAR THE META BIT
TRZ T3,CK.CHR ;GET RID OF THE CHARACTER VALUE
TRO T3,26 ;TURN INTO AN IMAGE-MODE ^V
JRST CPOPJ1## ;RETURN THE CHARACTER FOR TRANSLATION
;HERE TO GET THE NEXT VALUE FROM THE EQUIVALENCE STRING FOR THE CHARACTER IN T3.
;CONTROLLING PROGRESS BIT IS IN T1. USES T2.
TPCNXT: TRNE T3,CK.IMG ;IS THIS FOR A QUOTED CHARACTER?
JRST TPCNXQ ;YES, GO DO IT
MOVE T2,T1 ;NO, COPY PROGRESS BIT
LSH T1,TPCLSH ;CONVERT TO THIRD-PART BIT
ANDI T3,CK.MET+CK.FDE+CK.CHR;KEEP ONLY IMPORTANT BITS
TDNE T1,LDBBY3(U) ;NEED THIRD CHARACTER?
JRST TPCNX3 ;YES, GO GET IT
IOR T1,T2 ;GET BOTH CONTROL BITS IN ONE AC
MOVE T2,T3 ;COPY CHARACTER
ANDI T2,CK.CHR ;MASK DOWN TO INDEX
TRNE T3,CK.MET ;META CHARACTER?
SKIPA T2,MCHEQV(T2) ;YES, GET META EQUIVALENCE
MOVE T2,CHREQV-200(T2) ;NO, GET CHARACTER EQUIVALENCE
LSH T2,-9 ;DROP THE FIRST CHARACTER (ALREADY DONE)
ANDCAM T1,LDBBY3(U) ;CLEAR CONTROL BIT THAT BRINGS US HERE
TRZN T2,777000 ;IF A THIRD CHARACTER,
JRST TPCALM ;(NO)
IORM T1,LDBBY3(U) ; THEN LIGHT PART-2 AND PART-3 BITS
AOS (P) ;SKIP RETURN MEANS TO CONTINUE
TPCALM: ANDI T3,CK.FDE ;KEEP THE ONLY IMPORTANT BIT
IORI T3,(T2) ;BUILD A NEW CHARACTER
POPJ P, ;RETURN THE NEXT CHARACTER IN SEQUENCE
TPCNX3: IOR T1,T2 ;COMBINE PROGRESS BITS
ANDCAM T1,LDBBY3(U) ;DONE EXPANDING THIS CHARACTER
MOVE T2,T3 ;COPY CHARACTER
ANDI T2,CK.CHR ;MASK DOWN TO INDEX
TRNE T3,CK.MET ;IF META,
SKIPA T2,MCHEQV(T2) ;THEN GET META EQUIVALENCE
MOVE T2,CHREQV-200(T2) ;ELSE GET CHARACTER EQUIVALENCE
HLRZS T2 ;POSITION THIRD (AND KNOWN LAST) CHARACTER
JRST TPCALM ;FIX UP FOR CK.FDE AND RETURN NEW CHARACTER
TPCNXQ: ANDCAM T1,LDBBY3(U) ;CLEAR BIT THAT BROUGHT US HERE
TLNN T1,L3LEHD ;UNLESS THIS WAS FOR XMTECH,
TRZ T3,CK.MET ;CLEAR THE CONFUSING BIT
POPJ P, ;GIVE DONE RETURN
;ROUTINE TO CHECK FOR A SPECIAL CHARACTER AND SET T1 TO ITS DESCRIPTOR
;ENTER WITH T3 SET UP
;SKIPS IF CHAR IS 0-37 OR 175-177
;IGNORES AND DOES NOT RETURN PARITY BIT (CHEPAR)
SPCHEK::SE1ENT ;ENTER SECTION 1
TRNE T3,CK.MET ;IMBEDDED FUNCTION CHARACTER?
JRST SPCHE3 ;YES, HANDLE DIFFERENTLY
TRNE T3,CK.IMG ;IF IMAGE,
JRST SPCHE1 ;THEN ALWAYS HANDLE NORMALLY
MOVE T1,T3 ;COPY CHAR
ANDI T1,CK.CHR ;CLEAR BITS
SKIPN DINITF## ;U NOT SETUP IN ONCE ONLY
SKIPL LDBBKB(U) ;BREAK MASK SPECIFIED?
JRST SPCHE1 ;NO, NORMAL PROCESSING
PUSH P,T2 ;SAVE VOLATILE AC
MOVSI T2,LDLCOM ;COMMAND LEVEL BIT
TDNE T2,LDBDCH(U) ;ARE WE AT COMMAND LEVEL?
JRST [POP P,T2 ;YES, RESTORE AC
JRST SPCHE1] ;HANDLE NORMALLY
PUSHJ P,TOPGCB ;NO, GET CHARACTER STATUS BYTE
MOVE T1,CHTABL(T1) ;GET THE CHARACTER'S BITS
TRNE T2,CC.BRK ;SHOULD IT BREAK?
TLOA T1,CHBRK ;YES,
TLZ T1,CHBRK ;OR NOT
TRNE T2,CC.NSA ;STOP ANY SPECIAL ACTION?
TDZ T1,[CHRIA!CHCRET!CHCNC!CHALT,,-1] ;YES
TRNE T2,CC.OOB ;IS IT OUT-OF-BAND?
TLO T1,CHOOB ;YES, LIGHT O-O-B FLAG
POP P,T2 ;RESTORE T2
JRST SPCHE2 ;AND GET OUT
SPCHE1: TRNE T3,CK.IMG ;IF IMAGE,
TDZA T1,T1 ;NEVER SPECIAL
MOVE T1,CHTABL(T1) ;GET TABLE ENTRY
SPCHE2: TLZ T1,CHEPAR+CH2PC+CHPUNC ;CLEAR PARITY AND PUNCTUATION BIT
SKIPE T1 ;SPECIAL?
AOS (P) ;YES--SKIP
POPJ P, ;RETURN
SPCHE3: TRNN T3,CK.IMG ;IS THIS A QUOTED CHARACTER?
PJRST RICRET ;NO, JUST RETURN META BITS
MOVE T1,T3 ;YES, GET COPY OF CHARACTER
ANDI T1,CK.CHR ;KEEP ONLY RELEVANT PORTION
HLLZ T1,CHTABL(T1) ;GET ITS BITS
TLZ T1,CHRIA!CHFIL!CHCRE!CHALT!CHNDFR!CHBRK!CHCRET!CHCNC!CHVPOS!CHEPAR!CH2PC ;CLEAR CRUFTY BITS
TRNE T3,CK.CH7^!37 ;IS IT A CONTROL CHARACTER?
TLZE T1,CHDEL ;OF EITHER FLAVOR?
TLO T1,CHUAE ;YES, ECHO IN UPARROW FORM
POPJ P, ;GIVE MUNDANE RETURN
RICRET: MOVE T1,T3 ;GET COPY OF CHARACTER
ANDI T1,CK.CHR ;REDUCE TO JUST FUNCTION CODE
MOVE T1,METABL(T1) ;GET CHARACTER BITS
JRST CPOPJ1## ;THESE ARE ALWAYS SPECIAL
;SUBROUTINE TO GET EVEN PARITY USING CHEPAR BIT OF CHTABL
;CALLED FROM SCNSER,PTPSER AND IN ONCE
;CALLING SEQUENCE: PUSHJ P,PEVEN8
;ON ENTRY, T3 CONTAINS A CHARACTER IN BITS 28 TO 35,
; BITS 0 TO 27 ARE IGNORED
;ON EXIT, BIT 28 IS CHANGED IF NECESSARY SUCH THAT THE PARITY
; OF BITS 28 TO 35 IS EVEN, AND BITS
; 0 TO 27 ARE ALL 0
PEVEN8::ANDI T3,CK.CH7 ;CLEAR TO 7 BITS FOR INDEX
PUSH P,T1 ;SAVE T1
MOVE T1,CHTABL(T3) ;GET CHARACTER TABLE ENTRY
TLNN T1,CHEPAR ;ALREADY EVEN
TRO T3,CK.PAR ;WAS NOT, PUT IN PARITY BIT
JRST TPOPJ## ;RESTORE T1 AND RETURN
SUBTTL CHUNK HANDLERS
;The routines NEWCKI and NEWCKO are provided only to support the
;macros LDCHK, LDCHKR, and STCHK.
;NEWCKO -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN PUTTING CHARACTERS
; INTO THE TERMINAL BUFFER CHUNKS.
NEWCKO::JUMPE T1,NWCKO8 ;NO CHUNKS AT ALL, INITIALIZE
SSX T1,MS.SCN ;GET SECTION NUMBER
HRRZ T2,CK.BTH##(T1) ;ADDRESS OF NEXT CHUNK IN CHAIN, IF ANY
JUMPE T2,NWCKO3 ;ALLOCATE NEW CHUNK IF NONE THERE YET
PUSHJ P,RCCTST ;RANGE CHECK ALLEGED NEXT CHUNK ADDRESS
POPJ P, ;WHOA - A BAD CHUNK ADDRESS
JRST NWCKO6 ;SET BYTE POINTER AND RETURN
NWCKO3: MOVEI T2,CK.BTH##(T1) ;ADDRESS OF CURRENT CHUNK
PUSHJ P,GETCHK ;ALLOCATE A CHUNK FROM FREE LIST
SSX T1,MS.SCN ;GET SECTION NUMBER
HRLZM T2,(T1) ;BACK POINTER TO EXISTING LIST
SSX T2,MS.SCN ;GET SECTION NUMBER
HRRM T1,(T2) ;FORWARD POINTER TO NEW CHUNK
NWCKO5: HRRZS T2,T1 ;POSITION NEW CHUNK INTO T2, AND
NWCKO6: ADD T2,[POINT CK.WID,1] ;MAKE A BYTE POINTER
AOS (P) ;INLINE FOR SPEED
POPJ P, ;AND RETURN
NWCKO8: PUSHJ P,GETCKZ ;GET A NEW CHUNK
JRST NWCKO5 ;CONVERT TO BYTE POINTER AND RETURN
;NEWCKI -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS
; OUT OF THE TERMINAL CHUNKS. USES T1 - T3.
NEWCKI::SSX T1,MS.SCN ;SET SECTION NUMBER
HRRZ T2,CK.BTH##(T1) ;ADDRESS OF NEXT CHUNK IN CHAIN
PUSHJ P,RCCTST ;RANGE CHECK ALLEGED CHUNK
POPJ P, ;WHOA - BAD CHUNK ADDRESS
SSX T2,MS.SCN ;SET SECTION NUMBER
HRRZS (T2) ;CLEAR BACK POINTER
HRRZS T2 ;BACK TO SECTION RELATIVE
MOVEI T1,CK.BTH##(T1) ;ADDRESS OF OLD (EMPTY) CHUNK
PUSHJ P,FRECHK ;FREE UP THE STALE CHUNK
ADD T2,[POINT CK.WID,1] ;MAKE FORWARD POINTER INTO A BYTE PTR
AOS (P) ;INLINE FOR SPEED
POPJ P, ;AND RETURN
;NEWCKS -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS
; OUT OF THE TERMINAL CHUNKS. DIFFERS FROM NEWCKI IN THAT THE
; STALE CHUNKS ARE NOT DELETED.
NEWCKS::SSX T1,MS.SCN ;SET SECTION NUMBER
HRRZ T2,CK.BTH##(T1) ; ADDRESS OF NEXT CHUNK IN CHAIN
PUSHJ P,RCCTST ;GOODNESS-CHECK THE NEXT CHUNK
POPJ P, ;WHOA - A JUNK CHUNK
ADD T2,[POINT CK.WID,1] ;MAKE FORWARD POINTER INTO A BYTE PTR
AOS (P) ;INLINE FOR SPEED
POPJ P, ;AND RETURN
;RCCTST -- RANGE CHECK AND VERIFY CHUNK ADDRESS
;CALL IS:
;
; MOVX T2,<ADR>
; PUSHJ P,RCCTST
; ERROR (RCC STOPCD MESSAGE ISSUED)
; OK
;
;PRESERVES ALL ACS
RCCTST: JUMPE T2,CL0STP ;DIFFERENTIATE CL0 AND RCC STOPCDS
PUSH P,T2 ;SAVE ALL
CAML T2,TTBASE ;IF TOO LARGE
CAMLE T2,RCCMAX## ; OR TOO SMALL
PUSHJ P,RCCERR ;
ANDI T2,CK.BDY## ;JUST OFFSET WITHIN CHUNK
CAIE T2,1 ;MUST BE ONE
PUSHJ P,RCCERR ;ISN'T, DIE
SSX T2,MS.SCN ;SECTION NUMBER
HLLM T2,(P) ;STORE SO CAN ADDRESS AND FOR COMPARE
HLR T2,@(P) ;ADDRESS OF PREDECESSOR
HRR T2,(T2) ; SHOULD POINT TO US
CAME T2,(P) ;...
PUSHJ P,RCCERR ;DOESN'T, CHUNKS ARE MESSED UP
POP P,T2 ;INLINE
HRRZS T2 ;MAKE BACK INTO SECTION RELATIVE
AOS (P) ; FOR
POPJ P, ; SPEED
RCCERR: PUSHJ P,RCCSTP ;DIE
POP P,T2 ;ADJUST STACK
POP P,T2 ;RESTORE ORIGINAL T2
POPJ P, ;ERROR RETURN
;ASSORTED SCNSER STOPCD'S OF NOTE
CL0STP: STOPCD CLRSTP,DEBUG,CL0, ;++CHUNK LINKS TO 0
RCCSTP: STOPCD CLRSTP,DEBUG,RCC, ;++RANGE CHECKED CHUNK
RCDSTP: STOPCD CLRSTP,DEBUG,RCD, ;++RANDOM CHUNK DISCREPANCY
;HERE AFTER A STOPCD TO RESET AN LDB TO A NEW VIRGIN STATE SINCE
;WE CAN'T TRUST ANY OF ITS POINTERS/COUNTERS
CLRSTP: PUSH P,T1 ;PRESERVE ALL AC'S ON G.P.'S
SETZM LDBTIT(U) ;ZAPPETH ANY INPUT CHUNK STREAM
PUSHJ P,TYIVRG ;AND RESET ALL INPUT COUNTS/POINTERS
SETZM LDBTOT(U) ;ZAPPETH ANY OUTPUT CHUNK STREAMS
PUSHJ P,TYOVRG ;AND RESET ALL OUTPUT COUNTS/POINTERS
SETZM LDBEOT(U) ;ZAPPETH ANY ECHO CHUNK STREAMS
PUSHJ P,TYEVRG ;AND RESET ALL ECHO COUNTS/POINTERS
SETZM LDBOOT(U) ;ZAPPETH ANY OOB CHUNK STREAMS
PUSHJ P,TYBVRG ;AND RESET ALL OOB COUNTS/POINTERS
JRST TPOPJ## ;RESTORE T1 AND RETURN
SUBTTL CHUNK HANDLERS -- ALLOCATION AND DEALLOCATION
TYIVRG: SKIPE T1,LDBTIT(U) ;IF ANY POINTER
JRST TYIVR1 ;IF POINTER ALREADY EXISTS
PUSHJ P,GETCKZ ;GET A FREELIST CHUNK
ADD T1,[POINT CK.WID,1,CK.WID-1] ;MAKE BYTE POINTER
MOVEM T1,LDBTIT(U) ;SET TAKER
TYIVR1: MOVEM T1,LDBTIP(U) ;SET PUTTER BACK TO TAKER
MOVEM T1,LDBECT(U) ;AND THE ECHO POINTER
SETZM LDBBKU(U) ;BREAK LOCATION
SETZM LDBBKI(U) ;BREAK LOCATION
SETZM LDBTIC(U) ;NO CHARACTERS BUFFERED
SETZM LDBBKC(U) ;WHICH MEANS NO BREAK CHARACTERS BUFFERED
SETZM LDBECC(U) ;AND NO CHARACTERS WAITING TO BE ECHOED
SETZM LDBIIC(U) ;AND NO INIVISIBLE INPUT CHARACTERS
SETZM LDBIEC(U) ;AND NO INIVISIBLE CHARACTERS TO BE ECHOED
POPJ P, ;INPUT CHUNK STREAM ALL SET
TYOVRG: SKIPE T1,LDBTOT(U) ;IF ALREADY A GOOD POINTER
JRST TYOVR1 ;DON'T WASTE A GOOD CHUNK
PUSHJ P,GETCKZ ;GET A CHUNK FROM FREELIST
ADD T1,[POINT CK.WID,1] ;MAKE INTO A BYTE POINTER
MOVEM T1,LDBTOT(U)
TYOVR1: MOVEM T1,LDBTOP(U) ;PUT IN TYPEOUT STRING ADDRESSES
SETZM LDBTOC(U) ;MAKE SURE COUNT IS ZERO
POPJ P, ;OUTPUT CHUNK STREAM ALL SET
TYEVRG: SKIPE T1,LDBEOT(U) ;IF ALREADY A GOOD POINTER
JRST TYEVR1 ;DON'T WASTE A GOOD CHUNK
PUSHJ P,GETCKZ ;GET A CHUNK FROM FREELIST
ADD T1,[POINT CK.WID,1] ;MAKE INTO A BYTE POINTER
MOVEM T1,LDBEOT(U)
TYEVR1: MOVEM T1,LDBEOP(U) ;PUT IN ECHO OUTPUT STRING ADDRESSES
SETZM LDBEOC(U) ;MAKE SURE COUNT IS ZERO
POPJ P, ;ECHO CHUNK STREAM ALL SET
TYBVRG: SKIPE T1,LDBOOT(U) ;IF ALREADY A GOOD POINTER
JRST TYBVR1 ;DON'T WASTE A GOOD CHUNK
PUSHJ P,GETCKZ ;GET A CHUNK FROM FREELIST
ADD T1,[POINT CK.WID,1] ;MAKE INTO A BYTE POINTER
MOVEM T1,LDBOOT(U)
TYBVR1: MOVEM T1,LDBOOP(U) ;PUT IN OOB OUTPUT STRING ADDRESSES
SETZM LDBOOC(U) ;MAKE SURE COUNT IS ZERO
HRRZ T3,T1 ;ADDRESS PART OF POINTER
TRZN T3,CK.BDY ;ADDRESS OF CHUNK HEADER MINUS ONE.
SUBI T3,TTCHKS## ;WELL, NOW IT IS
SSX T3,MS.SCN ;SET SECTION NUMBER
HRRZ T1,1(T3) ;ADDRESS OF FIRST CHUNK IN CHAIN TO DELETE
JUMPE T1,TYBVR3 ;IF NULL CHAIN
SETZM 1(T3) ;CLEAR POINTER TO CHAIN BEFORE DELETION
TYBVR2: SSX T1,MS.SCN ;SET SECTION POINTER
HRRZ T3,(T1) ;POINTER TO CHUNK FOLLOWING CURRENT
PUSHJ P,FRECHK ;DELETE ONE CHUNK
MOVEI T1,(T3) ;NEXT CHUNK ON CHAIN
JUMPN T1,TYBVR2 ;LOOP TO END OF CHAIN
TYBVR3: POPJ P, ;OOB CHUNK STREAM ALL SET
;FRECHK and GETCHK are called to return and fetch chunks from the
;SCNSER chunk free chain. The chain is maintained in first-in first-out
;order in order to preserve as much information for crash analysis as
;possible. The oldest chunk is pointed to by TTFTAK, while the youngest
;is pointed to by TTFPUT. To aid in reconstruction of the events
;leading to a crash, the left half of each chunk header contains the LDB
;address of the line that last used it.
GETCKZ: PUSHJ P,GETCHK ;GET A FREE CHUNK
SETZM (T1) ;ZERO THE LINK WORD
HRRZS T1 ;MAKE SECTION RELATIVE ADDRESS
POPJ P, ; AND RETURN
GETCHK: MOVE T1,TTFTAK ;GET NEXT FROM FREE LIST
TRNN T1,-1 ;CHECK IT
STOPCD .,STOP,FLE, ;++FREE LIST EMPTY
PUSH P,T2 ;SAVE T2
HRRZ T2,(T1) ;TO NEXT CHUNK
HRRM T2,TTFTAK ;STORE POINTER TO NEW FIRST CHUNK
SOSN TTFREN## ;COUNT DOWN NUMBER OF FREE CHUNKS
STOPCD .,STOP,EXFCHK ;++EXHAUSTED FREE CHUNKS
JUMPN T2,T2POPJ## ;IF NOT LAST CHUNK, RETURN
MOVEI T2,TTFTAK ;MAKE TTFPUT POINT AT TTFTAK SO
MOVEM T2,TTFPUT ; FRECHK WILL RELINK THE POINTERS CORRECTLY
JRST T2POPJ## ; AND RETURN
FRECHK: SSX T1,MS.SCN ;GET SECTION NUMBER
HRLZM U,(T1) ;MARK LINE NUMBER IN CHUNK
HRRM T1,@TTFPUT ;STORE CHUNK AT END
MOVEM T1,TTFPUT ;POINT TO NEW ENTRY.
AOS TTFREN## ;COUNT UP NUMBER OF CHUNKS
POPJ P,
SUBTTL CHUNK HANDLERS -- CLEAR BUFFERS
;ROUTINES TO CLEAR INPUT AND OUTPUT BUFFERS
TSETBE: SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE2## ;PRESERVE SOME ACS
SETZ P2, ;CLEARING TTY EDITOR
PUSHJ P,SCNEDT ;DO SO
JFCL ;IT SKIPS
;FALL INTO TSETBI
TSETBI::SE1ENT ;ENTER SECTION 1
SKIPN U ;HAVE AN LDB?
STOPCD .,STOP,LNS, ;++LINE NOT SETUP
MOVEI T1,ISRREM ;CODE FOR REMOTE HANDLERS
MOVEI T3,IRRCIB ;ISRREM CODE TO CLEAR INPUT BUFFER
PUSHJ P,@LDBISR(U) ;POKE THE FRONT END
SKIPE LDBEDT(U) ;EDIT BUFFER ENABLED?
PUSHJ P,TYIL ;YES, SAVE THE REST OF THE LINE AWAY
TSETI1: PUSHJ P,STOPCM
SCNOFF
TSETI2: SETZM LDBTIC(U) ;CLEAR COUNTS
SETZM LDBECC(U) ;OF INPUT CHARACTERS
SETZM LDBIIC(U) ;ALSO OF
SETZM LDBIEC(U) ;INVISIBLE CHARACTERS
MOVE T1,LDBTIT(U) ;MOVE PUTTERS BACK TO TAKER
MOVEM T1,LDBTIP(U)
MOVEM T1,LDBECT(U) ;NO ECHOING EITHER
SETZM LDBBKU(U)
SETZM LDBBKI(U)
SETZM LDBBKC(U) ; ..
MOVEI T1,L2RECS ;CLEAR BIT IN LDB WHICH
ANDCAM T1,LDBBY2(U) ; MIGHT CAUSE A LINE TO BE SKIPPED
MOVSI T1,L3LIHD!L3LIPD!L3LEHD!L3LEPD!L3LCHD!L3LCPD ;CHARACTER EXPANSION BITS
ANDCAM T1,LDBBY3(U) ;ABORT 8-BIT CHARACTERS IN PROGRESS
MOVSI T1,L1LQTC!L1LQNC!L1LQCC ;QUOTE IN PROGRESS BITS
ANDCAM T1,LDBBYT(U) ;NOT QUOTING NOW
MOVSI T1,LOLREE ;RE-EAT ECHO
ANDCAM T1,LDBOST(U) ;CLEAR SINCE NONE THERE TO RE-EAT
MOVSI T1,LDLCRP!LDLDIP ;GET ^R SYNCH BITS
ANDCAM T1,LDBDCH(U) ;CLEAR THESE TOO, SINCE ^R WAS TYPEIN
SETZM LDBIST(U) ;RESET INPUT STATE MACHINE
LDB T1,LDPDEM ;RECINT'S DEFERRED ECHO MODE
DPB T1,[POINT 1,LDBBYT(U),^L<(L1LDEM)>] ;KEEP IN SYNCH WITH XMTECH
SCNON
PJRST CHKXON ;CHECK IF AN XON MUST BE SENT OUT AND EXIT
TSETBO::SE1ENT ;ENTER SECTION 1
MOVSI T1,LOLSTP+LOLSSO+LOLREO ;CLEAR OUTPUT STOP AND RE-EAT BITS
ANDCAM T1,LDBOST(U) ;OUTPUT CAN NOW HAPPEN AGAIN
SCNOFF ;NO PI'S HERE
IFN FTMIC&FTMLOG,<
SKIPE LDBLOT(U)
JRST MICLGC
> ;END OF FTMLOG CONDITIONAL
SETZM LDBTOC(U) ;NO OUTPUT CHARACTERS LEFT
MOVE T1,LDBTOT(U) ;PUT PUTTER BACK AT TAKER
MOVEM T1,LDBTOP(U) ; ..
HRRZ T3,T1 ;ADDRESS PART OF POINTER
TRZN T3,CK.BDY ;ADDRESS OF CHUNK HEADER MINUS ONE.
SUBI T3,TTCHKS## ;WELL, NOW IT IS
SSX T3,MS.SCN ;SET SECTION NUMBER
HRRZ T1,1(T3) ;ADDRESS OF FIRST CHUNK IN CHAIN TO DELETE
JUMPE T1,TSETB2 ;IF NULL CHAIN
SETZM 1(T3) ;CLEAR POINTER TO CHAIN BEFORE DELETION
TSETB1: SSX T1,MS.SCN ;SET SECTION POINTER
HRRZ T3,(T1) ;POINTER TO CHUNK FOLLOWING CURRENT
PUSHJ P,FRECHK ;DELETE ONE CHUNK
MOVEI T1,(T3) ;NEXT CHUNK ON CHAIN
JUMPN T1,TSETB1 ;LOOP TO END OF CHAIN
TSETB2: MOVSI T1,L2LDEL!L2LCCS ;SOME CRUFTY BITS
ANDCAM T1,LDBBY2(U) ;CLEAR THEM
MOVSI T1,L3LOHD!L3LOPD!L3LFHD!L3LFPD ;CHARACTER EXPANSION BITS
ANDCAM T1,LDBBY3(U) ;CLEAR 8-BIT CHARACTERS IN PROGRESS
SCNON ;ALL'S CLEAR NOW
MOVEI T3,IRRSCG ;ISR CODE FOR CHAR GOBBLER
MOVEI T1,ISRREM ;SPECIAL ISR ENTRY FOR REMOTES
PJRST @LDBISR(U) ;SEND MESSAGE TO CLEAR OUTPUT BUFFER IN REMOTE
SUBTTL UUO LEVEL ROUTINES FOR BUFFERED I/O
;DISPATCH TABLE FOR UUO'S AND INITIALIZATION
JRST ECOD2## ;NO DEVOP FUNCTIONS
JRST REGSIZ## ;BUFFER SIZE CAN BE GOTTEN FROM DDB
JRST TTYINI ;INITIALIZATION
JRST CPOPJ1## ;HUNG DEVICE (NEVER USED)
SCNDSP::JRST TTYREL ;RELEASE
JRST OUT## ;CLOSE OUTPUT
JRST TTYOUT ;TTY OUTPUT UUO
; JRST TTYIN ;TTY INPUT UUO
;FALL INTO TTYIN
;INPUT UUO PROCESSOR - CALLED FROM UUOCON ON INPUT UUO, DDB SET UP
TTYIN: SE1ENT ;ENTER SECTION 1
HRRZS F ;CLEAR LEFT HALF BITS (I/O OPERATIONS DONE SO FAR)
PUSHJ P,SAVE3## ;SAVE P1-P3
PUSHJ P,CKATTI ;MAKE SURE ATTACHED. SET S.
TRNN S,I ;IMAGE MODE?
JRST TTYIN0 ;NO. SKIP SETUP STUFF
TRNN S,IODERR ;EOF DUE TO ^C ON UNATTACHED LINE?
TLNE S,FRCEND ;CLOCK ROUTINE WANT IT FINISHED?
JRST TTYIN9 ;YES. GO DO SO.
MOVE T1,DEVMOD(F) ;IS THIS GUY ALLOWED IMAGE MODE INPUT?
TRNN T1,ASSCON ;I.E., HE HAS TERMINAL ASSIGNED?
JRST TTYINE ;NO. ERROR BIT TO USER.
MOVSI T1,LDLIMI ;YES. SET IMAGE INPUT IN LINE DATA
IORM T1,LDBDCH(U) ; ..
PUSHJ P,SETCHP ;MAKE SURE THAT THE FRONT END KNOWS
TTYIN0: MOVEI T1,DEPAIO ;IS THIS TERMINAL IN ASYNC INPUT
TDNN T1,DEVAIO(F) ; MODE?
JRST TTYINA ;NO--FORGE AHEAD
PUSHJ P,TTICHK ;IS THERE ANY INPUT AVAILABLE?
POPJ P,0 ;NO--RETURN NOW
TTYINA: MOVSI T1,L1LUNR ;UNREAD WAITING BIT
TDNN T1,LDBBYT(U) ;DON'T BLOCK DURING UNREAD
PUSHJ P,TWAITI ;BECOME ATTACHED, WAIT FOR INPUT
; OR FULL BUFFER CONDITION
TLNE S,FRCEND ;DID WE TIME OUT AT CLOCK
JRST TTYIN9 ;LEVEL WHILE WAITING ?
TTYIN5: HRRZ T1,DEVIAD(F) ;PREPARE AND ADDR CHECK THE
PUSHJ P,BUFCLR## ; USER'S BUFFER
JRST ADRERR## ;OUT OF BOUNDS. STOP JOB.
HRRZ P1,DEVIAD(F) ;USER VIRTUAL ADDRESS OF BUFFER
EXCTUX <LDB P2,[POINT 17,(P1),17]> ;SIZE OF BUFFER (DATA + 1)
SUBI P2,1 ;LESS THE .BFCNT WORD
MOVE U,DDBLDB(F) ;RESTORE LINE, CLOBBERED IN UUOCON
PUSHJ P,SRLPTR ;SETUP BYTE COUNT AND POINTER
PUSH P,P2 ;SAVE BYTE COUNT
;FALL INTO MAIN PART OF ROUTINE
TTYIN1: PUSHJ P,TYICC ;GET A CHARACTER
JRST TTYIN3 ; END OF BUFFER.
MOVE P3,T3 ;COPY CHARACTER
ANDI P3,CK.CHR ;STRIP IMAGE BIT
EXCTUU <IDPB P3,P1> ;AND STORE IN USER AREA
TRNN S,I!PIMMOD ;SKIP IF IMAGE MODE OF SOME SORT
JRST TTYIN2 ;NO, ASCII MODE
SOJG P2,TTYIN1 ;YES, JUST FILL BUFFER
JRST TTYIN3 ;BUFFER FULL, GIVE IT TO THE USER
TTYIN2: TLNE T1,CHBRK ;A BREAK?
SOSA P2 ;YES, COUNT IT AND TERMINATE
SOJG P2,TTYIN1 ;NO. LOOP FOR MORE, IF ROOM.
MOVSI S,IOEND ;COUNTED OUT, OR BREAK.
MOVE T1,DEVIOS(F) ;GET USER MODE BITS
TRNN T1,IOSTEC ;TRUTH-IN-ECHOING MODE AND
CAIE P3,"Z"-100 ;END OF FILE CHARACTER?
MOVEI S,0 ;NO. NOT EOF.
IORB S,DEVIOS(F) ;STORE IN DDB S WORD
TTYIN3: POP P,T1 ;GET BACK ORIGINAL MAX BYTE COUNT
TRNN S,PIMMOD!A8 ;BYTE COUNT IF PIM OR 8-BIT
SKIPA P2,DEVIAD(F) ;NOT PIM - BUFFER PTR IN P2
SKIPA ;PIM - DON'T DESTROY BYTE COUNT
JRST TTYINC ;NOT PIM-WORD COUNT
MOVN P1,P2 ;COUNT OF BYTES LEFT
ADD P1,T1 ;FROM MAX = COUNT OF BYTES DEPOSITED
SKIPA P2,DEVIAD(F) ;ALREADY HAVE COUNT IN P1
TTYINC: SUBI P1,1(P2) ;COMPUTE WORD COUNT FOR UUOCON
EXCTUU <HRRM P1,1(P2)> ;STORE WITH DATA IN RING
SKIPN P1 ;DID WE RETURN AN EMPTY BUFFER?
PUSHJ P,CLRUNR ;YES - DONE WITH UNREAD
PUSHJ P,ADVBFI## ;ON TO NEXT BUFFER
JRST TTYIN8 ;NO MORE BUFFERS AVAILABLE
TRNE S,I!PIMMOD ;IMAGE MODE?
SKIPG LDBTIC(U) ;AND MORE CHARACTERS TO READ?
JRST TTYIN8 ;NO - ASCII, ONLY PASS ONE LINE AT A TIME
JRST TTYIN5 ;YES. GO PASS SOME MORE
TTYIN8: MOVSI S,IOFST ;SET VIRGIN BUFFER BIT
TTYINX: IORB S,DEVIOS(F) ;IN DEV S WORD IN DDB
MOVE U,DDBLDB(F)
JUMPE U,CPOPJ##
PJRST NOCTRO ;CLEAR CONTROL O. END OF UUO
;HERE IF ATTEMPT TO PUT UNASSIGNED TERMINAL IN IMAGE INPUT STATE
TTYINE: MOVEI S,IOIMPM
JRST TTYINX ; AND RETURN
TTYIN9: MOVSI S,IOEND ;SET END OF FILE BIT IN S
JRST TTYINX
;OUTPUT UUO CALLS HERE
;CALLED ON OUTPUT OR OUTPUT CLOSE, FROM UUOCON, WITH DDB SET UP.
TTYOUT: SE1ENT ;ENTER SECTION 1
HRRZS F ;CLEAR LEFT HALF (I/O OPERATIONS DONE SO FAR)
PUSHJ P,SAVE2## ;SAVE P1-P2
IFN FTRSP,<PUSHJ P,RSPTOR##> ;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
TRNE S,IODERR ;^C TYPED AT TTYNNN
JRST TTOUT3 ;YES, RETURN
PUSHJ P,CKATOU ;FIRST, MAKE SURE THERE'S A
; PHYSICAL LINE ATTACHED TO JOB, AT USER LEVEL
TRNN S,I ;UNLESS IMAGE MODE,
PUSHJ P,CLRIMI ;CLEAR IMAGE INPUT STATE
MOVSI S,IOBEG ;IS THIS THE FIRST BUFFER AFTER INIT?
TDNN S,DEVIOS(F) ;CHECK DDB
JRST TTOUT1 ;NO.
ANDCAM S,DEVIOS(F) ;YES. CLEAR BEG BIT,
PUSHJ P,NOCTRO ; AND CONTROL O
TTOUT0: SETZM DEVSTS(F) ;CLEAR OLD PARTIAL BYTE POINTER IF ANY
;OUTPUT A BUFFER OF TEXT. AT THIS POINT WE COULD CHECK FOR ^O IN EFFECT
;AND JUST EAT THE BUFFER, BUT WE DON'T WANT ^O TO BE TOO FAST . . .
TTOUT1: MOVE S,[IO!IOFST,,IOACT] ;MARK START OF NEW OUTPUT
IORB S,DEVIOS(F) ;IN DEVICE DATA BLOCK
HRRZ P1,DEVOAD(F) ;USER VIRTUAL ADDRESS OF OUTPUT BUFFER
HRRZ T1,P1 ;CHECK ADDRESSES OF OUTPUT BLOCK
PUSHJ P,BRNGE## ;MAKE SURE BUFFER IS ADDRESSABLE
EXCTUX <HRRZ P2,1(P1)> ;SIZE OF DATA AREA (WORDS) TO BE OUTPUT
JUMPE P2,TTOUT6 ;SKIP THIS BUFFER IF EMPTY
EXCTUX <LDB T1,[POINT 17,(P1),17]> ;GET TOTAL BUFFER SIZE
MOVE T4,P2 ;SAVE BYTE/WORD COUNT
TRNN S,PIMMOD!A8 ;OR NOT IN PACKED IMAGE MODE OR 8-BIT MODE?
TDZA T4,T4 ;YES, INDICATE USE WORD COUNT
LSH T1,2 ;ELSE, FOUR BYTES PER WORD
CAML P2,T1 ;DATA CONTAINED WITHIN BUFFER?
JRST TTYINE ;NO, USER BLEW IT
; (IT ALSO MIGHT IME US!)
PUSHJ P,SRLPTR ;GET BYTE COUNT AND POINTER
SKIPE T4 ;WAS THERE AN EXACT BYTE COUNT?
MOVE P2,T4 ;YES, USE IT INSTEAD
SKIPN DEVSTS(F) ;OUTPUT PENDING?
JRST TTOUT2 ;NO, NEW BUFFER
MOVE P1,DEVSTS(F) ;YES, GET LAST OUTPUT POINTER
LDB P2,BYTCNT ;AND REMAINING BYTE COUNT
; AND FINISH (MAYBE) OUTPUTTING THE BUFFER
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;LOOP OUTPUTTING CHARACTER FROM THE USER BUFFER
TTOUT2: PUSHJ P,CKROOM ;SEE IF WE SHOULD CALL TYO
JRST TTOUT7 ;IO WAIT WOULD HAPPEN
MOVE T3,P1 ;COPY BYTE POINTER
EXCTUX <ILDB T3,T3> ;INCREMENT THIS COPY, GET USER'S CHAR
ANDI T3,CK.CHR ;KEEP JUST THE CHARACTER
TRNE S,I!PIMMOD ;SEE IF IMAGE MODE OR PIM
TRO T3,CK.IMG ;YES. SET BIT FOR SUPPRESSING FILLERS
TRNN S,I!PIMMOD!A8 ;IF 7-BIT ASCII,
JUMPE T3,TTOUT4 ;DON'T OUTPUT NULLS
MOVEI T1,DEPAIO ;IF DOING ASYNCHRONOUS I/O,
TDNE T1,DEVAIO(F) ; TELL TYO NOT TO BLOCK SINCE
TLO T3,(1B0) ; WE MAY BE HERE FORM TTMORE
TRNE S,IODERR ;^C TYPED ON TTYNNN
JRST TTOUT3 ;YES, RETURN
PUSHJ P,TYO9W ;OUTPUT THIS CHARACTER (WAIT IF NEEDED)
JUMPL T3,TTOUT7
TTOUT4: IBP P1
SOJG P2,TTOUT2 ;COUNT USER'S ITEMS.
TTOUT6: PUSHJ P,ADVBFO## ;ADVANCE HIS BUFFERS
JRST TTOUT3 ;JUST SINGLE BUFFER FOR NOW
MOVEI T1,DEPAIO ;NON-BLOCKING I/O BIT
TDNE T1,DEVAIO(F) ;DOING NON-BLOCKING I/O
JRST TTOUT0 ;YES, START THE NEXT BUFFER OUT
TTOUT3: SETZM DEVSTS(F)
MOVEI S,IOACT ;CLEAR ACTIVE BIT.
ANDCAB S,DEVIOS(F) ;IN DEVICE DATA BLOCK FOR THE JOB
POPJ P,0 ;END OF UUO. RETURN TO USER
TTOUT7: MOVEM P1,DEVSTS(F) ;SAVE THE INTERRUPTED BYTE POINTER
DPB P2,BYTCNT ; AND ITS COUNTER
TTOUT8: MOVEI T1,JS.NTO ;SET THE MAGIC
IORM T1,JBTSTS##(J) ; BIT IN JBTSTS
MOVEI S,IOACT ;CLEAR I/O ACTIVE BIT
ANDCAB S,DEVIOS(F) ;..
POPJ P,0 ;RETURN
TTMORE::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE2## ;SAVE P1-P2
HLRZ F,SCNDDB+DEVSER ;FIRST REAL DDB
MOVEI P2,JS.NTO ;FLAG RESET
MORE10: LDB T1,PJOBN## ;GET OWNER
CAIN T1,(J) ;IS IT THIS JOB?
SKIPN DEVSTS(F) ;IS OUTPUT WAITING?
JRST MORE20 ;NO, TRY NEXT DDB
MOVEI T1,DEPAIO
TDNN T1,DEVAIO(F) ;NON-BLOCKING I/O ON THIS TERMINAL?
JRST MORE20 ;NO, LOOK AT OTHER TERMINALS
PUSHJ P,MORE30 ;GO TRY OUTPUT
MOVEI P2,0 ;FLAG ONE ACTIVE
MORE20: HLRZ F,DEVSER(F) ;PICK UP NEXT DDB
MOVSI T1,DVTTY ;IS THIS A TTY?
TDNE T1,DEVMOD(F) ; ..
JUMPN F,MORE10 ;YES--LOOK AT IT TOO
ANDCAM P2,JBTSTS##(J) ;CLEAR THE STATUS
POPJ P,0 ;RETURN
MORE30: MOVE U,DDBLDB(F) ;GET ADDRESS OF LDB
JUMPE U,CPOPJ## ;PUNT IF DETACHED
MOVE S,DEVIOS(F) ;SET UP S FOR TYO
PUSHJ P,SSPCS## ;SAVE PCS
PUSHJ P,SPCS## ;SETUP PCS BASED ON DEVISN IN THIS DDB
LDB P1,BYTCNT ;GET THE BYTE COUNT
JUMPE P1,MORE41 ;IF BYTE COUNT=0 AND DEVSTS NON-0, BUFFER WASN'T ADVANCED
; BECAUSE WHAT DEVOAD POINTED TO WAS PAGED OUT
MORE40: PUSHJ P,CKROOM ;ROOM FOR MORE DATA?
JRST [DPB P1,BYTCNT ;NO--SAVE BYTE COUNT
POPJ P,0] ;RETURN
MOVE T1,DEVSTS(F) ;GET POINTER
IBP T1 ;UPDATE POINTER
MOVE T3,T1
TLZ T1,-1 ;CLEAR JUNK
PUSHJ P,IADRCK## ;MAKE SURE ITS LEGAL AND IN CORE
JRST MORE50
JRST MORE50
EXCTUX <LDB T3,T3> ;GET NEXT BYTE
ANDI T3,CK.CHR ;DON'T ALLOW USER TO GIVE US META-CHARACTERS
TRNE S,I!PIMMOD ;IF IMAGE OR PIM
TRO T3,CK.IMG ;FLAG IT
TRNN S,I!PIMMOD!A8 ;IF 7-BIT ASCII
JUMPE T3,MOR405 ;DON'T TYPE NULLS
TLO T3,(1B0) ;DON'T BLOCK IN TYO
PUSHJ P,TYO9W ;TYPE IT
JUMPGE T3,MOR405 ;PROCEED IF CHAR OUTPUT
DPB P1,BYTCNT ;ELSE REMEMBER WHERE
JRST TTOUT8 ;WE WERE & RETURN
MOR405: IBP DEVSTS(F) ;INCREMENT PRIME COPY
SOJG P1,MORE40 ;DO THE NEXT BYTE
MORE41: HRRZ T1,DEVOAD(F) ;BUF APR
SOS T2,T1 ;WORD-1
ADDI T2,3 ;THRU WORD1
PUSHJ P,ZRNGE## ;IN CORE?
JRST MORE50 ;NO
TLO S,IO ;FORCE FLAG TO OUTPUT
PUSHJ P,PSIIOD##
JRST TTOUT6 ;ALL DONE
MORE50: MOVEI M,(T1) ;FOR ROUTINE (PCS DOES SECTION WORK)
PUSHJ P,PFHGWD## ;TRY TO FAULT IT INTO CORE
JRST UADERR## ;BOMB USER IF CAN'T
JUMPN P1,MORE40 ;CONTINUE IF JUST WANTED A BYTE
HRRI M,3(M) ;NO, BUMP PAST HEADER
PUSHJ P,PFHGWD## ;MAKE SURE THIS IS ALSO IN CORE
JRST UADERR## ;BOMB USER IF NOT A VALID ADDRESS
JRST MORE41 ;GO ADVANCE BUFFER NOW
CKROOM: MOVEI T1,DEPAIO ;IF THIS JOB IS NOT USING
TDNN T1,DEVAIO(F) ; ASYNCHRONOUS I/O THEN
JRST CPOPJ1## ; JUST GIVE THE SKIP RETURN
SKIPLE T1,TTFREN## ;GET THE FREE CHUNK COUNT
CAIG T1,5 ;ENOUGH ROOM?
POPJ P,0 ;NO--QUIT NOW
MOVE T1,LDBTOC(U) ;GET OUTPUT BYTE COUNT
ADDI T1,^D25 ;REDUCE ODDS OF LOSSAGE
CAMG T1,TIWRNN ;TOO MUCH STUFF?
AOS (P) ;NO--CALL TYO
POPJ P,0 ;RETURN
SUBTTL DDT MODE CALLI'S
;INPUT TO DDT - CALL AC,[SIXBIT /DDTIN/] WHERE AC/ ADDR
;ADDR GETS UP TO 21 WORDS OF ASCIZ, BREAKING ON ANY CHARACTER
DDTIN:: PUSHJ P,SAVE3## ;SAVE P1-P3 (TYICC KRUMPS P3)
PUSHJ P,TTYFNU ;SET LINE AND DDB FOR THIS TTY
PUSHJ P,CKATTI ;MAKE SURE TERMINAL ATTACHED
PUSHJ P,GETWDU## ;DO ADDRESS CHECKING FIRST
HRRZS P1,T1 ;GET AND SAVE STARTING ADDRESS OF AREA
HRLI T1,(IFIW) ;OLD-STYLE UUO USES SECTION RELATIVE ADDRESSING
MOVEI T2,21 ;WORD COUNT
PUSHJ P,ARNGE## ;RANGE CHECK
JRST UADERR## ;ADDRESS CHECK
JRST UADERR## ;ADDRESS OK BUT ILLEGAL FOR I/O
HRLI P1,440700 ;SEVEN BIT BYTES, RELOCATED.
MOVEI P2,<21*5>-1 ;NUMBER OF BYTES ALLOWED
PUSHJ P,TWAITC ;GET AT LEAST ONE CHARACTER
DDTINL: SKIPG LDBTIC(U) ;ANY MORE TO COME?
JRST DDTINX ;NO.
PUSHJ P,TYICC ;YES. GO GET ONE
JRST DDTINX ;WASNT ANY. I'M CONFUSED.
TRNE T3,CK.CH7 ;NULL?
EXCTUU <IDPB T3,P1> ;NO. STORE IN USER AREA
SOJG P2,DDTINL ;IF MORE SPACE, GET ANOTHER CHARACTER
DDTINX: MOVEI T3,0 ;FLAG END OF STRING
EXCTUU <IDPB T3,P1> ; IN USER AREA
PJRST NOCTRO ;AND RETURN TO USER, CLEARING ^O FLAG
;DDTOUT - CALL AC,[SIXBIT /DDTOUT/], AC/ ADDR, ADDR/ ASCIZ /XXX/
DDTOUT::HRR M,T1 ;USER ADR. OF TEXT TO M
PUSHJ P,TTYFNU ;GET USER'S CONSOLE
PUSHJ P,CKATOU ;MAKE SURE AT USER LEVEL AND ATTACHED
JRST OUTSTR ;SAME AS THE CORRESPONDING TTCALL
SUBTTL TTCALL AND TRMOP. -- TTCALL DISPATCH
;TTCALL AC,E - VALUE OF AC DETERMINES ACTION OF UUO (051)
TTYUUO::PUSHJ P,SAVE2## ;SAVE P1,P2
PUSHJ P,TTYFNU ;FIND CURRENT USER'S TTY
MOVE P2,TTUUOT(P1) ;GET PRE-CHECK BITS
TLNE P2,TC.ATW ;ATTACH OR WAIT?
PUSHJ P,CKATTO ;YES. WAIT TILL ATTACHED
TLNN P2,TC.ATR ;ATTACH OR RETURN?
JRST TTUUB ;NO
JUMPE U,CPOPJ ;GO AWAY IF NO TERMINAL LINE
TTUUB: JUMPE U,TTUUD ;ONE UUO-GETLCH-CAN BE HERE DETACHED
MOVE T1,LDBDCH(U) ;GET LINE DESCRIPTION
TLNN P2,TC.USR ;USER OR RETURN?
JRST TTUUC ;NO
TLNE T1,LDLCOM ;YES. USER LEVEL?
POPJ P,0 ;NO. RETURN.
TTUUC: TLNE P2,TC.USW ;USER OR WAIT?
TLNN T1,LDLCOM ;YES. AT USER LEVEL
JRST TTUUD ;USER LEVEL, OR NOT NEEDED
PUSHJ P,CKATOU ;TOP LEVEL.WAIT FOR USER.
JRST TTYUUO ;RESTART UUO IN CASE OF
;ATTACH.
TTUUD: TLNN P2,TC.ADC ;ADDRESS CHECK NEEDED?
JRST TTUUE ;NO. GO DISPATCH.
HRRZ T1,M ;ADDRESS TO P1, WHICH IS P1
PUSHJ P,UADCK1## ;CHECK THE ADDRESS
TTUUE: TLNE P2,TC.ECS ;INPUT OPERATION?
PUSHJ P,TYIEAT ;YES, EAT COMMAND IF LEFT OVER
SSX P2,MCSEC1 ;ISOLATE DISPATCH ADDRESS
JRST (P2) ;DISPATCH TO ROUTINE
;THE FOLLOWING TABLE IS USED TO PRE-CHECK AND DISPATCH THE TTCALL'S.
;BITS IN THE LEFT ARE CHECKED BEFORE DISPATCHING.
;INDIRECT AND INDEX MUST BE ZERO, FOR JRST INDIRECT, BUT THIS COULD
;EASILY BE CHANGED IF THE BITS RUN OUT.
TC.ADC==400000 ;THIS FUNCTION MUST BE ADDRESS CHECKED
TC.USR==200000 ;THIS FUNCTION MUST BE AT USER LEVEL, ELSE POPJ
TC.USW==100000 ;THIS FUNCTION MUST BE AT USER LEVEL, ELSE WAIT
TC.ATW==040000 ;THIS FUNCTION MUST BE ATTACHED, ELSE WAIT
TC.ATR==020000 ;THIS FUNCTION MUST BE ATTACHED, ELSE POPJ
TC.ECS==010000 ;EAT COMMAND SYNC (CALL TYIEAT)
;DON'T ASSIGN BITS 13-17 WITHOUT CHANGING DISPATCH CODE
TTUUOT: XWD TC.ATW+TC.USW+TC.ADC+TC.ECS,INCHRW ;(00) INPUT CHARACTER, WAIT
XWD TC.ATW+TC.USW,ONEOUT ;(01) OUTPUT CHARACTER
XWD TC.ATR+TC.USR+TC.ADC+TC.ECS,INCHRS ;(02) INPUT CHARACTER, SKIP
XWD TC.ATW+TC.USW,OUTSTR ;(03) OUTPUT AN ASCIZ STRING
XWD TC.ATW+TC.USW+TC.ADC+TC.ECS,INCHWL ;(04) INPUT CHARACTER, WAIT LINE MODE
XWD TC.ATR+TC.USR+TC.ADC+TC.ECS,INCHSL ;(05) INPUT CHARACTER, SKIP LINE MODE
XWD TC.ADC,GETLIN ;(06) GET LINE CHARACTERISTICS
XWD TC.ATW+TC.ADC,SETLIN ;(07) SET LINE CHARACTERISTICS
XWD TC.ATR,TRESCU ;(10) RESCAN COMMAND LINE
XWD TC.ATR,TSETBI ;(11) CLEAR INPUT BUFFER
XWD TC.ATR,TSETBO ;(12) CLEAR OUTPUT BUFFER
XWD TC.ATR+TC.USR+TC.ECS,SKPINC ;(13) SKIP IF A CHAR TO BE INPUT
XWD TC.ATR+TC.USR+TC.ECS,SKPINL ;(14) SKIP IF A LINE TO BE INPUT
XWD TC.ATW+TC.USW,IONEOU ;(15) IMAGE ONE-CHARACTER OUTPUT
XWD 0,CPOPJ## ;(16) NOT IMPLEMENTED
XWD 0,CPOPJ## ;(17) NOT IMPLEMENTED
SUBTTL TTCALL AND TRMOP. -- OUTCHR AND IMAGE OUTCHR
;ONEOUT OUTPUTS ONE CHARACTER FROM C(E)
ONEOUT: PUSHJ P,SAVE2## ;SAVE P2
SKIPN F ;ANY DDB?
SKIPA P2,[CCTYO] ;NO--MUST BE SLOPPY
MOVEI P2,TYO7W ;YES--BE NEAT
IFN FTRSP,<PUSHJ P,RSPTOR##> ;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
ONEOU1: PUSHJ P,GETWDU## ;PICK UP USER'S WORD
MOVE T3,T1 ;PUT IN RIGHT AC
ANDI T3,CK.CHR ;MASK OUT ANY JUNK
MOVSI T1,LDL8BI ;8-BIT I/O
TDNN T1,LDBDCH(U) ;USER SET .IOAS8?
ANDI T3,CK.CH7 ;NO, KEEP ONLY 7-BIT
JUMPE T3,CPOPJ## ;IF NOT NULL,
PJRST (P2) ;TYPE OUT, WAIT IF NEEDED
;IONEOU OUTPUTS ONE CHARACTER FROM LOW 8 BITS OF C(E)
IONEOU:
IFN FTRSP,<PUSHJ P,RSPTOR##> ;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
PUSHJ P,CLRIIQ ;NOT IN INPUT WAIT ANY MORE
JUMPE F,ONEOU1 ;IF NO DDB, SEND 7 BITS
PUSHJ P,GETWDU## ;GET USER'S DATUM
HRRZ T3,T1 ;INTO RIGHT AC
ANDI T3,CK.CHR ;IGNORE POSSIBLE GARBAGE
TRO T3,CK.IMG ;FLAG AS IMAGE CHARACTER (NO FILLER)
PJRST TYO9W ;SEND IMAGE CHARACTER (WAIT IF NEEDED)
SUBTTL TTCALL AND TRMOP. -- OUTSTR AND RESCAN
;OUTSTR OUTPUTS A STRING OF ASCIZ CHARACTERS
OUTSTR:
IFN FTRSP,<PUSHJ P,RSPTOR##> ;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
PUSHJ P,SAVE4## ;SAVE P1-P4
MOVEI P3,TYO7W
OUTST3: LDB T1,[POINT 9,M,26] ;PAGE #
PUSHJ P,TPSHS## ;IS PAGE SHARED?
JRST OUTST6 ;YES -- JUST USE
HRROI T1,(M) ;LEFT JUSTIFIED ASCIZ STRING
PUSHJ P,CKSTR## ;MAKE SURE ITS IN CORE AND LEGAL
JRST UADERR## ;ADDRESS CHECK
OUTST6: HRRI M,-1(M) ;COMPENSATE FOR GETWD1
OUTST5: MOVEI P4,200 ;MAXIMUM # OF WORDS IN ONE SHOT
OUTST2: MOVE P1,[POINT 7,P2] ;PREPARE TO READ BYTES
PUSHJ P,GETWD1## ;GET A USER'S WORD
MOVE P2,T1 ;PUT WORD IN A SAFE AC
OUTST1: TLNN P1,760000 ;ANY BYTES LEFT?
JRST OUTST4 ;NO. GET ANOTHER WORD
ILDB T3,P1 ;YES. GET ONE
JUMPE T3,CPOPJ## ;NULL MARKS END OF STRING
HLL T3,P3 ;PROPAGATE SIGN-BIT STATE
PUSHJ P,(P3) ;TYPE OUT CHARACTER
JRST OUTST1 ;AND GO BACK FOR MORE.
OUTST4: SOJG P4,OUTST2 ;GO BACK FOR MORE. IS MESSAGE LONG?
PUSHJ P,SCDCHK## ;GIVE THE REST OF THE WORLD A CHANCE
JRST OUTST5
;TRESCU IS RESCAN FUNCTION FOR PROGRAM TO READ COMMAND THAT STARTED IT
TRESCU: MOVE T2,LDBBY2(U) ;SAVE OLD BIT FOR TEST
MOVEI T1,L2RECS ;CLEAR BIT IN LINE DATA BLOCK WHICH
ANDCAM T1,LDBBY2(U) ; WOULD CAUSE COMMAND TO BE SKIPPED
TDNN T2,T1 ;SEE IF ANYTHING THERE
TRNN M,1 ;NO--SEE IF USER WANTS TO KNOW
POPJ P,0 ;NO--JUST RETURN
JRST CPOPJ1## ;YES--GIVE SKIP RETURN
SUBTTL TTCALL AND TRMOP. -- TRMOP. UUO FUNCTION .TOISO (IMAGE STRING OUTPUT)
; OUTPUT A FIXED LENGTH STRING OF CHARACTERS IN IMAGE MODE
; CALL: MOVE AC,[4,,ARG]
; TRMOP. AC,
; <ERROR RETURN>
; <NORMAL RETURN>
;
; ARG: EXP .TOISO/.TOASO
; EXP UDX
; XWD BYTE-SIZE,BYTE-COUNT
; EXP STRING-ADDRESS
;
TOPASO: TDZA T4,T4 ;KEEP TRACK OF ENTRY POINT
TOPISO: MOVEI T4,CK.IMG ;DITTO
PUSHJ P,SAVE4## ;SAVE ACS P1-P4
FRAME <ISOFLG,ISOBPW,ISOCNT,ISOWRD> ;ALLOCATE STACK STORAGE
PUSHJ P,GETWRD## ;GET BYTE SIZE,,BYTE COUNT
JRST TOPX3 ;ADDRESS CHECK
HRRZ P1,T1 ;GET THE BYTE COUNT
JUMPE P1,CPOPJ1## ;RETURN IF NO CHARACTERS TO OUTPUT
HLRZ T2,T1 ;GET BYTE SIZE
CAIL T2,^D1 ;CHECK BYTE SIZE
CAILE T2,^D36 ;1 TO 36 BIT BYTES ARE OK
JRST TOPX10 ;ALL OTHERS ARE NO GOOD
MOVE P3,[POINT 0,ISOWRD] ;START TO BUILD BYTE POINTER
DPB T2,[POINT 6,P3,11] ;STORE THE BYTE SIZE
MOVEI T1,^D36 ;BITS PER WORD
IDIVI T1,(T2) ;GET BYTES PER WORD
MOVEM T4,ISOFLG ;SAVE FLAG BIT FOR CHARACTER TYPER
MOVEM T1,ISOBPW ;SAVE BYTES PER WORD FOR LATER
MOVEI T1,200 ;COUNT OF WORDS TO PROCESS BEFORE RESCHEDULE
MOVEM T1,ISOCNT
PUSHJ P,GETWR1## ;GET ADDRESS OF STRING TO OUTPUT
JRST TOPX3 ;ADDRESS CHECK
MOVEI M,-1(T1) ;SET UP SUBSEQUENT CALLS TO GETWR1
IFN FTRSP,<
HRRZ T1,TTYTAB##(J) ;GET CONTROLLING TTY DDB
CAIN T1,(F) ;IS THIS IT?
PUSHJ P,RSPTOR## ;YES--RECORD RESPONSE SATISFIED BY TTY OUTPUT
>
; JRST IMGSTR ;GO OUTPUT THE STRING
; HERE TO OUTPUT THE STRING IN IMAGE MODE
; FRAME ON PDL:
; ISOFLG - CK.IMG OR ZERO FOR MARKING CHARACTER IN CHUNKS
; ISOBPW - BYTES PER WORD
; ISOCNT - COUNT OF WORDS PROCESSED BEFORE RESCHEDULING JOB
; ISOWRD - WORD STORAGE
; AC: P1 - BYTE COUNT
; P2 - WORKING BYTE POINTER
; P3 - ORIGINAL BYTE POINTER
; P4 - CHARACTER COUNT PER WORD
;
IMGSTR: MOVE T1,P3 ;GET BYTE POINTER
TLZ T1,(@(17)) ;CLEAR OUR INDEXING AND INDIRECTION
HRRI T1,(M) ;GET USER ADDRESS OF START OF STRING
MOVE T2,P1 ;GET NUMBER OF BYTES IN STRING
PUSHJ P,PRNGE## ;RANGE CHECK
JRST TOPX3 ;ADDRESS CHECK
JFCL ;ADDRESS OK BUT IGNORE ILLEGAL FOR I/O
IMGS1: SOSLE ISOCNT ;COUNT WORDS PROCESSED
JRST IMGS2 ;GET MORE TEXT
MOVEI T1,200 ;GET WORD COUNT
MOVEM T1,ISOCNT ;RESET IT
PUSHJ P,SCDCHK## ;GIVE SOMEONE ELSE A CHANCE TO RUN
IMGS2: MOVE P2,P3 ;RESET BYTE POINTER
MOVE P4,ISOBPW ;RESET BYTES PER WORD
PUSHJ P,GETWR1## ;GET A WORD OF TEXT
JRST TOPX3 ;ADDRESS CHECK
MOVEM T1,ISOWRD ;SAVE IT
IMGS3: SOJL P1,CPOPJ1## ;COUNT BYTES, RETURN WHEN DONE
ILDB T3,P2 ;GET A CHARACTER
ANDI T3,CK.CHR ;FEND OFF SMART-ALECKS WITH CK.MET LIT
TDO T3,ISOFLG ;FLAG AS IMAGE IF .TOISO FUNCTION
PUSHJ P,TYO9W ;OUTPUT IT
SOJG P4,IMGS3 ;COUNT BYTES IN THIS WORD
JRST IMGS1 ;GET ANOTHER WORD OF TEXT
SUBTTL TTCALL AND TRMOP. -- TRMOP. UUO FUNCTION .TOFLM (FORCE LEFT MARGIN)
; FORCE TERMINAL TO LEFT MARGIN IF NOT ALREADY THERE
; CALL: MOVE AC,[2,,ARG]
; TRMOP. AC,
; <ERROR RETURN>
; <NORMAL RETURN>
;
; ARG: EXP .TOFLM
; EXP UDX
;
TOPFLM: MOVE T3,[1B0!MC.FLM] ;CHARACTER TO FORCE LEFT MARGIN
PUSHJ P,CCTYO8 ;TRY TO TYPE IT
JUMPGE T3,CPOPJ1## ;WIN IF TYPED
PUSHJ P,OUTSTS ;SLEEP FOR A TICK
JRST TOPFLM ;AND TRY AGAIN
SUBTTL TTCALL AND TRMOP. -- SKPINL AND SKPINC
;SKIP IF A LINE MAY BE INPUT
SKPINL: PUSHJ P,TYIEAT ;MAKE SURE NOT FAKED BY COMMAND
PUSHJ P,NOCTRO ;CLEAR THE ^O BIT
PJRST TTLCHK ;CHECK FOR LINE READY
; AND RETURN SKIP/NON-SKIP
;SKIP IF A CHARACTER MAY BE INPUT
SKPINC: PUSHJ P,TYIEAT ;MAKE SURE NOT FAKED BY COMMAND
PUSHJ P,NOCTRO ;CLEAR THE ^O BIT
PUSHJ P,SETBKA ;SET BREAK-ON-ALL
PUSHJ P,TICAVL ;ANY AVAILABLE CHARACTERS ECHOED?
CAIA ;YEP
PUSHJ P,ECCAVL ;OR IN TO-BE-ECHOED STREAM?
AOS (P) ;YUP
POPJ P, ;RETURN
NOCTRO::MOVEI T1,LDROSU ;CLEAR OUTPUT SUPPRESS BIT
ANDCAM T1,LDBDCH(U) ; IN LINE DATA BLOCK
POPJ P,0 ;AND RETURN
STCTRO::MOVEI T1,LDROSU ;THE OUTPUT SUPPRESS BIT
IORM T1,LDBDCH(U) ;SET OUTPUT SUPPRESSION
PJRST TSETBO ;CLEAR OUTPUT BUFFER
SUBTTL TTCALL AND TRMOP. -- GETLIN
;DEFINE THE BITS FOR THE USER ARGUMENT TO GETLIN AND SETLIN
GL.ITY==400000 ;PTY
GL.CTY==200000 ;CTY
GL.DSP==100000 ;TTY DISPLAY
GL.DSL==040000 ;DATA SET LINE
GL.CNE==020000 ;COMMAND-LEVEL NO ECHO
GL.HDP==010000 ;HALF DUPLEX
GL.REM==004000 ;REMOTE TTY, NO [1,2] LOGIN
GL.RBS==002000 ;NETWORK LINE
GL.8BM==000200 ;8-BIT I/O MODE BY PROGRAM
GL.LIN==000100 ;LINE OF INPUT READY
GL.SLV==000040 ;TTY SLAVE
GL.LCM==000020 ;TTY LOWER CASE
GL.TAB==000010 ;TTY TAB
GL.LCP==000004 ;TTY LOCAL COPY
GL.PTM==000002 ;TTY PAPER TAPE
GL.NEC==000001 ;NO ECHO BY PROGRAM
;GETLIN RETURNS A WORD OF INFORMATION ABOUT A LINE
GETLIN: PUSHJ P,GETWDU## ;GET "ADDR"
JUMPL T1,GETLN1 ;DOES HE WANT HIS OWN LINE
TRZ T1,.UXTRM ;CLEAR THE TTY IO INDEX BIT
CAIL T1,TTPLEN## ;LEGAL TTY?
JRST GETLNZ ;NO, RETURN A ZERO
MOVE U,LINTAB##(T1) ;GET THE LDB ADDRESS
GETLN1: JUMPE U,GETLNZ ;NO LDB, NO BITS!
LDB T1,LDPLNO ;COPY THE LINE # FROM THE LDB
TRO T1,.UXTRM ;SET THE TERMINAL INDEX BIT
;SET BITS FROM THE (RH) OF LDBDCH(U)
MOVE T2,LDBDCH(U) ;GET THE CHARACTERISTICS WORD
TRNE T2,LDRPTY ;PTY LINE?
TLO T1,GL.ITY ;YES
TRNE T2,LDRCTY ;CTY LINE?
TLO T1,GL.CTY ;YES
TRNE T2,LDRDSD ;DATA SET LINE?
TLO T1,GL.DSL ;YES
TRNE T2,LDRRMT ;"REMOTE" LINE?
TLO T1,GL.REM ;YES
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;SET BITS FROM THE (LH) OF LDBCH(U)
TLNE T2,LDLSLV ;SLAVE?
TLO T1,GL.SLV ;YES
TLNN T2,LDLLCT ;LOWER CASE TRANSLATION?
TLO T1,GL.LCM ;YES
TLNE T2,LDLTAB ;TTY TAB?
TLO T1,GL.TAB ;YES
TLNE T2,LDLLCP ;LOCAL COPY?
TLO T1,GL.LCP ;YES
TLNE T2,LDLCNE ;COMMAND NO ECHO?
TLO T1,GL.CNE ;YES
TLNE T2,LDL8BI ;8-BIT I/O MODE?
TLO T1,GL.8BM ;YES
HRRZ F,LDBDDB(U) ;ADDRESS OF TTY DDB
JUMPE F,GETLN3 ;SKIP IF NONE
MOVE T2,DEVIOS(F) ;TTY'S NO STATUS
TRNE T2,IOSNEC ;NO ECHO SET BY PROGRAM?
TLO T1,GL.NEC ;YES
;SET BITS FROM LDBTTW
MOVE T2,LDBTTW(U) ;LINE TYPE WORD
TLNE T2,LTLANF!LTLNRT!LTLLAT ;REMOTE STATION LINE?
TLO T1,GL.RBS ;YES
;SET BITS FROM THE (LH) OF LDBATR(U)
GETLN3: MOVE T2,LDBATR(U) ;GET THE TTY MODE WORD
TLNE T2,LALDIS ;DISPLAY MODE?
TLO T1,GL.DSP ;YES
;SET BITS FROM THE (RH) OF LDBBY2
MOVE T2,LDBBY2(U) ;GET THE SECOND BYTE WORD
TRNE T2,L2RXON ;PAPTER TAPE MODE?
TLO T1,GL.PTM ;YES
;FIND OUT IF WE HAVE A LINE OF INPUT READY
MOVE T3,T1 ;CLOBBERS T1
PUSHJ P,TTLCK2 ;CHECK FOR A READY LINE
TDZA T1,T1 ;NO LINE READY YET
MOVSI T1,GL.LIN ;READY BIT
IOR T1,T3 ;A LINE IS READY
PJRST PUTWDU## ;GIVE RESULT TO THE USER
;HERE WHEN WE HAVE FOUND AN ERROR TO RETURN ZERO
GETLNZ: MOVEI T1,0 ;GET A ZERO AND
PJRST PUTWDU ;RETURN IT TO INDICATE AN ERROR
SUBTTL TTCALL AND TRMOP. -- SETLIN, INCHSL, INCHWL, INCHRS & INCHRW
;ROUTINE TO SET LINE CHARACTERISTICS FOR THE CURRENT LINE (U)
SETLIN: PUSHJ P,GETWDU## ;GET THE BITS
HLRZS T1 ;GET THEM IN THE RH
TRNN T1,GL.PTM ;SET PAPER TAPE MODE?
TDZA T2,T2 ;NO
MOVEI T2,1 ;YES
DPB T2,L2PXON ;SET THE BIT
TRNN T1,GL.DSP ;DISPLAY MODE?
TDZA T2,T2 ;NO
MOVEI T2,1 ;YES
DPB T2,LDPDIS ;SET THE BIT
HRRZ F,LDBDDB(U) ;GET DDB
JUMPE F,SETLN3 ;SKIP IF NONE
TRNN T1,GL.NEC ;NO ECHO?
TDZA T2,T2 ;NO,
MOVEI T2,1 ;YES
DPB T2,SETLP0 ;SET THE BIT
MOVE T3,LDBDCH(U) ;OTHER FACTORS
TLNN T3,LDLCNE!LDLCOM ;UNLESS OVERRIDDEN,
DPB T2,LDPECH ;STORE IN LDB ALSO
SETLN3: TRC T1,20 ;STORED AS COMPLEMENT
ROT T1,-2 ;BIT DEPENDENT FOR DPB BELOW
DPB T1,SETLP1 ;THESE THREE BITS CAN BE SET
PJRST SETCHP ;LET THE NETWORK KNOW IF WE
;CHANGE ANYTHING
;BYTE POINTERS NEEDED BY SETLCH
L2PXON: POINT 1,LDBBY2(U),18 ;PAPER TAPE BIT
SETLP0: POINT 1,DEVIOS(F),^L<IOSNEC> ;NO ECHO REQUEST BIT
SETLP1: POINT 3,LDBDCH(U),15 ;PART OF LEGAL BITS
INCHRS: PUSHJ P,SKPINC ;CAN I GET A CHARACTER (CLEAR ^O)
POPJ P,0 ;NO. GIVE NON-SKIP RETURN
PUSHJ P,TWAITC ;WAIT IN CASE NOT ECHOED YET
ICS3: PUSHJ P,TYIS ;GET A CHARACTER
JRST ICS2 ;NONE THERE.
AOS 0(P) ;GIVE SKIP RETURN
JRST ICW1 ;AND RETURN THE CHARACTER
ICS2: PUSHJ P,CLRUNR ;CLEAR UNREAD BIT
PJRST NOCTRO ;ENABLE OUTPUT AND RETURN
INCHSL: PUSHJ P,SKPINL ;IS THERE A LINE AVAILABLE?
POPJ P,0 ;NO. NON-SKIP RETURN TO USER
PUSHJ P,TWAITL
JRST ICS3 ;YES. GO GET A CHARACTER FOR HIM
INCHWL: PUSHJ P,TWAITL ;WAIT FOR A LINE TO APPEAR
ICW2: PUSHJ P,TYI ;GO GET A CHARACTER
TDZA T3,T3 ;IMPOSSIBLE. NO CHARACTERS. USER SET IODERR?
JRST ICW1 ;GO STORE
PUSHJ P,CLRUNR ;CLEAR UNREAD BIT
ICW1: ANDI T3,CK.CHR ;MASK TO SEVEN BITS
SKIPL LDBATR(U) ;IF NOT 8-BIT,
ANDI T3,CK.CH7 ;DON'T RETURN PARITY
MOVE T1,T3
PUSHJ P,PUTWDU## ;GIVE HIM THE CHARACTER
JRST NOCTRO ;AND NON-SKIP RETURN
INCHRW: PUSHJ P,TWAITC ;WAIT FOR A CHARACTER TO APPEAR
JRST ICW2 ;GET & RETURN A CHARACTER
SUBTTL TTCALL AND TRMOP. -- TRMNO. UUO
;TRMNO. CALLI, TO GET TERMINAL NUMBER
;FOR SPECIFIED JOB NUMBER.
; MOVE AC,JOBNUMBER
;CALL CALLI AC,115
; .ERROR RETURN
; NORMAL RETURN ;AC HAS .UXTRM+LINE#
TRMNO:: CAMN T1,[-1] ;IS ARG -1?
MOVEI T1,(J) ;YES, USE THIS JOB
JUMPLE T1,RTZER## ;ERROR IF JOB # 0 OR LESS THAN -1
CAMLE T1,HIGHJB## ; OR TOO BIG
JRST RTZER## ;..
HRRZ T1,TTYTAB##(T1) ;GET DDB ADDRESS
JUMPE T1,RTZER## ;ERROR IF NONE
MOVE U,DDBLDB(T1) ;GET LDB ADDRESS
JUMPE U,RTZER## ;ERROR IF DETACHED
LDB T1,LDPLNO ;GET LINE NUMBER
ADDI T1,.UXTRM ;CONVERT TO UNIVERSAL
JRST STOTC1## ;SKIP RETURN INDEX TO USER
SUBTTL TTCALL AND TRMOP. -- TRMOP. DISPATCH
;TRMOP. UUO, OR CALLI 116.
;UUO TO PERFORM MISCELLANEOUS FUNCTIONS FOR
;A SPECIFIED TERMINAL.
;
;CALL: MOVE AC,[XWD N,ADR]
; CALLI AC,116
; ERROR RETURN
; NORMAL RETURN
;
TRMOP:: PUSHJ P,SAVE4## ;SAVE THE PRESERVED AC'S
MOVE P4,T1 ;USER'S ARGUMENT TO P4
HRRM T1,M ;ADDRESS OF ARGUMENT LIST
HLRZ T2,T1 ;CHECK FOR LENGTH AT LEAST 2
CAIL T2,2
PUSHJ P,GETWRD## ;GET USER'S ARG AT M
JRST TOPX3 ;ERROR CODE 3, ILLEGAL ADDRESS
TLNE T1,-1 ;IF BITS IN L.H.
JRST RTZER## ; THEN BAD FUNCTION
HRRZ P1,T1 ;COPY USER ARGUMENT
JUMPLE P1,RTZER## ;ZERO ERROR IF BAD ARGUMENT CODE
PUSHJ P,GETWR1## ;GET IT, IF POSSIBLE
JRST TOPX3 ;NOT A LEGAL ADDRESS
SUBI T1,.UXTRM ;REMOVE TERMINAL OFFSET
CAME T1,[-1-.UXTRM] ;WANTS CONTROLLING TTY?
JRST TRMNRM ;NO
HRRZ T1,TTYTAB##(J) ;YES, GET DDB ADDRESS
JUMPE T1,RTZER## ;ERROR IF NONE
MOVE U,DDBLDB(T1) ;GET LDB ADDRESS
JUMPE U,RTZER## ;DETACHED
LDB T1,LDPLNO ;GET LINE NUMBER
TRMNRM: JUMPL T1,RTZER## ;RANGE CHECK THE TERMINAL #
CAIL T1,TTPLEN## ;..
JRST RTZER## ;BAD LINE NUMBER
MOVE U,LINTAB##(T1) ;OK. GET THE LDB ADDRESS
IFN FTNET,<
SKIPGE LDBREM(U) ;IF LOCAL LINE SET HOSTING AWAY,
JRST TOPX6 ;THEN DISALLLOW ACCESS
>;END IFN FTNET
MOVE T2,LDBTTW(U) ;GET SOME BITS
TLNN T2,LTLUSE ;IS THIS LINE IN USE?
JRST TOPX6 ;NO--DISALLOW ACCESS
MOVE F,LDBDDB(U) ;AND DDB, IF ANY.
JUMPN F,TRMO1 ;DID WE FIND A DDB?
HRLZ T2,LDBDCH(U) ;NO, GET LINE STATUS
JUMPGE T2,TRMO1 ;PTY?
SUBI T1,TCONLN##+1 ;YES, GET NUMBER
HRRZ F,PTYTAB(T1) ;GET DDB ADDR
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
TRMO1: MOVE T1,P1 ;GET USER'S FUNCTION CODE
TRNE T1,3000 ;READ/SET CODE?
JRST TOPRSQ ;PROBABLY. GO SEE.
CAILE T1,TOPLN0 ;IS IT AN ACTION CODE?
JRST RTZER## ;NO. NO SUCH CODE
HRRI M,1(M) ;ADVANCE M
MOVE P3,TOPTB0-1(T1) ;PICK UP DISPATCH WORD
LDB T1,[POINT 3,P3,17] ;GET MIN LENGTH OF ARG LIST
HLRZ T2,P4 ;AND LENGTH USER SUPPLIED
CAIGE T2,(T1) ;DID HE GIVE US ENOUGH?
JRST TOPX3 ;NOPE
IFN FTMIC,<
MOVSI P2,(JB.LSY) ;PROGRAM FROM SYS BIT
TLNE P3,(TOP.MC) ;MIC TRMOP?
TDNN P2,JBTLIM##(J) ;AND DID THIS PROGRAM COME FROM SYS?
JRST CHKRED ;NO TO EITHER
MOVSI P2,'MIC' ;RUNNING MIC?
CAMN P2,JBTNAM##(J) ;SKIP IF NO
JRST CHKDDB ;RUNNING MIC, NO FUTHER CHECKING REQUIRED
CHKRED: MOVSI T1,JP.POK
TLNE P3,(TOP.MR)
PUSHJ P,PRVBIT
SKIPA
JRST TOPX1
>
TLNN P3,(TOP.RP) ;DO WE NEED READ PRIVS?
JRST CHKWRT ;NO--SEE IF WE NEED WRITE PRIVS
PUSHJ P,TREDOK ;YES--DO WE HAVE READ PRIVS?
JRST TOPX1 ;NO--GIVE ERROR RETURN
CHKWRT: TLNN P3,(TOP.WP) ;DO WE NEED WRITE PRIVS?
JRST CHKDDB ;NO--DISPATCH
PUSHJ P,TWRTOK ;YES--DO WE HAVE READ PRIVS?
JRST TOPX1 ;NO--GIVE ERROR RETURN
CHKDDB: TLNN P3,(TOP.NF) ;NEED F?
JRST CHKDD1 ;NO--ALLSET
PUSHJ P,TOPDDB ;YES--GET DDB
JRST TOPX6 ;CAN'T GIVE ERROR
CHKDD1: SSX P3,MCSEC1 ;STAY IN SECTION 1
JRST (P3) ;YES--DO THE TRMOP.
;HERE IF REQUESTED FUNCTION NOT FROM 1 THRU TOPLN0-1
;F AND U ARE SET UP TO THE DESIRED LINE.
TOPRSQ: SETZ P3, ;SETUP P3 FOR MYTTY1 ROUTINE (PRIV CHECKS)
ANDI P1,777 ;JUST THE ITEM NUMBER
TRZE T1,1000 ;READ CODE?
JRST TOPRED ;PROBABLY
CAIL T1,2000+TOPLN1 ;NO. SET CODE?
JRST RTZER## ;NOT A LEGAL CODE
HLRZ T2,P4 ;IS THERE ANOTHER DATUM?
CAIL T2,3 ;..
PUSHJ P,GETWR1## ;YES. GO GET IT
JRST TOPX3 ;NOT A LEGAL ADDRESS
MOVE P2,T1 ;SAVE ARGUMENT
PUSHJ P,TWRTOK ;DOES HE HAVE WRITE PRIVS?
JRST TOPX1 ;NO. ERROR CODE 1.
LDB T1,TOPSYR ;LEGAL TO TRY SETTING.
JUMPE T1,TOPST2 ;RANGE CHECK REQUIRED?
HLRZ T2,TOPSRT-1(T1) ;YES. GET MINIMUM VALUE
CAMGE P2,T2 ;SUPPLIED .GE. MINIMUM?
JRST TOPX2 ;NO. BAD ARG, TOO SMALL
HRRZ T2,TOPSRT-1(T1) ;OK. CHECK MAXIMUM
CAMLE P2,T2 ;..
JRST TOPX2 ;BAD. ARG TOO BIG.
TOPST2: SKIPN T2,TOPTB1(P1) ;SET ALLOWED?
PJRST RTZER## ;ILLEGAL/UNKNOWN FUNCTION
TLNE T2,(TOP.SA) ;OK TO SET?
JRST TOPST4 ;YES--DO SO
TLNN T2,(TOP.PS) ;NEED PRIVS?
JRST TOPX1 ;NO--CAN NOT SET
MOVSI T1,JP.POK ;POKE BIT
PUSHJ P,PRVBIT## ;IS IT SET?
JRST TOPST4 ;YES--DO SET
JRST TOPX1 ;NO. NOT ALLOWED.
TOPST4: TLNN T2,(TOP.IF) ;THIS FUNCTION ILLEGAL FOR FRCLIN?
JRST TOPST5 ;NO, CONTINUE
LDB T1,LDPLNO ;GET LINE NUMBER
CAIN T1,FRCLIN## ;IS IT FRCLIN?
JRST TOPX1 ;YES, ILLEGAL
TOPST5: MOVE T1,T2 ;COPY BITS
SSX T2,MCSEC1 ;MAKE INTO A SECTION 1 ADDRESS FOR INDEXING
TLNN T1,(TOP.RT) ;NEED A ROUTINE TO SET?
JRST TOPST6 ;NO, GO HANDLE BYTE POINTERS
AOS T2 ;YES, INCREMENT ADDRESS
TLNE T1,(TOP.BP) ;DOES READ FUNCTION USE A BYTE POINTER?
HRR T2,(T2) ;YES, INDIRECT ROUTINE ADDRESS
PJRST (T2) ;LET ROUTINE HANDLE IT
TOPST6: MOVE T3,T2 ;COPY B.P. ADDRESS
TLNE T1,(TOP.BP) ;IF DUAL FLAVOR,
MOVE T3,(T3) ;INDIRECT IT
LDB T3,0(T3) ;FETCH WHAT THE STATE IS CURRENTLY
CAMN T3,P2 ;WILL IT CHANGE?
JRST CPOPJ1## ;NO, DON'T SEND STATUS CHANGE THEN
MOVEI T3,LDRPTY ;THE LINE-IS-A-PTY BIT
CAIN P1,4 ;SET SLAVE?
TDNN T3,LDBDCH(U) ; ON PTY?
TRNA ;NO
JRST TOPX1 ;YES, ILLEGAL FUNCTION FOR PTY
TLNN T1,(TOP.BP) ;IS THIS A DUAL-B.P. FUNCTION?
JRST TOPST7 ;NO--HANDLE SINGE-B.P.
MOVE T3,(T2) ;YES--GET FIRST BYTE POINTER
DPB P2,(T3) ;SET IN IT
MOVE T3,1(T2) ;GET SECOND BYTE POINTER
DPB P2,(T3) ;SET IN BOTH POINTERS
TRNA ;SKIP SINGLE-B.P. CASE
TOPST7: DPB P2,0(T2) ;OK. CHANGE ITEM.
TLNE T1,(TOP.PE) ;DO WE NEED TO NOTIFY THE FE?
PUSHJ P,SETCHP ;YES, DO SO
JRST CPOPJ1## ;RETURN SUCCESS
TOPRED: CAIL T1,TOPLN1 ;LEGAL ITEM NUMBER?
JRST RTZER## ;NO. ERROR RETURN
PUSHJ P,TREDOK ;OK TO DO A READ?
JRST TOPX1 ;NO. PROTECTION FAILURE.
SKIPN T1,TOPTB1(P1) ;OK. GET TABLE ENTRY.
JRST RTZER## ;ILLEGAL/UNKNOWN FUNCTION
HRRZ T2,T1 ;GET JUST DISPATCH OR BYTE POINTER ADDRESS
TLNE T1,(TOP.RT) ;NEED A ROUTINE
TLNE T1,(TOP.BP) ;AND NOT JUST FOR SET?
JRST TOPRD1 ;NO, USE B.P.
PUSHJ P,0(T2) ;ZERO OFFSET TO READ
PJRST STOTC1## ;RETURN RESULT TO USER AND SKIP RETURN
TOPRD1: TLNE T1,(TOP.BP) ;DUAL-B.P. FUNCTION?
MOVE T2,(T2) ;YES--INDIRECT BYTE POINTER
LDB T1,0(T2) ;GET BYTE POINTED TO
PJRST STOTC1## ;AND RETURN IT TO USER
;ROUTINE TO RETURN OUTPUT-IN-PROGRESS
TOROIP: PUSHJ P,TOPSOP ;SKIP IF OUTPUT IN PROGRESS
TDZA T1,T1 ;CLEAR BUSY IF NO OUTPUT
MOVEI T1,1 ;NO, SET BUSY FLAG
POPJ P, ;...
;ROUTINE TO HANDLE FUNCTION 2022 (SET XOFF)
TOPXFF: DPB P2,LDPSTP ;STORE USERS VALUE
IFN FTNET,<
SKIPL LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST TOPXF1 ;NO, DON'T SET LRRXFF
MOVEI T1,LRRXFF ;TELL FRONT END ABOUT XON/XOFF IN STATUS MSG.
IORM T1,LDBREM(U) ;
JRST TOPXF2 ;GO TO COMMON CODE
>;END IFN FTNET
TOPXF1:
IFN FTKL10,<
HRRZ T1,LDBISR(U) ;GET ISR DISPATCH
CAIE T1,TTDDSP## ;IS THIS A -20F LINE
JRST CPOPJ1## ;NO
MOVSI T1,LTLXFF ;YES, SET BIT TO INFORM -20F
IORM T1,LDBTTD(U) ;
>;END IFN FTKL10
TOPXF2: PJRST SETCH1 ;SUCCEED AFTER NOTIFYING FE
;ROUTINE TO SET THE VALUE OF LDLFRM
TOPFRM: MOVEI T3,MC.FRM ;HERE TO SET .TOFRM. LOAD FUNCTION
PUSHJ P,OUTSTB ;QUEUE IT UP FOR SYNCHRONICITY
PJRST CPOPJ1## ;AND SIGNAL GOOD RETURN
;ROUTINE TO SET THE VALUE OF LDLTAB
TOPTAB: MOVEI T3,MC.TAB ;HERE TO SET .TOTAB. LOAD FUNCTION
PUSHJ P,OUTSTB ;QUEUE IT UP FOR SYNCHRONICITY
PJRST CPOPJ1## ;AND SIGNAL GOOD RETURN
;ROUTINE TO SET THE VALUE OF LDLNFC
TOPNFC: MOVEI T3,MC.NFC ;HERE TO SET .TONFC. LOAD FUNCTION TO PERFORM
PUSHJ P,OUTSTB ;QUEUE IT UP FOR SYNCHRONICITY
JRST CPOPJ1## ;AND SIGNAL GOOD RETURN
;ROUTINE TO FETCH/SET THE VALUE OF HPOS
TOPHPS: JRST TORHPS ;HERE FOR READ
MOVEI T3,MC.HPS ;GET FUNCTION TO USE IN XMTCHR
PUSHJ P,OUTSTF ;QUEUE UP THE FUNCTION
JRST CPOPJ1## ;AND SIGNAL GOOD RETURN
TORHPS: PUSHJ P,HPOS ;GET POSITION
MOVE T1,T2 ;GET INTO CORRECT AC
POPJ P,
;ROUTINE TO HANDLE SET OF LDRRMT
TOPRMT: ANDI P2,1 ;NORMALIZE ARGUMENT
LDB T2,LDPRMT ;GET CURRENT SETTING
CAMN T2,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;SUCCEED VACUOUSLY
JUMPE P2,TOPRM1 ;ELSEWHERE IF WANTING TO CLEAR
MOVSI T1,JP.POK ;POKE PRIVS REQUIRED TO SET
PUSHJ P,PRVBIT## ;CHECK FOR THEM
JRST TOPRM2 ;IT'S COOL
JRST TOPX1 ;PRIVILEGE ERROR
TOPRM1: LDB T2,LDPLNO ;LINE NUMBER
CAIL T2,FRCLIN## ;MAKE SURE IT'S A REASONABLE TERMINAL
CAILE T2,TCONLN## ;IS IT FRCLIN OR A CTY?
JRST TOPRM2 ;NO, SO ALLOW IT
JRST TOPX1 ;PRIVILEGE ERROR
TOPRM2: DPB P2,LDPRMT ;MAKE THE CHANGE
JRST CPOPJ1## ;AND RETURN SUCCESS
;ROUTINE TO SET THE VALUE OF LDPWID
TOPWID: MOVEI T3,MC.WID ;GET FUNCTION TO USE IN XMTCHR
PUSHJ P,OUTSTF ;QUEUE UP THE FUNCTION
JRST CPOPJ1## ;AND SIGNAL GOOD RETURN
;ROUTINE TO HANDLE SET OF L1RDEM
TOPDEM: LDB T2,LDPDEM ;GET OLD VALUE
ANDI P2,1 ;KEEP ONLY THE BIT WE'LL USE
CAMN T2,P2 ;CHANGING IT?
JRST CPOPJ1## ;NO, IGNORE
DPB P2,LDPDEM ;STORE OUR NEW VALUE
MOVSI T2,L3LDMC ;GET THE CHANGE BIT
IORM T2,LDBBY3(U) ;LIGHT IT FOR RECINT
PJRST SETCH1 ;POKE THE FRONT END AND RETURN GOODNESS
;ROUTINE TO HANDLE .TOPSZ (TTY PAGE N)
TOPPSZ: DPB P2,LDPLNB ;SET PAGE LENGTH
DPB P2,LDPSTB ;SET STOP BASE
MOVSI T2,LPLXNF!LPLSTP!LPLSBL ;GET THE "STOP" BITS
IORM T2,LDBPAG(U) ;AND SET AUTO STOP
PUSHJ P,CLRPCT
JRST CPOPJ1## ;SUCCESSFUL RETURN
;SUBROUTINE TO QUEUE UP A SYNCHRONOUS OUTPUT FUNCTION.
;CALL: MOVE T3,MC.XXX ;FUNCTION CHARACTER TO BE PERFORMED
; MOVE P2,USER VALUE ;ARGUMENT TO THE FUNCTION
; PUSHJ P,OUTSTF ;QUEUE UP TWO CHARACTERS
; ALWAYS RETURN CPOPJ
OUTSTB: ANDI P2,1 ;ENTRY FOR ONE-BIT VALUES
OUTSTF: SKIPG TTFREN## ;ANY FREE CHUNKS?
JRST OUTSF2 ;NO, WAIT FOR SOME
SCNOFF ;FOR STCHK'ING
MOVE P1,LDBTOP(U) ;SAVE POINTER FOR BACKING OUT
SKIPG TTFREN## ;CHECK FREE POOL AGAIN
JRST OUTSF1 ;WAIT FOR SOME TO APPEAR
STCHK T3,LDBTOP(U),OUTSF1 ;STUFF AWAY THE FUNCTION
STCHK P2,LDBTOP(U),OUTSF1 ;AND ITS ARGUMENT
MOVEI P1,2 ;NUMBER OF BYTES ADDED
ADDM P1,LDBTOC(U) ;UPDATE CHARACTER COUNT
SCNON ;ALLOW OTHERS AGAIN
PJRST TOPOKE ;BE SURE THE LINE IS QUEUED
OUTSF1: MOVEM P1,LDBTOP(U) ;RESTORE POINTER
SCNON ;ALLOW OTHERS
OUTSF2: PUSHJ P,OUTSTS ;WAIT A TICK
JRST OUTSTF ;AND TRY, TRY, AGAIN
OUTSTS: PUSH P,T3 ;SAVE THE CHARACTER
SETZ T1, ;A SHORT TIME
S0PSHJ SLEEPF## ;WAIT IT OUT
POP P,T3 ;RESTORE THE CHARACTER
POPJ P, ;RETURN TO TRY AGAIN
REPEAT 0,<
;SUBROUTINE TO QUEUE UP A SYNCHRONOUS INPUT FUNCTION.
;CALL: MOVE T3,MC.XXX ;FUNCTION CHARACTER TO BE PERFORMED
; MOVE P2,USER VALUE ;ARGUMENT TO THE FUNCTION
; PUSHJ P,INPSTF ;QUEUE UP TWO CHARACTERS
; ALWAYS RETURN CPOPJ
INPSTF: SKIPG TTFREN## ;ANY FREE CHUNKS?
JRST INPSF2 ;NO, WAIT FOR SOME
SCNOFF ;FOR STCHK'ING
MOVE P1,LDBTIP(U) ;SAVE POINTER FOR BACKING OUT
SKIPG TTFREN## ;CHECK FREE POOL AGAIN
JRST INPSF1 ;WAIT FOR SOME TO APPEAR
STCHK T3,LDBTIP(U),INPSF1 ;STUFF AWAY THE FUNCTION
STCHK P2,LDBTIP(U),INPSF1 ;AND ITS ARGUMENT
MOVEI P1,2 ;NUMBER OF BYTES ADDED
ADDM P1,LDBECC(U) ;UPDATE CHARACTER COUNT
JRST SONPPJ ;RETURN ALLOWING OTHERS AGAIN
INPSF1: MOVEM P1,LDBTIP(U) ;RESTORE POINTER
SCNON ;ALLOW OTHERS
INPSF2: PUSHJ P,OUTSTS ;WAIT A TICK
JRST INPSTF ;AND TRY, TRY, AGAIN
> ;END REPEAT 0
;ROUTINE TO GET/SET TERMINAL TYPE
TOPTTC: JRST TORTTC ;GET TERMINAL TYPE
MOVE T2,P2 ;GET USER'S ARGUMENT
PUSHJ P,TTUTYP## ;SET TERMINAL CHARACTERISTICS
JRST TOPX2 ;UNKNOWN TERMINAL TYPE
JRST CPOPJ1## ;GOOD RETURN
TORTTC::LDB T1,LDPTTT ;GET TERMINAL TYPE
MOVE T1,CTTWDT##(T1) ;GET TERMINAL NAME
POPJ P, ;STORE ANSWER FOR THE USER AND RETURN
;ROUTINE TO SET OUTPUT SUPPRESSION (^O) STATE
TOPSUP: TRNE P2,1 ;SET OR CLEAR ^O?
JRST TOPSU2 ;SET IT
PUSHJ P,NOCTRO ;CLEAR IT
JRST CPOPJ1## ;RETURN HAPPILY
TOPSU2: PUSHJ P,STCTRO ;SET ^O STATE
JRST CPOPJ1## ;RETURN SUCCESSFULLY
; ROUTINE TO SET FULL CHARACTER SET
TOPFCS: JUMPE F,TOPX6 ;NEED A DDB
DPB P2,LDPFCS ;STORE IN LDB
DPB P2,[POINT 1,DEVIOS(F),^L<IOSFCS>] ;YES--SET IN DDB
PUSHJ P,SETBMC ;POKE THE FRONT END
JRST CPOPJ1## ;AND RETURN
; ROUTINE TO SET BREAK ON ALL CHARACTERS
TOPBKA: JUMPE F,TOPX6 ;NEED A DDB
DPB P2,LDPBKA ;STORE IN LDB
DPB P2,[POINT 1,DEVIOS(F),^L<IOSBKA>] ;YES--SET IN DDB
PUSHJ P,SETBMC ;POKE THE FRONT END
JRST CPOPJ1## ;AND RETURN
;ROUTINE TO RETURN TOTAL INPUT CHARACTER COUNT
TORCCT: MOVE T1,LDBTIC(U) ;INPUT CHARACTER COUNT AVAILABLE TO USER
ADD T1,LDBECC(U) ;PLUS THOSE NOT YET ECHOED
SUB T1,LDBIIC(U) ;MINUS DELETIONS
SUB T1,LDBIEC(U) ;OF BOTH SORTS
POPJ P, ;RETURN TOTAL MONITOR CHARACTER COUNT
;HERE TO READ/SET TERMINAL LENGTH COUNTER
TOPLNC: JRST TORLNC ;GO HANDLE READ REQUEST
MOVN T2,P2 ;NEGATIVE SINCE COUNTS UP TO 0
ANDI T2,377 ;ONLY 8-BITS WORTH
DPB T2,LDPLNC ;BUT A 9-BIT POINTER (FOR OVERFLOW)
JRST CPOPJ1## ;SUCCESSFUL RETURN
TORLNC: LDB T1,LDPLNB ;GET BASE SIZE
JUMPE T1,CPOPJ## ;IF NO LENGTH THEN COUNTER IS 0 BY DEFINITION
LDB T1,LDPLNC ;ELSTWISE PICKUP CURRENT LENGTH COUNTER
IOR T1,[777777,,777400] ;"SIGN EXTEND" THE FIELD
MOVN T1,T1 ;GET POSITIVE LINES LEFT
POPJ P, ;AND RETURN
;HERE TO READ/SET TERMINAL STOP COUNTER
TOPSTC: JRST TORSTC ;GO HANDLE READ REQUEST
MOVN T2,P2 ;NEGATIVE SINCE COUNTS UP TO 0
ANDI T2,377 ;ONLY 8-BITS WORTH
DPB T2,LDPSTC ;BUT A 9-BIT POINTER (FOR OVERFLOW)
JRST CPOPJ1## ;SUCCESSFUL RETURN
TORSTC: LDB T1,LDPSTB ;GET BASE SIZE
JUMPE T1,CPOPJ## ;IF NO STOP SIZE THEN COUNTER IS 0 BY DEFINITION
MOVSI T1,LPLSTP ;THE AUTO STOP BIT
AND T1,LDBPAG(U) ;SEE IF AUTO STOP IS ENABLED
JUMPE T1,CPOPJ## ;IF NOT, THEN COUNTER IS 0 BY DEFINITION
LDB T1,LDPSTC ;ELSTWISE PICKUP CURRENT STOP COUNTER
IOR T1,[777777,,777400] ;"SIGN EXTEND" THE FIELD
MOVN T1,T1 ;GET POSITIVE LINES LEFT
POPJ P, ;AND RETURN
; ROUTINE TO SET/READ ECHO STATUS
TOPECH: JRST TORECH ;GO HANDLE READ REQUEST
JUMPE F,TOPX6 ;NEED A DDB
TRC P2,1 ;CORRECT SENSE
MOVE T2,LDBDCH(U) ;GET DCH BITS
TLNN T2,LDLCNE!LDLCOM ;IF NOT OVERRIDDEN,
DPB P2,LDPECH ;STORE IN LDB
DPB P2,SETLP0 ;YES--SET IN DDB
PJRST SETCH1 ;POKE THE FRONT END AND RETURN SUCCESS
TORECH: LDB T1,LDPECH ;GET ECHO STATUS FROM LDB
TRC T1,1 ;CORRECT SENSE SO USER NOT CONFUSED
POPJ P, ;AND RETURN
;ROUTINE TO SET UNPAUSE CHARACTER
TOPUNP: CAMN P2,[-1] ;WANT TO DEFAULT IT?
MOVEI P2,"Q"-100 ;YES, MAKE IT ^Q
LDB T2,LDPUNP ;GET PREVIOUS SETTING
CAMN T2,P2 ;CHANGING IT?
JRST CPOPJ1## ;NO, SUCCEED VACUUOUSLY
DPB P2,LDPUNP ;YES, DO SO
PUSHJ P,TOPNDS ;SET LMLNDS APPROPRIATELY
PUSHJ P,SETOBC ;POKE THE FRONT END
JRST CPOPJ1## ;SUCCESS
;ROUTINE TO SET ESCAPE CHARACTER
TOPESC: CAMN P2,[-1] ;WANT TO DEFAULT IT?
MOVEI P2,STDALT ;YES, MAKE IT ESCAPE
LDB T1,LDPESC ;GET PREVIOUS SETTING
CAMN T1,P2 ;CHANGING ANYTHING?
JRST CPOPJ1## ;NO, JUST SUCCEED
DPB P2,LDPESC ;YES, CHANGE IT
PUSHJ P,TOPNDS ;SET LMLNDS CORRESPONDINGLY
PUSHJ P,SETOBC ;POKE THE FRONT END
JRST CPOPJ1## ;RETURN TO USER
;ROUTINE TO SET/READ SWITCH SEQUENCE (FOR CTERM)
TOPSWI: JRST TORSWI ;HANDLE READ
CAMN P2,[-1] ;REQUESTING DEFAULT?
MOVSI P2,(<BYTE(8)34,15>) ;YES, LOAD UP ASCII8 "^\^M"
TDNE P2,[BYTE(16)0(20)-1] ;CHECK FOR BITS BESIDES THE CHARACTERS
JRST TOPX2 ;GIVE A RANGE ERROR IF SO
LSH P2,-^D20 ;RIGHT-JUSTIFY USER ARG
LDB T1,LDPSWI ;GET PREVIOUS SETTING
CAMN T1,P2 ;CHANGING ANYTHING?
JRST CPOPJ1## ;NO, SUCCEED VACUOUSLY
MOVE T2,P2 ;COPY USER ARG
LSH T2,-8 ;ISOLATE HIGH CHARACTER
XOR T2,P2 ;TEST FOR IDENTITY
TRNN T2,CK.CHR ;ARE THE CHARACTERS DIFFERENT?
JUMPN P2,TOPX2 ;NO, ERROR UNLESS CLEARING THE SEQUENCE
DPB P2,LDPSWI ;OK, SET THE NEW VALUE
MOVSI T2,LMLSSE ;SWITCH-SEQUENCE ENABLED BIT
IORM T2,LDBCHM(U) ;ASSUME WE JUST ENABLED
SKIPN P2 ;VALID ASSUMPTION?
ANDCAM T2,LDBCHM(U) ;NO, CLEAR THE BIT WHEN DISABLING
PUSHJ P,TOPNDS ;SET LMLNDS CORRESPONDINGLY
PUSHJ P,SETOBC ;NOTIFY THE FRONT END
JRST CPOPJ1## ;RETURN SUCCESS
TORSWI: LDB T1,LDPSWI ;FETCH THE SEQUENCE
LSH T1,^D20 ;MAKE IT MATCH A USER ARGUMENT
POPJ P, ;RETURN IT
;ROUTINE TO SET/CLEAR LMLNDS AS APPROPRIATE
TOPNDS::MOVSI T2,LMLNDS ;NON-DEFAULT SEQUENCE BIT
IORM T2,LDBCHM(U) ;ASSUME THE MAP IS NON-STANDARD
LDB T1,LDPUNP ;GET THE UNPAUSE CHARACTER
PUSHJ P,TOPND1 ;SEE IF ITS OK
POPJ P, ;NO, OUR ASSUMPTION IS VERIFIED
LDB T1,LDPESC ;IT WAS, GET THE ESCAPE CHARACTER
PUSHJ P,TOPND1 ;IS IT STANDARD?
POPJ P, ;NO
MOVSI T1,LMLSSE ;YES, CHECK FOR SWITCH SEQUENCE
TDNN T1,LDBCHM(U) ;IS IT ENABLED?
JRST TOPND2 ;NO, THIS IS A STANDARD MAP
LDB T1,LDPSW1 ;YES, GET SWITCH-1
PUSHJ P,TOPND1 ;IS IT STANDARD?
POPJ P, ;NO
LDB T1,LDPSW2 ;YES, HOW ABOUT SWITCH-2
PUSHJ P,TOPND1 ;CHECK IT
POPJ P, ;NON-STANDARD
TOPND2: ANDCAM T2,LDBCHM(U) ;STANDARD SEQUENCE AFTER ALL
POPJ P, ;RETURN TO CALLER
TOPND1: TRNE T1,CK.CH7^!37 ;IS IT A CONTROL CHARACTER?
POPJ P, ;NO, IT'S NON-STANDARD
CAIE T1,11 ;YES, IF IT'S NOT A TAB
JUMPN T1,CPOPJ1## ;AND NOT NULL, IT'S STANDARD
POPJ P, ;NOPE, NON-STANDARD
;ROUTINE TO SET 8-BIT TTY MODE
TOP8BT: ANDI P2,1 ;NORMALIZE ARGUMENT
LDB T1,LDP8BT ;GET OLD VALUE
CAMN T1,P2 ;IF NO CHANGE,
JRST CPOPJ1## ;SUCCEED QUIETLY
MOVSI T1,LIL7BT ;DUMB FE BIT
TDNE T1,LDBISB(U) ;IS IT SET?
JUMPN P2,TOPX4 ;YES, DON'T ALLOW SETTING 8-BIT
DPB P2,LDP8BT ;OK--SET USER'S BIT
JRST SETCH1 ;TELL FE AND SUCCEED
;ROUTINE TO SET LDBATR
TOPATR: MOVSI T1,LIL7BT ;DUMB FE BIT
TDNE T1,LDBISB(U) ;IS IT SET?
TLZ P2,LAL8BT ;YES--DON'T ALLOW SETTING 8-BIT
CAMN P2,LDBATR(U) ;IF NO CHANGE,
JRST CPOPJ1## ;SUCCEED VACUOUSLY
MOVEM P2,LDBATR(U) ;CHANGE IT
JRST SETCH1 ;TELL FE AND SUCCEED
;ROUTINE TO SET THE 8-BIT I/O MODE BIT
TOP8BI: JUMPE F,TOPX6 ;MUST HAVE A DDB TO DO THIS
DPB P2,LDP8BI ;STORE IN LDB
LDB T1,[POINT 4,DEVIOS(F),35] ;GET THE I/O MODE CURRENTLY SET
CAILE T1,A8 ;IS IT SOMETHING WE SHOULD CHANGE?
JRST SETCH1 ;NO, JUST SUCCEED
MOVEI T1,A8 ;YES, GET NEW MODE
TRNN P2,1 ;UNLESS TURNING IT OFF,
MOVEI T1,AL ;THEN GET OTHER NEW MODE
DPB T1,[POINT 4,DEVIOS(F),35] ;SAVE IT AWAY IN THE DDB
JRST SETCH1 ;NOW SUCCEED
;ROUTINE TO SET THE MAXIMUM IDLE TIME FOR THE AUTO-DISCONNECT FEATURE
TOPMXT: AOS (P) ;WE'RE GOING TO SUCCEED
MOVE T1,P2 ;PUT THE ARGUMENT WHERE IT BELONGS
PJRST SCNADT ;SET THE TIMER AND RETURN
;ROUTINE TO READ THE REMAINING LIMIT ON THE AUTO-DISCONNECT TIMER
TORADT: LDB T2,LDPTMR ;GET THE COUNT-UP VALUE
SETO T1, ;AND THE VALUE FOR AN EXPIRED TIMER
TRNE T2,L3RTMO ;IF IT'S TIMED-OUT,
POPJ P, ;RETURN MINUS ONE
LDB T2,LDPMXT ;GET THE ORIGINAL LIMIT
HRLOI T1,377777 ;LOAD UP A POSITIVE INFINITY
JUMPE T2,CPOPJ## ;RETURN INFINITY IF NO TIMING
LDB T1,LDPTMR ;GET COUNT-UP VALUE AGAIN
MOVNS T1 ;ACCOUNT FOR ITS NEGATION
ANDI T1,377 ;KEEP ONLY RELEVANT BITS
POPJ P, ;RETURN THE REMAINING TIME LIMIT
TOPCNE: JRST TORCNE ;READ ROUTINE
ANDI P2,1 ;NORMALIZE THE ARGUMENT
JUMPN P2,TOPCN1 ;ELSEWHERE IF 'CLEARING'
MOVSI T2,LDLCNE!LDLNEC ;SETTING, EASY CASE
IORM T2,LDBDCH(U) ;JUST LIGHT THE NO-ECHO BITS
PJRST SETCH1 ;POKE FRONT END AND RETURN GOODNESS
TOPCN1: MOVSI T2,LDLCNE ;GET BIT WE'RE CLEARING
ANDCAM T2,LDBDCH(U) ;WIPE IT
JUMPE F,TOPCN2 ;ALSO CLEAR LDLNEC IF NO DDB
MOVE T1,DEVIOS(F) ;GET STATUS BITS
TRNE T1,IOSNEC ;IF STILL WANT NO ECHO,
JRST SETCH1 ;JUST POKE FE AND SUCCEED
TOPCN2: MOVSI T1,LDLNEC ;ANOTHER NO-ECHO BIT
ANDCAM T1,LDBDCH(U) ;CLEAR IT, TOO
PJRST SETCH1 ;POKE FE AND SUCCEED
TORCNE: MOVSI T1,LDLCNE ;GET BIT TO TEST
TDNE T1,LDBDCH(U) ;SEE IF CLEAR
TDZA T1,T1 ;NO, RETURN ZERO
MOVEI T1,1 ;YES, RETURN ONE
POPJ P, ;RETURN IT TO THE USER
;ROUTINE TO HANDLE EDIT BUFFER CREATIONS AND DESTRUCTIONS
TOPEDT::JRST TOREDT ;READ ROUTINE
SCNEDT::ANDI P2,1 ;NORMALIZE THE ARGUMENT
IFN FTMP&FTXMON,<
PUSHJ P,INTLVL## ;IF AT UUO LEVEL,
JRST SCNED0 ;SKIP FUNNY BUSINESS 'CAUSE GGVMM IS OK
JUMPN P2,SCNED0 ;IF FROM COMCON, WE HAVE THE MM
PUSHJ P,GETMM## ;TRY TO GET THE MM
JRST SCNED1 ;NO GO, SEE HOW MUCH WE CARE
PUSHJ P,SCNED0 ;WE GOT IT, USE IT
JRST GIVMM## ;GIVE AWAY MM, PROPAGATING FAILURE
AOS (P) ;PROPAGATE SKIPNESS
PJRST GIVMM## ;RETURN THE MM AND GO HOME
SCNED1: JUMPN P2,SCNED2 ;USER WANTS TO GET CORE
SKIPN T1,LDBEDT(U) ;USER WANTS TO GIVE IT AWAY, DO WE HAVE IT?
JRST CPOPJ1## ;NO, SUCCEED VACUOUSLY
SETZM LDBEDT(U) ;YES, BUT WE SOON WON'T
SETZM (T1) ;TERMINATE THE QUEUE
SCNOFF ;NEED SOME INTERLOCK HERE
EXCH T1,EDTBLQ ;MAKE NEW HEAD OF QUEUE
MOVEM T1,@EDTBLQ ;FIXUP FORWARD LINK
JRST SONPJ1 ;RETURN INTERLOCK AND SUCCEED
SCNED2: SKIPE LDBEDT(U) ;DOES USER ALREADY HAVE A BUFFER?
JRST CPOPJ1## ;YES, BE FRIENDLY
PUSHJ P,SCNEDQ ;TRY TO GET A BLOCK FROM THE QUEUE
JUMPN T1,SCNED3 ;SUCCEED IF GOT THE BLOCK
JRST TOPX2 ;FAIL IF COULDN'T
;HERE TO GET A BLOCK OFF THE FREE QUEUE
SCNEDQ: SCNOFF ;NO, INTERLOCK THE QUEUE
SKIPE T1,EDTBLQ ;HAVE ANY BLOCKS THAT WE COULDN'T GIVE AWAY?
MOVE T1,(T1) ;YES, GET THE FORWARD LINK
EXCH T1,EDTBLQ ;UPDATE AND GET THE FIRST
SCNON ;DONE MUCKING WITH THE QUEUE
POPJ P, ;LET CALLER SORT IT OUT
SCNED0:
> ;END IFN FTMP&FTXMON
JUMPE P2,TOPED1 ;CLEARING, GO DO IT
SKIPE LDBEDT(U) ;IF ALREADY DONE
JRST CPOPJ1## ;SUCCEED VACUOUSLY
IFN FTXMON&FTMP,<
PUSHJ P,SCNEDQ ;TRY TO GET A BLOCK FROM THE FREE QUEUE
JUMPN T1,SCNED3 ;WE GOT ONE, USE IT
> ;END IFN FTXMON&FTMP
MOVEI T2,EDTBFL ;GET LENGTH OF BUFFER INCLUDING HEADER INFO
IFE FTXMON,<PUSHJ P,GETWDS##> ;ALLOCATE FROM FREE CORE
IFN FTXMON,<PUSHJ P,GFWNZS##> ;ALLOCATE FROM FUNNY SPACE
JRST TOPX2 ;NO MORE SPACE AVAILABLE, USER LOSES
SCNED3: MOVEM T1,LDBEDT(U) ;STORE INTO THE POINTER
AOS (P) ;GIVE A SKIP RETURN
PJRST EDTINI ;GO INITIALIZE THE BUFFER
TOPED1: SKIPN T2,LDBEDT(U) ;GET THE ADDRESS OF THE BUFFER
JRST CPOPJ1## ;NO BUFFER, ALL DONE
MOVEI T1,EDTBFL ;GET LENGTH OF BUFFER INCLUDING HEADER INFO
SETZM LDBEDT(U) ;CLEAR THE BUFFER POINTER FOR THE FUTURE
IFE FTXMON,<PUSHJ P,GIVWDS##> ;GIVE BACK THE WORDS
IFN FTXMON,<PUSHJ P,GVFWDS##> ;GIVE BACK THE WORDS
JRST CPOPJ1## ;RETURN GOOD
TOREDT: SKIPE T1,LDBEDT(U) ;ARE WE POINTING TO A BUFFER??
MOVEI T1,1 ;YES, ONLY ONE BIT IS ENOUGH
POPJ P,
EDTEND: PUSH P,T1 ;SAVE REGISTERS
MOVE T1,LDBEDT(U) ;GET THE BUFFER ADDRESS
MOVE T1,EDTCNT(T1) ;GET THE COUNT OF CHARACTERS LEFT
CAIN T1,EDTCHC ;ARE WE STORING THE FIRST CHARACTER?
JRST TPOPJ## ;YES, EMPTY LINES DON'T GET SAVED
PUSH P,T3 ;SAVE THE CHARACTER
SETZ T3, ;MAKE A NULL CHARACTER
PUSHJ P,EDTSTO ;GO STORE IT
POP P,T3 ;RESTORE THE CHARACTER
PUSHJ P,EDTINI ;GO REINIT THE BUFFER
JRST TPOPJ## ;AND GO RETURN
EDTINI: SKIPN T2,LDBEDT(U) ;GET THE BUFFER ADDRESS
POPJ P, ;NOT IN EDIT MODE
MOVEI T1,EDTCHC ;GET THE CHARACTER COUNT FOR THE BUFFER
MOVEM T1,EDTCNT(T2) ;STORE INTO THE BUFFER HEADER
ADDI T2,EDTHDL ;BUMP HEADER ADDRESS TO POINT TO THE BUFFER
IFE FTXMON,<
TLO T2,(POINT 9,,) ;MAKE IT A BYTE POINTER
>;FTXMON
IFN FTXMON,<
TLO T2,670000 ;MAKE A ONE WORD GLOBAL BYTE POINTER
>;FTXMON
MOVE T1,T2 ;DUPLICATE IT
DMOVEM T1,@LDBEDT(U) ;STORE THEM INTO THE HEADER
POPJ P, ;RETURN
EDTSTO: PUSHJ P,SAVE1## ;GET A REGISTER
SKIPE P1,LDBEDT(U) ;STORE INTO EDIT BUFFER IF ENABLED
PUSHJ P,FULLCQ ;CHARACTER IN LINE MODE?
POPJ P, ;NO, RETURN
SKIPG EDTCNT(P1) ;ANY MORE FOOM FOR CHARACTERS IN THE BUFFER?
POPJ P, ;NO ROOM, RETURN NOW
TRNN T3,CK.MET ;IF NOT META,
TRNN T3,CK.IMG ;BUT IT IS IMAGE,
TRNA ;META OR NOT IMAGE IS OK
POPJ P, ;REAL IMAGE ISN'T
PUSHJ P,SPCHEK ;SEE IF CHARACTER SPECIAL
JRST EDTST1 ;IT ISN'T, JUST STORE IT
TLNN T1,CHBRK ;BREAK CHARACTER?
JRST EDTST1 ;IT ISN'T, JUST STORE IT
MOVE T2,EDTCNT(P1) ;GET THE CHARACTER COUNT LEFT
CAIN T2,EDTCHC ;ARE WE AT THE BEGINNING OF THE BUFFER?
POPJ P, ;YES, DON'T CORRUPT BUFFER
PUSH P,T3 ;SAVE THE CHARACTER
SETZ T3, ;MAKE A NULL
IDPB T3,EDTPTP(P1) ;TERMINATE THE BUFFER
PUSHJ P,EDTINI ;AND GO REINIT IT
JRST T3POPJ## ;RESTORE CHARACTER AND RETURN
EDTST1: IDPB T3,EDTPTP(P1) ;ELSE, STORE THIS CHARACTER
SOS EDTCNT(P1) ;ROOM FOR ONE LESS CHARACTER
POPJ P, ;RETURN
;ROUTINE TO HANDLE FUNCTION 1111 (READ CLASS NAME)
TORTCN::LDB T1,LDPTTT ;GET TTY TYPE INDEX
HLRZ T1,CTATAB##(T1) ;GET CLASS INDEX
MOVE T1,CCNTAB##(T1) ;THEN CLASS NAME
POPJ P, ;LET TRMOP DO THE STOTC1
;SUBROUTINE TO CHECK FOR READ PRIVS
;CALL WITH:
; F = DDB OF TARGET OR 0
; PUSHJ P,TREDOK
; RETURN HERE IF ERROR
; RETURN HERE IF OK TO READ
TREDOK: PUSHJ P,SAVE3## ;SAVE P1,P2 AND P3
MOVSI P1,PVSPYM!PVSPYA;LOAD UP THE SPY BIT
JRST MYTTY ;JUMP TO COMMON CODE
;SUBROUTINE TO CHECK FOR WRITE PRIVS
;CALL WITH:
; F = DDB OF TARGET OR 0
; PUSHJ P,TWRTOK
; RETURN HERE IF ERROR
; RETURN HERE IF OK
;PRESERVES ALL AC'S
TWRTOK: PUSHJ P,SAVE3## ;SAVE P1,P2 AND P3
MOVSI P1,JP.POK ;FALL INTO COMMON CODE
MYTTY: SKIPE P2,F ;IS THERE A DDB?
LDB P2,PJOBN## ;YES--GET THE OWNERS JOB NUMBER
CAMN P2,J ;DO I OWN THIS TERMINAL
JRST MYTTY1 ;CHECK PRIVS FOR MIC STYLE TRMOP
MYTTY2: EXCH P1,T1 ;SAVE T1 AND SET UP PRIV BIT
PUSHJ P,PRVBIT## ;CHECK THE BIT
AOS (P) ;OK TO READ OR SET
MOVE T1,P1 ;RESTORE T1
POPJ P,0 ;RETURN
MYTTY1:
IFE FTMIC,<JRST CPOPJ1##> ;OK TO DO YOUR THING
IFN FTMIC,<
TLNN P3,(TOP.MC) ;MIC TRMOP?
JRST CPOPJ1## ;NO--OK TO DO YOUR THING
MOVE P2,DEVMOD(F) ;IS THE TARGET TTY...
TLNE P2,TTYATC ;CONTROLLING HIS JOB?
JRST CPOPJ1## ;YES--OK TO DO MIC TRMOP
MOVE P2,LDBDCH(U) ;NO--IS THE TARGET TTY...
TRNE P2,LDRCTY ;A CTY?
JRST MYTTY2 ;YES--CHECK PRIVS
CAMN U,OPRLDB## ;IS THIS "OPR"?
JRST MYTTY2 ;YES--CHECK PRIVS
HRRZ P3,TTYTAB##(J) ;GET USER'S TTY DDB ADDRESS
JUMPE P3,MYTTY2 ;ERROR IF NONE
MOVE P3,DDBLDB(P3) ;USER'S LDB ADDRESS
JUMPE P3,MYTTY2 ;DETACHED
MOVE P3,LDBDCH(P3) ;USER'S TTY CHARACTERISTICS BITS
TRNN P3,LDRDSR ;IS HE A LOCAL TTY?
JRST CPOPJ1## ;YES--LET HIM DO MIC TRMOP TO EITHER REMOTE OR LOCAL TTY'S
TRNE P2,LDRDSR ;NO--TARGET TTY ANOTHER REMOTE TTY?
JRST CPOPJ1## ;YES--DO IT
JRST MYTTY2 ;NO--CHECK PRIVS
>
;ERROR RETURNS
ERCODE TOPX1,TRMNP% ;(1) ERROR CODE FOR PROT CHECK
ERCODE TOPX2,TRMBR% ;(2) ERROR CODE FOR RANGE BAD
ERCODE TOPX3,TRMIA% ;(3) ERROR CODE FOR ADDRESS BAD.
ERCODE TOPX4,TRMCD% ;(4) ERROR CODE FOR NOT POSSIBLE TO DO
ERCODE TOPX5,TRMDO% ;(5) ERROR IN DIALLER OPERATION
ERCODE TOPX6,TRMND% ;(6) CAN NOT GET DDB
ERCODE TOPX7,TRMNB% ;(7) ATTEMPT TO SET BREAK MASK WHEN NOT IN BREAK MODE
ERCODE TOPX10,TRMIB% ;(10) ILLEGAL BYTE SIZE
ERCODE TOPX11,TRMNT% ;(11) NOT A NETWORK TERMINAL
;TOPTB0 - TRMOP. ACTION FUNCTIONS LESS THAN 1000
TOP.RP==1B1 ;NEED READ PRIVS TO DO THIS FUNCTION
TOP.WP==1B2 ;NEED WRITE PRIVS TO DO THIS FUNCTION
TOP.NF==1B3 ;NEED F SETUP TO DO THIS FUNCTION
IFN FTMIC,<
TOP.MC==1B4 ;THIS FUNCTION IS LEGAL IF RUNNING MIC
TOP.MR==1B5 ;FUNCTION REQUIRES MIC
>
;FIELD WHICH CONTAINS THE MINIMUM NUMBER OF ARGS WHICH A USER MUST
;SUPPLY FOR A PARTICULAR FUNCTION. THIS FIELD ONLY NEEDS TO BE FILLED
;IN IF THE ARG COUNT IS GREATER THAN 2. IF THE FUNCTION TAKES A VERY
;LONG ARG LIST (LIKE TOPRBS) THEN IT SHOULD DO ITS OWN CHECKING
TOP.CT==7B17
TOPTB0: EXP TOP.RP+TOPSIP ;1 - SKIP IF INPUT PRESENT
EXP TOP.RP+TOPSOP ;2 - SKIP IF OUTPUT PRESENT
EXP TOP.WP+TOPCIB ;3 - CLEAR INPUT BUFFER
EXP TOP.WP+TOPCOB ;4 - CLEAR OUTPUT BUFFER
EXP <3B17>+TOP.RP+TOP.WP+TOPOUC ;5 - OUTPUT CHAR
EXP <3B17>+TOP.RP+TOP.WP+TOP.NF+TOPOIC ;6 - OUTPUT IMAGE CHAR
EXP <3B17>+TOP.RP+TOP.WP+TOPOUS ;7 - OUTPUT STRING
EXP TOP.RP+TOP.WP+TOPINC ;10 - INPUT CHAR
EXP TOP.RP+TOP.WP+TOPIIC ;11 - INPUT IMAGE CHAR
EXP TOP.WP+TOPDSE ;12 - DATASET ENABLE
EXP <4B17>+TOP.WP+TOPDSC ;13 - DATASET CALL
EXP TOP.WP+TOPDSF ;14 - DATASET OFF
EXP TOP.RP+TOP.WP+TOPRES ;15 - RESCAN
EXP <3B17>+TOP.WP+RTZER## ;16 - SET TYPE ELEMENT
EXP TOP.WP+TOPABR ;17 - ENABLE AUTO BAUD DETECT
EXP TOP.RP+TOP.WP+TOPISC ;20 - INPUT CHAR.
EXP <3B17>+TOP.RP+TOP.WP+IFN FTMIC,<TOP.MC>+TOPMTY ;21 - MICTYP
IFN FTMIC,<
EXP <3B17>+TOP.RP+TOP.WP+TOP.MC+TOPMGT ;22 - MICGET
EXP <3B17>+TOP.RP+TOP.WP+TOP.MC+TOP.MR+TOPMST;23 - MICSET
EXP <3B17>+TOP.RP+TOP.WP+TOP.MC+TOPMCL ;24 - MICCLR
>
IFE FTMIC,<
EXP RTZER## ;22 - NOT IMPLEMENTED
EXP RTZER## ;23 - NOT IMPLEMENTED
EXP RTZER## ;24 - NOT IMPLEMENTED
>
EXP <3B17>+TOP.RP+TOP.WP+IFN FTMIC,<TOP.MC>+TOPMDP ;25 - MICDPY
IFN FTMIC,<
EXP <3B17>+TOP.RP+TOP.WP+TOP.MC+TOPMRS ;26 - MICDSP
IFN FTMLOG,<
EXP <3B17>+TOP.MC+TOP.RP+TOP.WP+TOPMLG ;27 - MICLOG
>
IFE FTMLOG,<
EXP RTZER## ;27 - NOT IMPLEMENTED
>
>
IFE FTMIC,<
EXP RTZER## ;26 - NOT IMPLEMEMTED
EXP RTZER## ;27 - NOT IMPLEMENTED
>
EXP TOPDSS ;30 - RETURN DATA SET STATUS
EXP TOP.NF+TOPSBS ;31 - SET BREAK SET MASK TABLE
EXP TOP.NF+TOPRBS ;32 - READ BREAK MASK TABLE
EXP <3B17>+TOP.NF+TOPISO ;33 - IMAGE STRING OUTPUT
EXP TOP.WP+TOPFLM ;34 - FORCE LEFT MARGIN
EXP TOP.NF+TOP.RP+TOPGCS ;35 - GET CHARACTER STATUS
EXP TOP.NF+TOP.WP+TOPSCS ;36 - SET CHARACTER STATUS
EXP TOP.NF+TOP.WP+TOPUNR ;37 - UNREAD
EXP <3B17>+TOP.NF+TOP.WP+TOPASO ;40 - ASCII STRING OUTPUT
EXP TOP.WP+TOPDNT ;41 - DISCONNECT [NETWORK] TTY
IFN FTPATT,<
EXP RTZER## ; - FOR PATCHING
>
TOPLN0==.-TOPTB0
;TOPTB1 - TRMOP. READ/SET FUNCTIONS GREATER THAN 1000
;CONTENTS OF TOPTB1 ARE AS FOLLOWS
;BITS 0-5 ARE RANGE TABLE INDEX FOR RANGE CHECK ON SET.
;BITS 6-17 ARE FLAGS FOR DETERMINING LEGALITY OF TRMOP UUO
;RH IS ADDRESS OF BYTE POINTER.
TOP.SA==1B6 ;SET ALLOWED
TOP.PS==1B7 ;SET ALLOWED FOR PRIVILEGED JOB ONLY
TOP.PE==1B8 ;POKE THE FRONT END IF SET
TOP.RT==1B9 ;FETCH/SET REQUIRES A ROUTINE. ENTERED AT ADDRESS+0
;FOR FETCH, ADDRESS+1 FOR SET. FETCH ROUTINE MUST
;RETURN VALUE IN T1. SET ROUTINE'S RETURN IS PROPAGATED
;BACK TO USER.
TOP.IF==1B10 ;THIS FUNCTION IS ILLEGAL FOR FRCLIN NO MATTER IF
;THE JOB IS PRIVILEGED OR NOT
TOP.BP==1B11 ;THIS FUNCTION TAKES EITHER TWO B.P.S OR A B.P. AND A ROUTINE
;NOTE: THESE DEFINITIONS MUST AGREE WITH LDB DEFINITIONS
TOPTB1::EXP <0>B5+<TOP.RT>+<TOROIP> ;1000
EXP <0>B5+<0>+<LDPCOM> ;1001
EXP <0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBBY2(U),^L<L2RXON>]> ;1002
EXP <0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPLCT> ;1003
EXP <0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBDCH(U),^L<(LDLSLV)>]> ;1004
EXP <0>B5+<TOP.SA+TOP.RT+TOP.BP>+<[EXP LDPTAB,TOPTAB]> ;1005
EXP <0>B5+<TOP.SA+TOP.RT+TOP.BP>+<[EXP LDPFRM,TOPFRM]> ;1006
EXP <0>B5+<TOP.SA+TOP.PE>+<LDPLCP> ;1007
EXP <0>B5+<TOP.SA+TOP.RT+TOP.BP>+<[EXP LDPNFC,TOPNFC]> ;1010
EXP <0>B5+<TOP.SA+TOP.RT>+<TOPHPS> ;1011
EXP <1>B5+<TOP.SA+TOP.RT+TOP.BP>+<[EXP LDPWID,TOPWID]> ;1012
EXP <0>B5+<TOP.SA>+<[POINT 1,LDBBY2(U),^L<(L2LSND)>]> ;1013
EXP 0 ;1014
EXP <0>B5+<TOP.SA+TOP.RT+TOP.IF+TOP.BP>+<[EXP LDPRMT,TOPRMT]> ;1015
EXP <0>B5+<TOP.SA+TOP.PE>+<LDPDIS> ;1016
EXP <2>B5+<TOP.SA+TOP.PE>+<LDPFLC> ;1017
EXP <0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBBY2(U),^L<(L2LTAP)>]>;1020
EXP <0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPXNF> ;1021
EXP <0>B5+<TOP.SA+TOP.RT+TOP.IF+TOP.BP>+<[EXP LDPSTP,TOPXFF]> ;1022
EXP <3>B5+<TOP.SA+TOP.RT+TOP.IF+TOP.BP>+<[EXP LDPSTB,TOPPSZ]> ;1023
EXP <3>B5+<TOP.SA+TOP.RT>+<TOPSTC> ;1024
EXP <0>B5+<TOP.SA>+<[POINT 1,LDBPAG(U),^L<(LPLBLK)>]> ;1025
EXP <0>B5+<TOP.SA+TOP.PE>+<LDPALT> ;1026
EXP <0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPAPL> ;1027
EXP <4>B5+<TOP.SA+TOP.PE>+<LDPRSP> ;1030
EXP <4>B5+<TOP.SA+TOP.PE>+<LDPTSP> ;1031
EXP 0 ;1032
EXP 0 ;1033
EXP 0 ;1034
EXP <5>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPACR> ;1035
EXP <TOP.SA+TOP.PE>+LDPRTC ;1036
EXP <0>B5+<TOP.SA>+<[POINT 36,LDBPBK(U),35]> ;1037
EXP <0>B5+<TOP.SA+TOP.RT+TOP.PE+TOP.BP>+<[EXP LDPDEM,TOPDEM]> ;1040
EXP <0>B5+<TOP.SA+TOP.RT+TOP.IF>+<TOPTTC> ;1041
EXP <0>B5+<TOP.IF>+<[POINT 36,LDBBCT(U),35]> ;1042
EXP <0>B5+<TOP.IF>+<[POINT 36,LDBICT(U),35]> ;1043
EXP <0>B5+<TOP.IF>+<[POINT 36,LDBOCT(U),35]> ;1044
EXP <0>B5+<TOP.SA+TOP.RT+TOP.BP>+<[EXP LDPOSU,TOPSUP]> ;1045
EXP <0>B5+<TOP.SA+TOP.RT+TOP.IF+TOP.BP>+<[EXP LDPFCS,TOPFCS]> ;1046
EXP <0>B5+<TOP.SA+TOP.RT+TOP.IF+TOP.BP>+<[EXP LDPBKA,TOPBKA]> ;1047
EXP 0 ;1050
EXP 0 ;1051
<0>B5+<[POINT 36,LDBTIC(U),35]> ;1052
EXP 0 ;1053
<0>B5+<[POINT 36,LDBBKC(U),35]> ;1054
<0>B5+<[POINT 36,LDBECC(U),35]> ;1055
<0>B5+<TOP.RT>+<TORCCT> ;1056
<0>B5+<[POINT 36,LDBTOC(U),35]> ;1057
<3>B5+<TOP.SA+TOP.IF>+<LDPLNB> ;1060
<3>B5+<TOP.SA+TOP.RT+TOP.IF>+<TOPLNC> ;1061
<3>B5+<TOP.SA+TOP.IF>+<LDPSTB> ;1062
<3>B5+<TOP.SA+TOP.RT+TOP.IF>+<TOPSTC> ;1063
<0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBPAG(U),^L<(LPLFFH)>]> ;1064
<0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBPAG(U),^L<(LPLFFF)>]> ;1065
<0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBPAG(U),^L<(LPLFFS)>]> ;1066
<0>B5+<TOP.SA+TOP.IF>+<LDPSPE> ;1067
<0>B5+<TOP.SA+TOP.IF>+<LDPSST> ;1070
<0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBPAG(U),^L<(LPLSBL)>]> ;1071
<0>B5+<0>+<LDPFSP> ;1072
<0>B5+<0>+<[POINT 1,LDBOFL(U),^L<(L1LOFL)>]> ;1073
<0>B5+<TOP.SA+TOP.RT+TOP.IF>+<TOPECH> ;1074
<0>B5+<LDPAPC> ;1075
<6>B5+<TOP.SA+TOP.IF+TOP.RT+TOP.BP>+<[EXP LDPUNP,TOPUNP]> ;1076
<6>B5+<TOP.SA+TOP.IF+TOP.RT+TOP.BP>+<[EXP LDPESC,TOPESC]> ;1077
<0>B5+<TOP.SA+TOP.IF+TOP.RT>+<TOPSWI> ;1100
<0>B5+<TOP.SA+TOP.IF+TOP.RT+TOP.BP>+<[EXP LDP8BT,TOP8BT]> ;1101
<0>B5+<TOP.SA+TOP.RT+TOP.BP>+<[EXP LDP8BI,TOP8BI]> ;1102
<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPQOT> ;1103
<3>B5+<TOP.PS+TOP.IF+TOP.RT+TOP.BP>+<[EXP LDPMXT,TOPMXT]> ;1104
<0>B5+<TOP.RT>+<TORADT> ;1105
<0>B5+<TOP.IF+TOP.SA+TOP.RT>+<TOPCNE> ;1106
0;<0>B5+<TOP.IF+TOP.SA+TOP.RT>+<TOPEDT> ;1107
<0>B5+<TOP.IF+TOP.SA>+<LDPTTN> ;1110
<0>B5+<TOP.RT>+<TORTCN> ;1111
<0>B5+<TOP.IF+TOP.SA+TOP.BP+TOP.RT>+<[EXP LDPATR,TOPATR]> ;1112
<0>B5+<TOP.IF+TOP.SA+TOP.PE>+<LDPAT2> ;1113
<0>B5+<TOP.IF+TOP.SA+TOP.PE>+<LDPAT3> ;1114
IFN FTPATT,<
EXP 0 ;FOR PATCHING
EXP 0 ;FOR PATCHING
>
TOPLN1==:.-TOPTB1
TOPSYR: POINT 6,TOPTB1(P1),5 ;POINTER TO RANGE TABLE INDEX
;THIS IS THE RANGE TABLE
TOPSRT: XWD ^D16,^D255 ;(1)MIN AND MAX WIDTHS
XWD 0,3 ;(2)MIN AND MAX FILLER CLASSES
XWD 0,^D255 ;(3)MIN AND MAX PAGE LENGTH
XWD 0,17 ;(4)MIN AND MAX SPEED
XWD 0,^D200 ;(5)AUTO C.R. TABLE
XWD 0,CK.CHR ;(6)CHARACTER MAP DEFINITION TABLE
IFN FTPATT,<BLOCK 1> ;FOR PATCHING
SUBTTL TTCALL AND TRMOP. -- SKIPS AND CLEARS
TOPSIP==SKPINC
TOPSOP::SE1ENT ;ENTER SECTION 1
PUSH P,T1 ;SAVE T1 FOR JOBSTS UUO
MOVSI T2,LPLPOK ;THE TTY QUEUED-BY-TOPOKE BIT
TDNN T2,LDBPAG(U) ;IS THE TERMINAL QUEUED FOR SERVICE?
SKIPL T2,LDBDCH(U) ;NO, IS SERVICE CURRENTLY ACTIVE?
.CREF LDLIDL ; (CREF REFERENCE TO SYMBOLIC NAME)
JRST TPOPJ1## ;OUTPUT ACTIVE OR TEMINAL QUEUED
SKIPLE LDBTOC(U) ;REAL CHARACTERS AVAILABLE?
JRST TPOPJ1## ;YES, SKIP RETURN
MOVE T2,LDBOST(U) ;GET OUTPUT STATE BITS
TLNE T2,LOLXFP!LOLNBS!LOLFSP!LOLESP!LOLSAP!LOLREO!LOLREE ;ANYTHING PENDING?
JRST TPOPJ1## ;YES, SKIP RETURN
MOVE T2,LDBBYT(U) ;GET DEFER BITS
SKIPL LDBBKB(U) ;BREAK MASK IS ALWAYS DEFERRED
TRNE T2,L1RDEM ;IF DEFERRED ECHO,
TRNE T2,L1RDEC!L1RDEL ; ONLY IF WANTS INPUT
CAIA ;YES, TEST
JRST TPOPJ## ;NO, IDLE
PUSHJ P,ECCAVL ;ANYTHING YET TO BE ECHOED?
JRST TPOPJ1## ;YES, SKIP RETURN
JRST TPOPJ## ;NO, LINE IS IDLE RETURN
TOPCIB: AOS 0(P) ;SUCCESS RETURN
PJRST TSETBI ;CLEAR INPUT BUFFER
TOPCOB: AOS 0(P) ;SUCCESS RETURN
PJRST TSETBO ;CLEAR OUTPUT BUFFER
;FOLLOWING NOT DONE YET
TOPIIC==RTZER##
SUBTTL TTCALL AND TRMOP. -- TRMOP. I/O
;OUTPUT 1 CHAR
TOPOUC: AOS (P)
PUSHJ P,TOPDDB ;GET A DDB
SETZM F ;NO--DON'T NEED IT BADLY
JRST ONEOUT ;TYPE
;OUTPUT A STRING
TOPMDP: TDZA F,F ;SO CCTYO WILL BE USED (AVOID TIOW)
TOPOUS: SETOM F ;SEARCH FOR A DDB
AOS (P)
PUSHJ P,GETWDU## ;GET POINTER
HRRZ M,T1 ;PUT IN RIGHT AC
JUMPE F,TOPOU1 ;USE CCTYO FOR MIC TYPEOUT
PUSHJ P,TOPDDB ;GET DDB
JRST TOPOU1 ;IF NO DDB
HRRZ T1,TTYTAB##(J) ;CONTROLLING TTY
CAIN T1,(F) ;IS THIS IT?
PJRST OUTSTR ;YES, THEN TOPOUS IS SAME AS OUTSTR
PUSHJ P,SAVE4## ;SET TO JOIN OUTSTR CODE IN MIDDLE
MOVEI P3,TYO7W ;TYPEOUT ROUTINE
PJRST OUTST3 ;JOIN OUTSTR
TOPOU1: PUSHJ P,SAVE4## ;SET TO JOIN OUTSTR CODE IN MIDDLE
MOVE P3,[1B0!CCTYO8] ;NON-BLOCKING OUTPUT
PJRST OUTST3 ;JOIN OUTSTR
;OUTPUT IMAGE CHAR
TOPOIC::AOS (P) ;SKIP RETURN
JRST IONEOU ;TYPE IT
;INPUT A CHAR
TOPISC: SKIPA P1,[EXP INCHRW]
TOPINC: MOVEI P1,INCHWL
AOS (P)
LDB T1,PUUOAC## ;WHERE TO PUT ANSWER
HRR M,T1
PUSHJ P,TOPDDB
SETZB F,S ;NO DDB, NO I/O STATUS
PUSHJ P,TYIEAT ;EAT ANY LEFT-OVER COMMAND
PJUMPN F,(P1) ;INPUT AND BLOCK IF A DDB AVAILABLE
PUSHJ P,TYI ;NO DDB, CAN'T BLOCK, GET CHAR
MOVEI T3,0 ;NONE THERE--RETURN NULL
MOVE T1,T3 ;COPY CHAR
JRST STOTAC## ;STORE FOR USER
;INPUT IMAGE CHAR
TOPIIC==RTZER##
;DO A RESCAN
TOPRES: PUSHJ P,TRESCU ;DO IT
JRST CPOPJ1## ;WIN
JRST CPOPJ1## ;WIN
SUBTTL TTCALL AND TRMOP. -- TRMOP. I/O SUBROUTINES
;GET A DDB FOR TRMOP. I/O
TOPDDB: SETZ S, ;IN CASE NO I/O STATUS AVAILABLE
HRRZ F,LDBDDB(U) ;GET DDB POINTER
JUMPN F,TOPDD2 ;FIND A DDB?
HRLZ T2,LDBDCH(U) ;NO, GET THE LINE STATUS
JUMPGE T2,TOPDD2 ;IS IT A PTY?
LDB T1,LDPLNO ;YES, GET THE TTY NUMBER
HRRZ F,PTYTAB##-PTYOFS##(T1) ;GET DDB ADDRESS, IF ANY
TOPDD2: JUMPE F,TOPDD1 ;ANY DDB THERE?
MOVE S,DEVIOS(F) ;AH - A DDB, GET I/O STATUS
LDB T1,PJOBN## ;YES--IS IT MINE?
CAMN T1,.CPJOB## ; ..
AOSA (P) ;YES--USE IT
SETZ S, ;NO, THEN NO I/O STATUS AFTER ALL
POPJ P, ;RETURN AS APPROPRIATE
TOPDD1: PUSHJ P,TTYNAM ;GET SIXBIT NAME
MOVE T1,T2 ;PUT IN T1
PUSHJ P,GETDDJ ;GET A DDB
POPJ P, ;NONE LEFT
MOVEI T1,ASSPRG ;INIT THE DDB SO
IORM T1,DEVMOD(F) ; IT WILL STICK
MOVE T1,.CPJCH## ; AROUND AND WE
DPB T1,PJCHN## ; CAN WAKE OWNER
MOVE S,DEVIOS(F) ;LOAD UP I/O STATUS WORD
AOS (P) ;SKIP RETURN (CALL?)
PUSHJ P,@0(P) ;CALL OUR CALLER
JRST .+2 ;NON-SKIP
AOS -1(P) ;SKIP
PUSHJ P,TTYREL ;KILL OFF DDB
JRST TPOPJ## ;AND RETURN
SUBTTL TTCALL AND TRMOP. -- TRMOP. DATASET FUNCTIONS
;MORE SUBROUTINES FOR TRMOP
TOPDSE: MOVE T1,LDBDCH(U) ;GET DEVICE CHARACTERISTICS
IFN FTNET,<
SKIPGE LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
PJRST NETDSE ;YES, LET NETSER DO IT
>
TRNN T1,LDRDSD ;IS IT A DATASET?
JRST TOPX4 ;NO. ERROR CODE 4
LDB U,LDPDSC ;GET THE TABLE OFFSET INTO U
MOVSI T1,DSCIC2 ;CLEAR FAILURE, DIALLER FLAGS AND TIMER
ANDCAM T1,DSCTAB##(U) ; ..
MOVSI T1,DSCSWC ;SET TO ALLOW HIM ON
PUSHJ P,DSRRN1 ;SEND TO MODEM HANDLER
JRST CPOPJ1## ;AND SKIP RETURN
TOPDSF::MOVE T1,LDBDCH(U) ;GET DEV CHARACTERISTICS
IFN FTNET,<
SKIPGE LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
PJRST NETDSF ;YES, LET NETSER DO IT
>
TRNN T1,LDRDSD ;IS IT A MODEM
JRST TOPX4 ;NO. CAN'T DO THIS.
PUSHJ P,LDBCLR ;CLEAR OUT LDB
HRRZ F,LDBDDB(U) ;DDB?
JUMPE F,TOPDF1 ;NOT CONTROLLING JOB
MOVE T1,DEVMOD(F)
TLNN T1,TTYATC ;CONTROLLING TTY?
JRST TOPDF1 ;NOPE
PUSHJ P,DSCDET ;DETACH IT
TOPDF1: PUSH P,U ;SAVE U
LDB U,LDPDSC ;GET TABLE INDEX
MOVSI T1,DSCHWC ;CLEAR
ANDCAM T1,DSCTAB##(U)
PUSHJ P,DSROF1 ;HANG IT UP
JRST UPOPJ1## ;AND SKIP RETURN
TOPDSS: MOVE T1,LDBDCH(U) ;CHARACTERISTICS
IFN FTNET,<
SKIPGE LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST NETDSS ;YES, LET NETSER DO IT
>
TRNN T1,LDRDSD ;DATASET?
JRST TOPX4 ;NO, LOSE
LDB U,LDPDSC ;DSCTAB OFFSET
SKIPL DSCTAB##(U) ;HARDWARE CARRIER?
TDZA T1,T1 ;NO
MOVSI T1,DSCHWC ;YES
JRST STOTC1## ;STORE ANSWER FOR USER
IFN FTNET,<
;CODE TO CONTROL REMOTE DATASET LINES
NETDSS: MOVEI T3,DSTSTS ;STATUS
JRST NETISR ;CALL NETSER
NETDSE: MOVEI T3,DSTON ;SET DATASET ON
JRST NETISR ;CALL NETSER
NETDSF: MOVEI T3,DSTOFF ;SET DATASET OFF
JRST NETISR ;CALL NETSER
NETDSC: MOVEI T3,DSTCRQ ;DIALER REQUEST
NETISR: MOVEI T1,ISRDSC ;DATASET CONTROL FUNCTION
PJRST D85DSC## ;CALL NETSER DIRECTLY SINCE NO DATASET TIMING
>
TOPDSC: MOVE T1,LDBDCH(U) ;DEVICE CHARACTERISTICS
IFN FTNET,<
SKIPGE LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST NETDSC ;YES, LET NETSER DO IT
>
TRNN T1,LDRDSD ;DATASET?
JRST TOPX4 ;NO. CAN'T DIAL THEN.
IFN FTMP,<
PUSHJ P,ONCPUL## ;MUST BE ON DEVICES OWN CPU
>
LDB U,LDPDSC ;GET DSCTAB INDEX
MOVE T1,DSCTAB##(U) ;AND BITS
TLNE T1,DSCHWC!DSCSWC ;ALREADY IN USE?
JRST TOPX5 ;YES. CAN'T DIAL ON IT.
TOPDC1: HRRZ T1,DSCTAB##(U) ;GET TERMINAL NUMBER FOR MODEM
CAME T1,DSDUNI## ;BUSY FOR SAME UNIT, OR
AOSN TTYDDL## ;DIALLER FREE?
JRST TOPDC2 ;YES
MOVEI T1,5 ;NO. WAIT FOR IT.
S0PSHJ SLEEP## ; ..
JRST TOPDC1 ;TRY AGAIN
TOPDC2: MOVEM T1,DSDUNI## ;SAVE LINE BEING DIALLED
PUSHJ P,GETWRD## ;FROM USER CORE
JRST TOPX3 ;ADDRESS CHECK
MOVEM T1,DSCNUM ;STORE FOR DIALLER CODE
PUSHJ P,GETWR1## ;AND SECOND WORD
JRST TOPX1 ;ADDRESS CHECK
TRO T1,17 ;GUARANTEE AN END OF NUMBER CODE
MOVEM T1,DSCNUM+1 ;STORE SECOND WORD
MOVSI T1,DSCIC2 ;CLEAR OUT THESE BITS
ANDCAM T1,DSCTAB##(U) ;IN CONTROL TABLE
MOVSI T1,DSCSWC!DSCDLW!^D30
IORM T1,DSCTAB##(U) ;AND SET UP TO WAIT FOR DIALLER
MOVE T1,[POINT 4,DSCNUM]
MOVEM T1,TTYDDA## ;STORE INITIAL POINTER TO NUMBER
MOVEI T3,DSTCRQ ;CALL REQUEST CODE
PUSHJ P,DSCCAL ;TO THE DEVICE HANDLER
TOPDC3: MOVEI T1,^D15 ;SLEEP FOR FIFTEEN SECONDS
S0PSHJ SLEEP## ; ..
MOVE T1,DSCTAB##(U) ;SEE WHAT HAPPENED.
TLNE T1,DSCDLF ;FAIL?
JRST TOPX5 ;YES.
TLNE T1,DSCDLC ;COMPLETED OK?
JRST CPOPJ1## ;YES. SKIP RETURN TO USER
JRST TOPDC3 ;NEITHER YET. LOOP.
SUBTTL TTCALL AND TRMOP. -- AUTOBAUD DETECT, NETWORK DISCONNECT
TOPABR: MOVEI T3,<LPCABR>B27 ;SET UP FUNCTION
MOVEI T1,ISRLPC ;FUNCTION CODE
SKIPL LDBISB(U) ;SKIP IF DC76
JRST TOPX4 ;GIVE ERROR IF STUPID FE
PUSHJ P,@LDBISR(U) ;CALL SERVICE ROUTINE
JRST CPOPJ1## ;GIVE GOOD RETURN
;HERE FOR A DISCONNECT NETWORK TERMINAL REQUEST
TOPDNT::
IFE FTNET,<JRST TOPX11> ;NEED NETWORKS
IFN FTNET,<
MOVEI T1,ISRREM ;REMOTE HANDLER FUNCTION
MOVEI T3,IRRDSC ;DISCONNECT CODE
PUSHJ P,@LDBISR(U) ;TRY TO DISCONNECT IN CANONICAL FASHION
JRST TOPX11 ;POOR CHOICE FOR GENERIC ERROR RETURN
JRST CPOPJ1## ;PROPAGATE SUCCESS
>
SUBTTL TTCALL AND TRMOP. -- SET/READ BREAK FIELD WIDTH/BREAK MASKS
TOPSBS: PUSHJ P,CHKABS ;MUST BE IN BREAK MASK MODE
JRST TOPX7 ;VERY CONFUSED
PUSHJ P,SAVE3## ;SAVE SOME ACS
HLRZ P1,P4 ;GET LENGTH OF USER'S ORIGINAL ARGUMENT
SUBI P1,2 ;ACCOUNT FOR FUNCTION/UDX
JUMPLE P1,CPOPJ1## ;SKIPPING NOOP IF NO MORE ARGUMENTS
PUSHJ P,GETWRD## ;GET BREAK FIELD WIDTH
JRST TOPX3 ;ADDRESS CHECK
CAIL T1,^D1 ;RANGE CHECK ARGUMENT
CAILE T1,^D255 ;MUST BE IN THE RANGE 1-255
JRST TOPX2 ;ARGUMENT OUT OF RANGE
DPB T1,LDPFWD ;STORE FIELD WIDTH
SOJLE P1,CPOPJ1## ;SKIP RETURN IF ONLY CHANGING FIELD WIDTH
MOVEI P2,10 ;MAX. LENGTH OF USER TABLE
MOVE P3,[POINT CC.WID,LDBCSB(U)] ;POINTER TO STATUS BYTES
TOPSB2: MOVEI T1,0 ;STORE A ZERO IF USER DOESN'T SPECIFY
MOVEI T2,^D32 ;NUMBER OF CHARACTERS DESCRIBED PER WORD
SOJL P1,TOPSB3 ;GO IF EXHAUSTED USER ARGUMENT LENGTH
PUSHJ P,GETWR1## ;GET NEXT WORD OF BREAK MASK
JRST TOPX3 ;ADDRESS CHECK
TOPSB3: ILDB T3,P3 ;GET STATUS BYTE
SKIPL T1 ;DO WE WANT THIS ONE TO BREAK?
TRZA T3,CC.BRK!CC.NSA;NO, DON'T LET IT
TRO T3,CC.BRK!CC.NSA;YES, LIGHT THE BITS
CAMN P3,[POINT CC.WID,LDBCSB(U),CC.WID*4-1] ;IS THIS ^C?
JRST [TRO T3,CC.BRK ;YES, IT'S A BREAK
TRZ T3,CC.NSA ;AND GETS ITS SPECIAL ACTION
JRST .+1] ;RE-JOIN MAIN LINE
DPB T3,P3 ;STORE IT BACK
LSH T1,1 ;POSITION FOR NEXT CHARACTER
SOJG T2,TOPSB3 ;NEXT BIT IN USER'S WORD
SOJG P2,TOPSB2 ;GET NEXT WORD OF MASK FROM USER
AOS (P) ;TELL HIM HE DID GOOD
PJRST CHKBKC ;SET LDBBKC CORRECTLY
TOPRBS: PUSHJ P,CHKABS ;INSURE IN BREAK SET MODE
JRST TOPX7 ;NOT, ALLOWING CONTINUATION COULD BE A DISTASTER
PUSHJ P,SAVE3## ;SAVE SOME WORKING ACS
HLRZ P1,P4 ;LENGTH OF ARGUMENT
SUBI P1,2 ;ACCOUNT FOR FUNCTION/UDX
JUMPLE P1,CPOPJ1## ;RETURN IF NO ROOM TO STORE ANYTHING
LDB T1,LDPFWD ;GET FIELD WIDTH
SKIPN T1 ;IS THERE ONE?
MOVEI T1,1 ;NO, FIELD WIDTH IS 1 (BKA)
PUSHJ P,PUTWRD## ;STORE FIELD WIDTH FOR THE USER
JRST TOPX3 ;ADDRESS CHECK
SOJLE P1,CPOPJ1## ;RETURN IF THAT'S ALL HE WANTED
MOVEI P4,10 ;LENGTH OF THE TABLE
MOVE P3,[POINT CC.WID,LDBCSB(U)] ;POINTER TO MONITOR'S TABLE
TOPRB1: MOVSI T2,(1B0) ;BEGINNING BIT (PER WORD) FOR CHARACTER
SETZ T1, ;FOR ACCUMULATING THE MASK
MOVEI T3,^D32 ;NUMBER OF CHARACTERS PER WORD OF MASK
TOPRB2: ILDB T4,P3 ;GET CHARACTER'S STATUS BYTE
TRNE T4,CC.BRK ;IS IT A BREAK?
TDO T1,T2 ;YES, LIGHT ITS BIT
LSH T2,-1 ;POSITION BIT FOR NEXT CHARACTER
SOJG T3,TOPRB2 ;LOOP FOR ENTIRE WORD
PUSHJ P,PUTWR1## ;STORE THIS ENTRY FOR THE USER
JRST TOPX3 ;ADDRESS CHECK
SOJLE P1,CPOPJ1## ;GO IF THAT'S ALL THE USER WANTS TO SEE
SOJG P2,TOPRB1 ;LOOP IF THE ENTIRE TABLE HASN'T BEEN SCANNED
JRST CPOPJ1## ;AND GOOD RETURN
;SUBROUTINE TO SEE IF A DDB IS IN BREAK SET MODE - CPOPJ IF NOT, CPOPJ1 IF SO
CHKABS: MOVE T1,DEVIOS(F) ;GET DEVICE STATUS
TRNE T1,IOSABS ;IN BREAK SET MODE?
AOS (P) ;YES, SKIP RETURN
POPJ P, ;RETURN
SUBTTL TTCALL AND TRMOP. -- SET/READ SPECIAL CHARACTER STATUS
TOPGCS: PUSHJ P,TOPCSS ;SET UP TO LOOP OVER THE ARG BLOCK
POPJ P, ;PROPAGATE ERRORS
JRST TOPGC2 ;NOT IN BREAKSET MODE--RETURN FROM CHTABL
TOPGC1: PUSHJ P,GETWR1## ;GET NEXT CHARACTER REQUESTED
JRST TOPX3 ;ADDRESS CHECK
ANDI T1,CK.CHR ;IGNORE LEFT-OVER CRUFT FROM PREVIOUS TIMES
PUSHJ P,TOPGCB ;GET THE CORRESPONDING BITS IN T2
DPB T2,[POINT 36-8,T1,35-8] ;MERGE INTO ANSWER
PUSHJ P,PUTWRD## ;STORE THE ANSWER BACK
JRST TOPX3 ;ADDRESS CHECK
SOJG P1,TOPGC1 ;LOOP OVER ENTIRE LIST
JRST CPOPJ1## ;RETURN GOODNESS
TOPGCB::MOVE T2,T1 ;COPY THE CHARACTER
ADJBP T2,[POINT CC.WID,LDBCSB(U),CC.WID-1] ;FORM POINTER TO ITS BYTE
LDB T2,T2 ;FETCH THE BYTE
TRNE T1,CK.CH7^!37 ;IS IT A CONTROL CHARACTER?
POPJ P, ;NO, RETURN THE REQUESTED BITS
PUSH P,T1 ;YES, SAVE ORIGINAL CHARACTER
PUSH P,T2 ;SAVE BITS SO FAR
TRNN T1,CK.PAR ;IS IT 7-BIT?
SKIPA T2,LDBCC1(U) ;YES, USE LOW-ORDER 'CLEAR' MASK
MOVE T2,LDBCC2(U) ;NO, USE 8-BIT MASK
ANDI T1,CK.CH7 ;ISOLATE CONTROL PORTION OF CHARACTER
MOVE T1,BITTBL##(T1) ;GET THE CORRESPONDING BIT
TDNN T1,T2 ;IS IT A 'CLEAR' OOB CHARACTER?
JRST TTPOPJ## ;NO, JUST RETURN THE MASK FROM ABOVE
POP P,T2 ;YES, RESTORE MASK
TRO T2,CC.CLR ;FLAG THE SPECIAL STATE
JRST TPOPJ## ;RESTORE ORIGINAL CHARACTER AND RETURN
TOPGC2: PUSHJ P,GETWR1## ;GET NEXT CHARACTER WE CARE ABOUT
JRST TOPX3 ;ADDRESS CHECK
ANDI T1,CK.CHR ;REMOVE LEFTOVER CRUFT
MOVE T2,CHTABL(T1) ;GET OUR BITS FOR THIS CHARACTER
TLNN T2,CHRIA ;IF NO RECINT ACTION,
TRO T1,CC.NSA_8 ;FLAG IN RETURN VALUE
TLNE T2,CHBRK ;IF A BREAK,
TRO T1,CC.BRK_8 ;FLAG IN RETURN VALUE
PUSHJ P,PUTWRD## ;GIVE FLAGS BACK TO USER
JRST TOPX3 ;ADDRESS CHECK
SOJG P1,TOPGC2 ;LOOP OVER ENTIRE ARGUMENT LIST
JRST CPOPJ1## ;RETURN SUCCESS
CC.INV==<<1_^D14>-1>^!CC.MSK ;MASK FOR INVALID SELECT BITS
TOPSCS: PUSHJ P,TOPCSS ;SET UP FOR PROCESSING CHARACTER STATUS BLOCK
POPJ P, ;PROPAGATE ERROR
JRST TOPX7 ;MUST BE IN USER-BREAKSET MODE TO SET BITS
SETZ P3, ;CLEAR FLAGS FOR STATUS MESSAGES
PUSHJ P,TOPSC1 ;PERFORM THE LOOP
SOS (P) ;CANCEL THE COMING SKIP RETURN
TRNE P3,1 ;DID WE CHANGE THE BREAK MASK?
PUSHJ P,CHKBKC ;YES, EXAMINE THE SIDE-EFFECTS
TLNN P3,1 ;DID WE CHANGE ANYTHING ELSE?
JRST CPOPJ1## ;NO, JUST RETURN TO USER
AOS (P) ;WE'LL RETURN SUCCESS
SETOBC: MOVEI T3,IRROOB ;YES, GET OUT-OF-BAND CHANGE CODE
MOVEI T1,ISRREM ;FOR REMOTE HANDLERS
PUSHJ P,@LDBISR(U) ;ATTEMPT TO NOTIFY THEM
PJRST SETCHP ;IT DIDN'T UNDERSTAND, USE GENERAL NOTIFIER
POPJ P, ;AND RETURN
TOPSC1: PUSHJ P,GETWR1## ;GET NEXT CHARACTER TO SET
JRST TOPX3 ;ADDRESS CHECK
TLNN T1,(-1B13) ;ANY 'SELECT' BITS ON?
JRST TOPSC2 ;NO, DON'T BOTHER
TLNE T1,(<CC.INV>B13);YES, ARE THEY ALL LEGAL?
JRST TOPX2 ;NO, GIVE RANGE ERROR
MOVE T3,T1 ;COPY THE ARGUMENT (TO KEEP IT SAFE)
ANDI T1,CK.CHR ;ISOLATE THE AFFECTED CHARACTER
PUSHJ P,TOPGCB ;GET THE CHARACTER'S BYTE
MOVE T4,T3 ;COPY ORIGINAL ARGUMENT AGAIN
LSH T4,-8 ;RIGHT-JUSTIFY NEW VALUE SECTION
LSH T3,^D<14-36> ;AND SELECTOR MASK
AND T4,T3 ;KEEP ONLY BITS WE CARE ABOUT
ANDCA T3,T2 ;ISOLATE BITS WE WANT TO KEEP
IORB T3,T4 ;INCLUDE THE NEW ONES
CAMN T2,T3 ;ARE WE CHANGING ANYTHING?
JRST TOPSC2 ;NO, SKIP SOME OVERHEAD
XOR T4,T2 ;YES, GET MASK OF REAL CHANGES
TRNE T1,CK.CH7^!37 ;YES, IS IT A CONTROL CHARACTER?
TRZ T4,CC.CLR ;NO, CAN'T BE A CLEAR CHARACTER
JUMPE T4,TOPSC2 ;SKIP AROUND IF NOT CHANGING ANYTHING AFTER ALL
TRNE T4,CC.BRK ;CHANGING BREAK STATUS?
TRO P3,1 ;YES, FLAG FOR EXIT ROUTINE
TRNE T4,^-CC.BRK ;CHANGING ANYTHING ELSE?
TLO P3,1 ;YES, FLAG THAT TOO
MOVE T2,T1 ;COPY CHARACTER WE'RE AFFECTING
ADJBP T2,[POINT CC.WID,LDBCSB(U),CC.WID-1] ;POINT TO ITS BYTE
DPB T3,T2 ;STORE THE NEW BITS
TRNN T4,CC.CLR ;WANT TO CHANGE 'CLEAR' STATUS?
JRST TOPSC2 ;NO, SO DON'T
TRNN T3,CC.CLR ;WANT IT ON?
SKIPA T2,[ANDCAM T1,LDBCC1(U)] ;NO, WE'LL CLEAR IT
MOVE T2,[IORM T1,LDBCC1(U)] ;YES, WE'LL LIGHT IT
TRZE T1,CK.PAR ;IS IT EIGHT-BIT?
HRRI T2,LDBCC2 ;YES, AFFECT RIGHT WORD
MOVE T1,BITTBL##(T1) ;GET THE CORRESPONDING BIT
XCT T2 ;TWIDDLE APPROPRIATELY
TOPSC2: SOJG P1,TOPSC1 ;LOOP OVER ENTIRE ARGUMENT LIST
JRST CPOPJ1## ;SUCCESS RETURN
;HERE TO SET UP TO LOOP OVER THE CHARACTER STATUS BLOCK FOR .TOGCS & .TOSCS
;RETURNS NON-SKIP WITH ERROR CODE ALREADY DELIVERED,
;OR SKIP WITH M SETUP FOR GETWR1 & P1 WITH THE BLOCK LENGTH.
;DOUBLE-SKIP IF IOSABS IS ON.
TOPCSS: HLRZ T1,P4 ;GET LENGTH AGAIN
CAIL T1,3 ;DO WE HAVE OUR POINTER?
PUSHJ P,GETWRD## ;YES, FETCH IT
JRST TOPX3 ;NO, GIVE ADDRESS CHECK
HLRZ T2,T1 ;ISOLATE LENGTH
CAILE T2,0 ;IS IT IN RANGE
CAILE T2,CK.CHR+1 ;OF REASONABLE VALUES?
JRST TOPX2 ;NO, GIVE RANGE ERROR
HRLI T1,(IFIW) ;USE SECTION-LOCAL ADDRESSING
PUSHJ P,ARNGE## ;SEE IF IT LOOKS LIKELY
JRST TOPX3 ;ADDRESS CHECK
JFCL ;IGNORE ILLEGAL FOR I/O HERE
HRRI M,-1(T1) ;POINT TO TABLE (OFFSET FOR GETWR1)
MOVE P1,T2 ;COPY THE LENGTH
PUSHJ P,CHKABS ;SEE IF IOSABS IS ON
JRST CPOPJ1## ;RETURN PARTIAL SUCCESS
JRST CPOPJ2## ;COMPLETE SUCCESS
CLRCSB: SETZM LDBBKB(U) ;NO BREAK MASK STATUS
SETZM LDBCSB(U) ;STORE A ZERO IN SPECIAL STATUS AREA
IFN FTXMON,<
MOVEI T1,LDBCSL+2-1 ;NUMBER OF WORDS TO ZERO
XMOVEI T2,LDBCSB(U) ;SOURCE
XMOVEI T3,LDBCSB+1(U) ;DESTINATION
EXTEND T1,[XBLT] ;ZERO THE STATUS BYTES
>
IFE FTXMON,<
MOVSI T1,LDBCSB(U) ;SOURCE
HRRI T1,LDBCSB+1(U) ;DESTINATION
BLT T1,LDBCC2(U) ;CLEAR OUT THE STATUS BYTES
>
SCNOFF ;FOR CHUNK HANDLING
MOVSI T1,LMLSSE ;SWITCH SEQUENCE ENABLED BIT
ANDCAM T1,LDBCHM(U) ;NOT IF YOU CAN'T TAKE THE PSI
DPB T1,LDPSWI ;AND CLEAR THE CHARACTERS
PUSHJ P,TYBVRG ;MAKE A VIRGIN OOB STREAM
JRST SONPPJ ;RETURN, ALLOWING OTHERS AGAIN
SUBTTL TTCALL AND TRMOP. -- UNREAD FUNCTION
TOPUNR: AOS (P) ;WE WILL SUCCEED
SETUNR: MOVSI T2,L1LUNR ;UNREAD IN PROGRESS BIT
IORM T2,LDBBYT(U) ;SET IT
MOVEI T2,L1RDEL!L1RDEC ;DEFERRED ECHO ALLOWED BITS
ANDCAM T2,LDBBYT(U) ;CLEAR
PJRST RCVWKQ ;RETURN TRYING TO FORCE A WAKEUP
CLRUNR: PUSH P,T1 ;SAVE SOME ACS
PUSH P,T2 ;THAT GET USED
MOVSI T1,L1LUNR ;UNREAD BIT
ANDCAM T1,LDBBYT(U) ;CLEAR IT
PUSHJ P,TOPOKE ;MAKE SURE ECHOING CAN BE RESTARTED IF DESIRED
JRST TTPOPJ## ;RESTORE ACS & RETURN
SUBTTL TTCALL AND TRMOP. -- TYPE INTO TTY ON BEHALF OF A USER
; TOPMTY TYPE A STRING ON BEHALF OF USER
;ADDR: LINE NO.
; [ASCIZ/STRING/]
TOPMTY: PUSHJ P,SAVE4## ;SAVE AN AC
LDB P1,LDPLNO ;LINE NUMBER
PUSHJ P,GETWRD## ;GET ADDRESS OF STRING
JRST TOPX3 ;ADDRESS CHECK
HRRI M,-1(T1) ;AND PUT IT IN M FOR FUTURE GETWD1'S
HRROS T1 ;LEFT JUSTIFIED ASCIZ STRING
PUSHJ P,CKSTRL## ;MAKE SURE ITS IN CORE AND LEGAL
JRST TOPX3 ;ADDRESS CHECK
CAIL T2,TTIMAX## ;WILL IT EVER FIT?
JRST TOPX2 ;NO, GIVE RANGE ERROR
JUMPE T2,CPOPJ1## ;SUCCEED VACUOUSLY IF NO CHARACTERS TO TYPE
MOVE P4,T2 ;SAVE STRING LENGTH
AOS (P) ;GIVE GOOD RETURN
MOVEI T4,10000 ;MAXIMUM LOOP COUNT IF TOO FEW CHUNKS
MOVEI T1,L1RMIF ;THE MIC INTERLOCK FLAG
TOPMT0: SCNOFF ;GET THE GLOBAL INTERLOCK
TDNE T1,LDBBYT(U) ;IS THE INTERLOCK AVAILABLE?
JRST TOPMT3 ;NO, WAIT FOR IT
MOVE T2,LDBTIC(U) ;YES, GET INPUT COUNT
ADD T2,LDBECC(U) ;AND ECHO COUNT
ADD T2,P4 ;PLUS OUR STRING COUNT
CAIL T2,TTIMAX## ;CAN WE DO IT?
SOJG T4,TOPMT3 ;NO, WAIT A WHILE
IDIVI T2,CK.CPC## ;YES SO FAR, BUT SEE HOW MANY CHUNKS WE NEED
CAML T2,TTFREN## ;DO WE HAVE THEM AVAILABLE?
SOJG T4,TOPMT3 ;NO, WAIT A WHILE
IORM T1,LDBBYT(U) ;YES, GET THE INPUT INTERLOCK
SCNON ;AND ALLOW OTHERS AGAIN
TOPMT1: MOVE P3,[POINT 7,P2] ;SET UP BYTE POINTER
PUSHJ P,GETWD1## ;GET NEXT WORD OF ASCIZ STRING
MOVE P2,T1 ;AND SAVE IT
TOPMT2: TLNN P3,760000 ;END OF CURRENT WORD?
JRST TOPMT1 ;YES - GET NEXT ONE
ILDB T3,P3 ;GET NEXT CHAR
JUMPE T3,TOPMT4 ;END OF STRING, WAKE CONTROLLER
MOVE U,LINTAB##(P1) ;SET LDB ADDRESS
PUSHJ P,RECINM ;TYPE IT
JRST TOPMT2 ;NEXT CHAR
TOPMT3: SCNON ;ALLOW OTHERS AGAIN
PUSHJ P,SCDCHK## ;SEE IF SCHEDULAR WANTS TO DO ANYTHING
JRST TOPMT0 ;AND TRY AGAIN
TOPMT4: PUSHJ P,RECINU ;RETURN THE MIC INTERLOCK
JRST PTSTRT ;START CONTROLLER
;TOPTYP -- TYPE ONE CHARACTER FOR USER
;CALL WITH CHARACTER IN T3, LDB IN U
MICLOK: SE1ENT ;MUST BE IN PROPER SECTION
PUSH P,T1 ;PRESERVE A REGISTER
MOVEI T1,L1RMIF ;MIC INTERLOCK BIT
MICLK1: SCNOFF ;NO INTERRUPTS WHILE SETTING LOCK
TDNE T1,LDBBYT(U) ;CHECK INTERLOCK
JRST [SCNON ;ALLOW PENDING INTERRUPTS
JRST MICLK1] ;TRY AGAIN
IORM T1,LDBBYT(U) ;SET THE INTERLOCK BIT
JRST SONTPJ ;RESTORE T1, RETURN INTERLOCK AND RETURN
MICULK::SE1ENT ;RUN IN PROPER SECTION
PJRST RECINU ;RETURN 'MIC' INTERLOCK
MICREC: SE1ENT ;RUN IN PROPER SECTION
PJRST RECINM ;RECEIVE A CHARACTER FOR MIC
SUBTTL TTCALL AND TRMOP. -- MIC -- SET/CLEAR LDBMIC
IFN FTMIC, <
; MICCLR - CLEAR DOWN LDBMIC
;ADDR: LINE NO.
; MICSET - SET UP LDBMIC
;ADDR: LINE NO.
; STATUS
;
; BOTH GIVE OLD CONTENTS OF LDBMIC IN ADDR+1
TOPMCL: SETZ T1, ;SET IMPLIED ZERO ARGUMENT
JRST TOPMS1 ;JOIN MIC SET CODE
TOPMST: PUSHJ P,GETWRD## ;GET THE ARGUMENT
JRST TOPX3 ;ADDRESS CHECK
PUSH P,T1
ANDI T1,177 ;MASK DOWN TO JOB NUMBER
CAMLE T1,HIGHJB## ;ISOLATE JOB NUMBER
JRST [POP P,T1
PJRST ECOD2##] ;RETURN ERROR CODE 2 (OUT OF RANGE)
POP P,T1
TLZ T1,LDLMTI!LDLMMM;CLEAR INTERNAL BITS
TOPMS1: MOVSI T2,LOLMIC ;GET THE MIC ACTIVE BIT
SKIPE T1 ;...
IORM T2,LDBOST(U) ; SET OR
SKIPN T1 ;...
ANDCAM T2,LDBOST(U) ; CLEAR AS NEEDED
EXCH T1,LDBMIC(U) ;SET NEW VALUE, RETURN OLD
AOS (P) ;GOOD RETURN
SKIPE LDBMIC(U) ;IF WE DIDN'T CLEAR IT,
JRST TOPMS2 ;THEN DON'T ANNOY BATCON
PUSH P,T1 ;SAVE STATUS TO RETURN
MOVEI T1,LDRPTY ;A PTY?
TDNE T1,LDBDCH(U)
PUSHJ P,PTYOW## ;YES, TELL BATCON
POP P,T1 ;RESTORE OLD STATUS
TOPMS2: PJRST PUTWDU## ;GIVE USER OLD MIC WORD
;STILL IN IFN FTMIC
SUBTTL TTCALL AND TRMOP. -- MIC -- RETURN MIC STATUS
; MICGET - GET STATUS
;ADDR: LINE
; RETURN RESULT TO ADDR+1
TOPMGT: PUSHJ P,SAVE1## ;SAVE AN AC
SKIPN P1,LDBMIC(U) ;IS MIC RUNNING US?
JRST TOPMG1 ;NO FAIL RETURN
HRRZ F,LDBDDB(U) ;SET UP F
JUMPE F,TOPMG1 ;ZERO MEANS HE LOGGED OUT -LOOSE HIM
LDB J,PJOBN## ;OTHERWISE - GET HIS JOB NO
IFN FTMP,<
CAMN J,COMJOB## ;ON THE SAME CPU AS US
PUSHJ P,ONCPU0## ;NO, GET HIM THERE
>
PUSHJ P,UJBSTX## ;GO GET JBTSTS
TLZ P1,LDLMMM!LDLMTI!LDLMUI!LDLCL1 ;CLEAR VOLATILE BITS
TLNE T1,(JB.UML) ;IN MONITOR MODE?
TLO P1,LDLCHK!LDLMMM;YES - SET FLAGS
TLNE T1,(JB.UDI) ;READY FOR I/P?
TLO P1,LDLCHK!LDLMTI;YES - SET FLAGS
TLNE T1,(JB.UHI) ;JOB HIBERING FOR INPUT?
TLO P1,LDLCHK!LDLMUI;YES - SET FLAGS
IFN FTMLOG,<
HRRZ T1,LDBLOC(U)
SKIPE T1
TLO P1,LDLCHK!LDLCL1;SET TO FLAG
> ;END OF FTMLOG CONDITIONAL
SKIPGE LDBCOM(U) ;COMMAND WAITING?
TLZ P1,LDLMTI!LDLMUI;YES - CLEAR TI BITS
MOVE T1,P1 ;PUT LDBMIC INTO T1 FOR
AOS (P) ;GOOD RETURN
PJRST PUTWDU## ;RETURNING TO USER
TOPMG1: MOVSI T1,LOLMIC ;THE CONTROLLED-BY-MIC BIT
ANDCAM T1,LDBOST(U) ;CLEAR FOR XMTCHR
SETZM LDBMIC(U) ;CLEAR DOWN LDBMIC
MOVEI T1,LDRPTY ;IF A PTY
TDNE T1,LDBDCH(U) ;(TEST)
PUSHJ P,PTYOW## ;NOTIFY BATCON
SETZ T1, ;NO STATUS TO RETURN
PJRST PUTWDU## ;AND EXIT
;STILL IN IFN FTMIC
SUBTTL TTCALL AND TRMOP. -- MIC -- READ ERROR RESPONSE TEXT
; MICRSP : RECORD ERROR MESSAGE
;ADDR: LINE NO.
; ADDRESS OF SPACE TO RETRIEVE RESPONSE
TOPMRS: SKIPE T2,LDBMIC(U) ;RUNNING MIC
TLNN T2,LDLERC ;ERROR?
JRST TOPX4 ;NO
TLNN T2,LDLRSY ;MAKE SURE GOT TO INT LEVEL WITH SYNC
JRST TOPX4 ;NO
PUSHJ P,GETWRD## ;GET ADDRESS OF RESPONSE BUFFER
JRST TOPX3 ;ADDRESS CHECK
PUSHJ P,MICADC
JRST TOPX3 ;ADDRESS CHECK OF BUFFER
PUSHJ P,SAVE3## ;SAVE WORKING ACS
MOVSI P1,(<POINT 7,>)
ADDI P1,(T1)
MOVEI P2,<21*5>-1 ;MAX SPACE IN BUFFER
CAMLE P2,LDBTOC(U) ;GOT THIS MANY?
MOVE P2,LDBTOC(U) ;NO - USE LESSER
JUMPLE P2,TOPX4 ;NO CHARACTERS
SKIPN P3,LDBTOT(U) ;GET CHAR ADDRESS OF ERROR LINE
JRST TOPX4 ;HASN'T GOT ONE?
SCNOFF ;PROTECT CHUNK LIST
TOPMR1: LDCHK T3,LDBTOT(U),TOPMR3 ;GET NEXT CHARACTER
TOPMR2: EXCTUU <IDPB T3,P1>
JUMPE T3,TOPMR3 ;EXIT HAVING MADE ASCIZ
SOJG P2,TOPMR1 ;GET NEXT CHAR
SETZ T3, ;MAKE ASCIZ
JRST TOPMR2
TOPMR3: MOVEM P3,LDBTOT(U) ;RESTORE POINTER
SCNON ;THE CHUNKS ARE SAFE ONCE AGAIN
MOVSI T1,LDLRSP!LDLRSY;CLEAR RESPONSE FLAG
ANDCAM T1,LDBMIC(U)
AOS (P) ;GOOD RETURN TO THE USER
PJRST TOPOKE ;START UP TERMINAL OUTPUT - GOOD EXIT
;STILL IN IFN FTMIC
SUBTTL TTCALL AND TRMOP. -- MIC -- LOG ALL TERMINAL OUTPUT
IFN FTMLOG,<
; MICLOG: RECORD ALL UUO LEVEL OUTPUT
;ADDR: LINE NUMBER
; ADDR LOG BUFFER
TOPMLG: SKIPE T2,LDBMIC(U) ;RUNNING MIC?
TLNN T2,LDLLOG ;WANT LOG FEATURE?
JRST TOPX4
PUSHJ P,GETWRD##
JRST TOPX3 ;ADDRESS CHECK
PUSHJ P,MICADC ;ADDRRESS CHECK ALL OF BUFFER
JRST TOPX3 ;ADDRESS CHECK
AOS (P) ;SET FOR GOOD RETURN TO THE USER
PUSHJ P,SAVE2## ;SAVE WORKING ACS
MOVSI P1,440700
HRRI P1,(T1)
MOVEI P2,<21*5>-1
TOPML1: SCNOFF ;DOWN PI SYSTEM
SOSGE LDBLOC(U) ;CHECK COUNT
JRST [SETZB T3,LDBLOC(U) ;FIX COUNT
JRST TOPML2] ;JOIN PROCESSING
LDCHKR T3,LDBLOT(U),TOPML9 ;TAKE A BYTE
TOPML2: SCNON ;TURN PI'S BACK ON
TOPML3: EXCTUU <IDPB T3,P1>
JUMPE T3,XMTWAK
SOJG P2,TOPML1
SETZ T3,
JRST TOPML3 ;LOOP UNTIL COUNT EXHAUSTED OR END BUFFER
TOPML9: SETZB T3,P2 ;TERMINATE THE UUO
JRST TOPML2 ;AND RESTORE THE TERMINAL SERVICE INTERLOCK
> ;END OF FTMLOG CONDITIONAL
;STILL IN IFN FTMIC
SUBTTL TTCALL AND TRMOP. -- MIC -- MISCELLANEOUS MIC SUBROUTINES
IFN FTMLOG,<
; HERE WITH SCANNER INTERRUPTS DISABLED
MICLGC: MOVE T1,LDBMIC(U) ;GET MIC STATUS
TLNN T1,LDLLOG ;LOGGING?
JRST MICLG1 ;NO-MIC HAS GIVEN UP MUST TIDY
MOVE T1,LDBTOP(U) ;MOVE TAKER TO PUTTER
MOVEM T1,LDBTOT(U) ;SO MIC CAN CATCH UP WITH PUTPUT
MOVE T1,LDBTOC(U) ;REMEMBER HOW MANY
ADDM T1,LDBLOC(U) ;KEEP TRACK FOR MIC
JRST MICLG2
;MIC HAS GONE AWAY MUST TIDY UP LOG BUFFER
MICLG1: MOVE T1,LDBLOT(U) ;MOVE PUTTER AND TAKER
MOVEM T1,LDBTOT(U)
MOVEM T1,LDBTOP(U) ;BACK UP
SETZM LDBLOT(U) ;ZAP LOG BUFFER
MICLG2: SETZM LDBTOC(U) ;ZAP COUNT
JRST SONPPJ ;AND EXIT
> ;END OF FTMLOG CONDITIONAL
;STILL IN IFN FTMIC
;SUBROUTINE TO ADDRESS CHECK A USER BUFFER
MICADC: PUSH P,M
PUSH P,T1
HRRI M,(T1)
PUSHJ P,GETWRD##
JRST MICAD1
HRRI M,21(M)
PUSHJ P,GETWRD##
TRNA
AOS -2(P)
MICAD1: POP P,T1
JRST MPOPJ##
;STILL FTMIC
;SUBROUTINE TO SET UP HORIZONTAL POSITION FOR MIC AND TO CHECK FOR
;OPERATOR AND ERROR CHARS IN COLUMN 1
MICPOS: SKIPN T2,LDBMIC(U) ;MIC RUNNING FOR THIS LINE?
POPJ P, ;NO, RETURN IMMEDIATELY
PUSH P,T3 ;PRESERVE CHAR
TRNN T3,CK.IMG ;IF NOT IMAGE,
TRNN T3,CK.MET ;UNLESS META-CHARACTER,
ANDI T3,CK.CHR ;MASK OFF BITS
PUSHJ P,SPCHEK ;GET CHARACTERISTICS OF CHAR
JRST MICPS2 ;NOT SPECIAL
TLNN T1,CHCRET ;IS IT <CR>?
JRST MICPS1 ;NOT - MUST CHECK OTHERS
TLO T2,LDLCL1 ;SET COL 1 FLAG IN MICLDB
MOVEM T2,LDBMIC(U)
MOVSI T1,L1LEEL ;EOL IN ERROR STREAM BIT
TLNE T2,LDLERC ;SEEN AN ERROR CHARACTER?
IORM T1,LDBBYT(U) ;YES--FLAG EOL FOR XMTMIC
JRST T3POPJ## ;AND RETURN
MICPS1: CAIE T3,177 ;IS IT A RUBOUT
CAIN T3,12 ;OR LINE-FEED
JRST T3POPJ## ;YES - NO CHECKING
MICPS2: TLZN T2,LDLCL1 ;ARE WE IN COLUMN 1?
JRST T3POPJ## ;NO - RETURN
LDB T1,LDP.OP ;GET OPERATOR CHAR
JUMPE T1,MICPS4 ;JUMP IF NOT SET
CAMN T1,T3 ;HAVE WE FOUND ONE?
TLO T2,LDLCHK!LDLOPC;YES - SET BITS
MICPS4: LDB T1,LDP.ER ;GET ERROR CHAR
JUMPE T1,MICPS3 ;IF NO ERROR
CAIE T3,"?" ;"?" ERROR CHARACTER
CAMN T1,T3 ;ONE OF THOSE?
TLOA T2,LDLCHK!LDLERC;YES - SET ITS FLAGS
JRST MICPS3 ;SKIP ON
MOVSI T1,L1LEEL ;EOL IN ERROR STREAM BIT
ANDCAM T1,LDBBYT(U) ;CLEAR IT
MICPS3: MOVEM T2,LDBMIC(U) ;STORE MIC WORD
JRST T3POPJ## ;RESTORE T3, AND RETURN
;STILL IN IFN FTMIC
;STILL FTMIC
IFN FTMLOG,<
;A ROUTINE TO FREE THE MIC LOG BUFFER IF REQUIRED
MLOGOF: SKIPN LDBLOT(U) ;HAS NOT GOT ONE
POPJ P,0
SCNOFF ;SNEAKY PEEK
SKIPE LDBTOC(U) ;OUTPUT BUFFER IDLE
JRST SONPPJ ;NO FORGET IT
JRST MICLG1 ;YES-GO ZAP LOG BUFFER AND TURN ON PI
> ;END OF FTMLOG CONDITIONAL
;ROUTINE TO WAKE MIC UP WHEN CONTROLLED JOB REQUIRES INPUT
MICWAK: LDB T1,LDPMJN ;LOAD MASTER JOB NO.
CAMLE T1,HIGHJB## ;JOB NUMBER TOO BIG?
JRST MICWA1 ;YES JUST RETURN
MOVE T2,JBTSTS##(T1) ;CHECK JOB STATUS
TLNN T2,JLOG ;LOGGED IN?
JRST MICWA1 ;NO JUST RETURN
PUSH P,T3 ;SAVE CHARACTER
PUSHJ P,WAKJOB## ;GO WAKE MIC
POP P,T3 ;RESTORE CHARACTER
MICWA1: MOVE T1,LDBDCH(U) ;RESTORE C(U)
POPJ P, ;AND RETURN
MICECH: TLNN T1,CHCRET ;IS IT A <CR>?
POPJ P, ;NO, RETURN
PUSH P,T1 ;SAVE T1
MOVSI T1,LDLCL1 ;YES, SET COL 1 BIT
IORM T1,LDBMIC(U) ; IN LDBMIC
JRST TPOPJ## ;RETURN
MICCHK: PUSHJ P,UUOLVL## ;IS .CPJOB EVEN MEANINGFUL HERE?
JRST CPOPJ1## ;NO, DO THINGS FOR MIC
PUSH P,T1 ;SAVE A REGISTER
LDB T1,LDPMJN ;GET MIC MASTER JOB FOR THIS LDB
CAMN T1,.CPJOB## ;IS MIC TYPING THIS?
SKIPN LDBMIC(U) ;I MEAN REALLY?
AOS -1(P) ;NO, DO THINGS FOR MIC
JRST TPOPJ## ;RESTORE & RETURN
MICRIC: PUSHJ P,MICCHK ;IS MIC TYPING THIS?
POPJ P, ;YES, IGNORE IT
MICPRC: CAIN T3,1 ;IS THE CHAR A ^A
JRST MICRIA ;YES - GO DEAL WITH ^A
TLO T1,LDLCHK!LDLMCC;SAY THAT ^C WAS TYPED
MOVEM T1,LDBMIC(U) ;PUT IT BACK
POPJ P, ;AND RETURN
;STILL FTMIC
MICRIA: TLO T1,LDLCHK!LDLMCA;SAY ^A
MOVEM T1,LDBMIC(U) ;PUT IT AWAY!
TRC T3,2 ;CONVERT CHAR INTO A ^C
MOVSI T1,CHBRK!CHCRE!CHCNC
IORM T1,-1(P) ;AND SET UP BITS TO LOOK LIKE ^C
POPJ P,
PTYMCK: CAIN T3,20
TLO T2,LDLCHK!LDLMCP
CAIN T3,2
TLO T2,LDLCHK!LDLMCB
MOVEM T2,LDBMIC(U)
TLNE T2,LDLMCP
JRST RICB3
JRST PTYPT1
> ;END IFN FTMIC
;CO-ROUTINE TO SETUP U AND .CPTOA SO THAT THE MONITOR CAN TYPE
; A COMMAND AT ITSELF. USES LDB CORRESPONDING TO FRCLIN
FRCSET::EXCH U,(P) ;GET CALLER'S PC, SAVE U
PUSH P,.CPTOA## ;SAVE .CPTOA
PUSH P,U ;WHERE TO RETURN TO CALLER
MOVE U,LINTAB##+FRCLIN## ;LDB
PUSHJ P,MICLOK ;GET 'MIC' INTERLOCK FOR FRCLIN
MOVEI U,MICREC ;PUT CHARS INTO INPUT
MOVEM U,.CPTOA## ; STREAM
MOVE U,LINTAB##+FRCLIN## ;LDB
POP P,(P) ;ADJUST STACK
PUSHJ P,@1(P) ;CALL CALLER AS A SUBROUTINE
CAIA ;NON-SKIP
AOS -2(P) ;PROPAGATE SKIP
MOVE U,LINTAB##+FRCLIN## ;LDB
PUSHJ P,MICULK ;RETURN FRCLIN'S 'MIC' INTERLOCK
POP P,.CPTOA## ;RESTORE .CPTOA
JRST UPOPJ## ;RESTORE U AND RETURN
SUBTTL SUBROUTINES FOR I/O
;SUBROUTINE TO READ A CHARACTER AND KEEP THE BREAK COUNT RIGHT
;
;IT IS ASSUMED THAT THE CALLER HAS DONE ANY NECESSARY WAITING. THERE
;ARE TWO UNUSUAL CASES: FIRST, IF THERE ARE NO CHARACTERS IN THE
;BUFFER, TYI WILL NON-SKIP RETURN. IF THE CHARACTER READ IS A
;CONTROL C, AND IF THE TERMINAL IS IN USER MODE, NOT SLAVED, NOT
;IN IMAGE INPUT STATE, AND NOT RUNNING UNDER JACCT, THEN TYI CALLS
;ROUTINES TO PUT CONSOLE AT MONITOR LEVEL, AND GOES BACK INTO I/O
;WAIT UNTIL A POSSIBLE CONTINUE COMMAND.
;
;IT IS THE CALLER'S RESPONSIBILITY TO EAT ANY POSSIBLE COMMAND LEFT
;LYING AROUND (I.E., CALL TYIEAT).
;
;TYICC USES P3! BE WARNED!
TYIS: PUSHJ P,SAVE3## ;REALLY SHOULD DO IT
SETOM P3 ;FLAG DON'T WAIT IF NOTHING THERE
JRST TYICC2
TYI: PUSHJ P,SAVE3##
TDZA P3,P3 ;FLAG WAIT ON ^C, CONTINUE
TYICC: TDZA P3,P3 ;FLAG WAIT ON ^C, CONTINUE SEQUENCE
TYICC2: SETZB P1,P2 ;INDICATE NO BUFFER
TYICC3: TRNE S,IODERR ;HAS HE GOTTEN A ^C?
POPJ P, ;YES, FORGET IT
TYICC4: SCNOFF ;NO RACES
MOVSI T1,LDLCRP!LDLDIP ;GET CONTROL-R BITS
TDNN T1,LDBDCH(U) ;IN COMPETITION WITH COMCON?
JRST TYICC5 ;NO, GO READ A CHARACTER
SCNON ;YES, RELEASE INTERLOCK
JUMPN P3,CPOPJ## ;RETURN IF ASYNCH
SETZ T1, ;NOT, SO SLEEP
S0PSHJ SLEEPF## ;FOR A JIFFY
JRST TYICC4 ;AND TRY AGAIN
TYICC5: MOVE T1,LDBTIT(U) ;GET INPUT TAKER
CAME T1,LDBECT(U) ;AVOID TIC STOPCDS
SOSGE LDBTIC(U) ;ANY LEFT TO INPUT?
JRST TYICCZ ;FIX INPUT COUNT AND RESTORE PI
LDCHKR T3,LDBTIT(U),TYICCZ ;GET CHARACTER
MOVSI T2,L3LIHD ;GET IN MIDDLE OF CHARACTER EXPANSION BIT
TDNN T2,LDBBY3(U) ;ARE WE?
TRNE T3,CK.NIS ;NON-EXISTENT CHARACTER?
TRNA ;EITHER TRUE, WE DON'T STORE THIS
PUSHJ P,EDTSTO ;STORE THE CHARACTER
PUSHJ P,TPCINP ;FUDGE 2-PART INPUT CHARACTERS
MOVE T2,LDBTIT(U) ;INPUT TAKER POINTER
CAMN T2,LDBBKU(U) ;TAKEN LAST BREAK?
SETZM LDBBKU(U) ;YES, ZAP POINTER TO IT
SCNON ;ALLOW INTERRUPTS
PUSH P,T3 ;PRESERVE CHAR.
SKIPG LDBTIC(U) ;IS THIS THE LAST CHARACTER IN THE BUFFER
PUSHJ P,CHKXON ;YES, GO CHECK IF XON IS NEEDED
POP P,T3 ;RESTORE CHAR.
SETZ T1, ;FOR TTYIN2
TRNE T3,CK.NIS ;NON-REAL CHARACTER?
JRST [SOS LDBIIC(U) ;YES, COUNT ANOTHER GONE
JRST TYICC4] ;AND TRY FOR A REAL ONE
TRNE T3,CK.IMG ;IMAGE CHARACTER?
JRST CPOPJ1## ;YES, DONE HERE
TRNE T3,CK.MET ;LEFT-OVER TRASH CHARACTER?
JRST TYICC4 ;YES, TRY FOR A BETTER ONE
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
PUSHJ P,SPCHEK ;SEE WHAT KIND OF CHARACTER IT IS
JRST CPOPJ1## ;NOTHING SPECIAL
TLNE T1,CHRIA ;UNLESS CC.NSA,
JUMPE T3,TYICC4 ;IF NULL, SKIP IT.
MOVE T4,LDBDCH(U) ;GET LINE BITS
TLNE T1,CHALT ;SOME ALT CHAR?
TLNE T4,LDLFCS ;FULL CHR SET?
CAIA ;NO CONVERSION
PUSHJ P,RIALTO ;CONVERT
TLNE T1,CHBRK ;BREAK CHARACTER?
SOS LDBBKC(U) ;COUNT IT DOWN
JUMPE F,CPOPJ1## ;GOOD RETURN IF NO DDB
TLNN T1,CHCNC ;CONTROL C CHARACTER?
JRST CPOPJ1## ;NO JUST RETURN TO CALLER
MOVE T4,DEVMOD(F) ;GET SOME BITS
TLNN T4,TTYATC ;IS TTY CONTROLLING A JOB?
JRST CPOPJ1## ;NO, RETURN CHAR
PUSHJ P,CNCCHK ;SEE IF IT IS A CONTROL C
JFCL ;YES, STORE
JRST CPOPJ1## ;YES, BUT IT SHOULD BE STORED.
MOVE S,[XWD IOW,IOACT]
IORB S,DEVIOS(F)
SKIPN P3 ;WAIT?
PUSHJ P,TIWAIT ;NOW WAIT IN CASE TYPE CONTINUE
PUSHJ P,TYIEAT ;EAT THE CONTINUE COMMAND
JUMPE P1,TYICC3 ;DONE IF NO PTR
DMOVE T1,P1 ;SETUP BYTE POINTER AND COUNT SO PRNGE CAN
PUSHJ P,PRNGE## ;MAKE SURE BUFFER DIDN'T GO AWAY
; (USER TYPED .CORE <SMALLER-VALUE> AND
; ZAPPED THE END OF HIS BUFFER)
JRST UADERR## ;ADDRESS CHECK
JRST UADERR## ;ADDRESS OK BUT ILLEGAL FOR I/O
JRST TYICC3 ;LOOP AROUND AGAIN.
;HERE WITH THE PI SYSTEM TURNED OFF AFTER INPUT COUNT HAS BEEN
;FOUND EXHAUSTED. (PROBABLY BY A SOSGE THAT DID NOT SKIP).
TYICCZ: SETZM LDBTIC(U) ;FIX CHARACTER COUNT
SETZM LDBIIC(U) ; AND INVISIBLE CHARACTER COUNT
SETZM LDBBKU(U) ;CLEAR BREAK POSITION
SETZM LDBBKC(U) ; AND COUNT, SINCE EMPTY
PUSHJ P,INPCHI ;SEE IF LDBTIT AND LDBECT MATCH
JRST TYICC5 ;NO, TRY AGAIN
JRST SONPPJ ;RESTORE PI AND NON-SKIP RETURN
;SUBROUTINE TO DISCARD A COMMAND FROM INPUT BUFFER IF L2RECS STILL ON
TYIEAT::MOVEI T1,L2RECS ;GET EAT CHARACTER SYNC BIT
TDNN T1,LDBBY2(U) ;STILL WANT COMMAND EATEN?
POPJ P,0 ;NO. RETURN.
PUSHJ P,EDTINI ;INITALIZE THE EDIT BUFFER
TYIL: SCNOFF ;NO RACES
SOSGE LDBTIC(U) ;ANY CHARACTERS LEFT?
JRST TYILZP ;FIX COUNT AND RETURN
LDCHKR T3,LDBTIT(U),TYILZP ;TAKE A CHARACTER
MOVSI T2,L3LIHD ;GET IN MIDDLE OF CHARACTER EXPANSION BIT
TDNN T2,LDBBY3(U) ;ARE WE?
TRNE T3,CK.NIS ;NON-EXISTENT CHARACTER?
TRNA ;EITHER TRUE, WE DON'T STORE THIS
PUSHJ P,EDTSTO ;STORE THE CHARACTER AWAY
PUSHJ P,TPCINP ;MAKE SURE WE GET THE RIGHT BREAK CHARACTERS
MOVE T2,LDBTIT(U)
CAMN T2,LDBBKU(U) ;TAKEN LAST BREAK?
SETZM LDBBKU(U) ;ZAP POINTER
SCNON ;ALLOW INTERRUPTS
TRNE T3,CK.NIS ;IF NOT IN STREAM,
SOSA LDBIIC(U) ;COUNT ANOTHER INVISIBLE CHARACTER AND LOOP
PUSHJ P,SPCHEK ;GET CHARACTER DESCRIPTORS
JRST TYIL ;ORDINARY
TLNE T1,CHBRK ;BREAK CHAR?
SOSA LDBBKC(U) ;YES. COUNT IT AND QUIT
JUMPN T3,TYIL ;NO. LOOP IF STILL SOME TO GO
TYID: MOVEI T1,L2RECS ;NOW CLEAR THE BIT
ANDCAM T1,LDBBY2(U) ;IN THE DEVICE WORD
SKIPE LDBEDT(U) ;EDIT MODE ENABLED?
JRST EDTEND ;YES, TERMINATE THE SAVED LINE
POPJ P,
TYILZP: SETZM LDBTIC(U) ;FIX COUNT
SETZM LDBIIC(U) ;ALSO NO INVISIBLE CHARACTERS LEFT
PUSHJ P,INPCHI ;MAKE SURE EVERYTHING MATCHES UP
JRST [SCNON ;DIDN'T, ALLOW INTERRUPTS AGAIN
JRST TYIL] ;AND TRY FOR ONE MORE CHARACTER
SCNON ;LET WORLD BACK IN
JRST TYID ; AND GIVE UP
;ROUTINE TO CHECK THAT INPUT TAKERS MATCH WHEN LDBTIC IS ZERO
;CALL/ MOVE U,LINE
; PUSHJ P,INPCHK
; HERE IF DIDN'T MATCH (IE, ANOTHER CHARACTER IS THERE)
; HERE IF MATCHED UP
;
;CLOBBERS T1
INPCHK: SCNOFF ;LET NOONE ELSE DO THIS WHILE WE'RE LOOKING
SKIPG LDBTIC(U) ;COUNT BACK UP?
INPCH1: PUSHJ P,INPCHI ;NO, CHECK
JRST SONPPJ ;AND PROPAGATE
JRST SONPJ1 ; EITHER RETURN
INPCHI: SETZM LDBIIC(U) ;SINCE LDBTIC IS ZERO, THIS SHOULD BE
SETZM LDBBKC(U) ;AND THIS
SETZM LDBBKU(U) ;AND THIS
MOVSI T1,L3LIHD!L3LIPD ;INPUT EXPANSION BITS
ANDCAM T1,LDBBY3(U) ;AND THESE
MOVE T1,LDBTIT(U) ;GET INPUT TAKER
CAMN T1,LDBECT(U) ;SEE IF MATCHES
JRST CPOPJ1## ;YES, GIVE GOODNESS RETURN
MOVSI T1,L3LEHD!L3LEPD ;GET TPCECH PROGRESS BITS
TDNE T1,LDBBY3(U) ;WAS THE POINTER BACKSPACED?
JRST CPOPJ1## ;YES, TRUST IT
SKIPN TICCNT ;NO, SEE IF FIRST SUCH ERROR
STOPCD .+1,DEBUG,TIC, ;++LDBTIC WRONG
AOS LDBTIC(U) ;COUNT ANOTHER CHARACTER TO READ
AOS TICCNT ;COUNT TIC STOPCD ERRORS
POPJ P, ;AND RETURN BADNESS
;HERE ARE THE ROUTINES TO PERFORM VARIOUS "TTY INPUT" FUNCTIONS
CTIGNC::PUSHJ P,CTICOM ;GET THE NEXT CHARACTER (IN T3)
CTIGLC::PUSHJ P,CTICOM ;GET THE "LAST CHAR COMCON READ" (IN T3)
CTISLC::PUSHJ P,CTICOM ;SET THE "LAST CHAR" (FROM T3)
CTIGBP::PUSHJ P,CTICOM ;GET THE BYTE POINTER BEING USED (IN T1)
CTISBP::PUSHJ P,CTICOM ;SET THE BYTE POINTER TO USE (FROM T1)
CTICOM: EXCH T4,(P) ;SAVE "T4" GET OFFSET
ANDI T4,-1 ;GET JUST THE ADDRESS
SUBI T4,CTIGNC+1 ;MAKE IT 0 ORIGINED
ADD T4,.CPTIV## ;GET ADDRESS OF TTY INPUT VECTOR TO USE
SE1XCT <XCT (T4)> ;CALL EITHER COMCON OR ONCE
POP P,T4 ;RESTORE T4
POPJ P, ; AND RETURN
;HERE IS THE "NORMAL" TTY INPUT VECTOR
COMTIV::PUSHJ P,CCTYI ;CCTYI GETS NEXT CHAR
LDB T3,LDPLCH ;LAST CHAR IS HERE
DPB T3,LDPLCH ; STILL HERE...
MOVE T1,LDBCLP(U) ;BYTE POINTER IS HERE
MOVEM T1,LDBCLP(U) ; STILL HERE...
;ROUTINE TO "GET NEXT CHAR" FROM NORMAL LINES
CCTYI:: SE1ENT ;ENTER SECTION 1
SCNOFF ;NO RACES
CCTYI0: SKIPE T2,LDBCLP(U) ;ADDRESS THERE TO USE?
CAMN T2,LDBTIP(U) ;YES. CAUGHT UP TO PUTTER?
JRST CCTYI1 ;YES. RETURN END OF LINE CHARACTER
LDCHK T3,LDBCLP(U),CCTYI1 ;LOAD CHARACTER FROM TTCMCA POINTER
TRNE T3,CK.NIS ;IF NOT A REAL CHARACTER,
JRST CCTYI0 ;TRY FOR A REAL ONE
PUSHJ P,TPCCOM ;CHECK IF NEED TO TRANSLATE CHARACTER
TRNE T3,CK.MET ;IF A SPECIAL FUNCTION,
JRST CCTYI1 ;RETURN A BREAK
JRST SONPPJ ;ALLOW INTERRUPTS AND RETURN
CCTYI1: MOVSI T3,L3LCHD!L3LCPD ;COMMAND PROGRESS BITS
ANDCAM T3,LDBBY3(U) ;NOT EXPANDING A COMMAND CHARACTER ANY MORE
MOVSI T3,L1LQCC ;QUOTE FLAG
ANDCAM T3,LDBBYT(U) ;ALSO NOT QUOTING ANY MORE
MOVEI T3,12 ;RETURN BREAK CHAR
JRST SONPPJ
;SUBROUTINE TO SEE IF A CONTROL C SHOULD BE ACTED ON OR STORED.
;NON-SKIP MEANS STORE IT.
;SKIP MEANS JACCT SET
;DOUBLE SKIP MEANS .HALT DONE.
CNCCHK: PUSH P,T1 ;SAVE T1
MOVE T1,LDBDCH(U) ;DEVICE FLAGS
TLNE T1,LDLSLV+LDLIMI ;SHOULD ^C BE RETURNED?
JRST TPOPJ## ;YES.
AOS -1(P) ;ADVANCE RETURN
HRRZ F,LDBDDB(U) ;GET LINE'S JOB
JUMPE F,CNCCK1 ;IF NO DDB ATTACHED, ASSUME SHOULD DO ^C
LDB T1,PJOBN## ; ..
MOVE T1,JBTSTS##(T1) ;GET JOB STATUS WORD
TDNE T1,[XWD JACCT,JS.DEP] ;IS ^C LEGAL? (PRIVILEGED PROG OR
; DAEMON ERROR PAUSE)
JRST TPOPJ## ;NO. GIVE IT TO CUSP
PUSHJ P,CNCMOD
CNCCK1: PUSHJ P,TTHALT ;FORCE CONTROL C
JRST TPOPJ1## ;RESTORE T1, SKIP RETURN
CLRIIQ: HRRZ F,LDBDDB(U) ;GET DDB, IF ANY.
JUMPE F,CLRIM1 ;CLEAR BIT IF NO DDB
MOVE S,DEVIOS(F) ;GET STATUS WORD.
TRNE S,I ;IF STILL IMAGE, DON'T CLEAR BIT
POPJ P,0 ;IMAGE. JUST RETURN
CLRIMI: HRRZ F,LDBDDB(U) ;GET ATTACHED JOB, IF ANY
JUMPE F,CLRIM1 ;IF NONE, SKIP PART OF THIS
MOVSI S,FRCEND ;ALSO CLEAR FORCED END OF FILE BIT
ANDCAB S,DEVIOS(F)
CLRIM1: MOVSI T1,LDLIMI ;NO. CLEAR IMAGE BIT AND TIME
DPB T1,LDPTIM ; ..
ANDCAM T1,LDBDCH(U) ; ..
PJRST SETCHP ;TELL THE FRONT END AND RETURN
;ROUTINE TO SCAN THE CHARACTERS ALREADY ECHOED IN THE INPUT STREAM
;AND SET LDBBKC CORRECTLY ACCORDING TO THE NUMBER OF BREAK CHARACTERS FOUND.
;USES T1-T3 AND LDBBKU
CHKBKC: PUSHJ P,SAVE2##
SCNOFF ;DON'T LET THINGS CHANGE
SETZM LDBBKC(U) ;START FROM SCRATCH
SETZM LDBBKU(U)
SETZM LDBBKI(U)
MOVSI P1,LOLPIM ;PIM STAUS BIT
TDNE P1,LDBOST(U) ;ARE WE IN PACKED IMAGE MODE?
JRST SONPPJ ;YES, WE CAN'T CHANGE ANYTHING
SKIPN P1,LDBTIC(U) ;ANY CHARACTERS ALREADY ECHOED?
JRST CHKBK1 ;NOPE
MOVE P2,LDBTIT(U) ;GET CURRENT INPUT STREAM
CHKBKL: LDCHK T3,LDBTIT(U),CHKBK1 ;SCAN NEXT CHARACTER, GIVE UP ON ERROR
TRNN T3,CK.NIS ;IF STILL THERE,
PUSHJ P,SPCHEK ;SEE IF IT'S SPECIAL
JRST CHKBKE ;CAN'T BE
TLNN T1,CHBRK ;BREAK?
JRST CHKBKE ;NO
AOS LDBBKC(U) ;YES, COUNT IT
MOVE T3,LDBTIT(U) ;GET POINTER TO BREAK
MOVEM T3,LDBBKU(U) ;STORE IT
CHKBKE: SOJG P1,CHKBKL
MOVEM P2,LDBTIT(U) ;RESTORE STREAM POINTER
CHKBK1: SKIPN P1,LDBECC(U) ;ANY UNECHOED CHARACTERS?
JRST CHKBK4 ;NO, RETURN
MOVE P2,LDBECT(U) ;YES, GET STREAM POINTER
CHKBK2: LDCHK T3,LDBECT(U),CHKBK4 ;GET NEXT CHARACTER TO EXAMINE
TRNN T3,CK.NIS ;IF STILL THERE,
PUSHJ P,SPCHEK ;SEE IF IT'S SPECIAL
JRST CHKBK3 ;CAN'T BE
TLNN T1,CHBRK ;BREAK?
JRST CHKBK3 ;NO
MOVE T3,LDBECT(U) ;GET POINTER TO IT
MOVEM T3,LDBBKI(U) ;STORE IT
CHKBK3: SOJG P1,CHKBK2 ;LOOP OVER ALL SUCH CHARACTERS
MOVEM P2,LDBECT(U) ;RESTORE POINTER
CHKBK4: SCNON ;ALLOW OTHERS AGAIN
SKIPLE LDBBKC(U) ;ANY BREAK CHARACTERS READY FOR READS?
PUSHJ P,RCVWKQ ;YES, TRY TO WAKE THE JOB
SETBMC: MOVEI T3,IRRBMC ;BREAK-MASK-CHANGED CODE
MOVEI T1,ISRREM ;OF REMOTE ISR VECTOR ENTRY
PUSHJ P,@LDBISR(U) ;TRY TO NOTIFY HANDLER
PJRST SETCHP ;TRY HARDER IF IT DOESN'T UNDERSTAND
POPJ P, ;RETURN
;ROUTINE TO PUT TERMINAL INTO MONITOR COMMAND MODE. DON'T CALL THIS
;ROUTINE IF TERMINAL IS A SLAVE, UNLESS YOU WANT SLAVE BIT CLEARED TOO.
;CALL WITH LINE SET.
CNCMOD::SE1ENT ;ENTER SECTION 1
SKIPG LDBTOC(U) ;UNLESS OUTPUT IS ACTIVE,
PUSHJ P,CLRPCT ;RESET THE "STOP" LINE COUNTER
PUSHJ P,STRTDL ;LET ONE DEFERRED LINE ECHO
MOVEI T1,L2RECS ;EAT RACE SYNC BIT
ANDCAM T1,LDBBY2(U)
HRRZ T1,LDBDDB(U) ;DDB ADDRESS
JUMPE T1,CNCMO2 ;IF NO DDB, DON'T TRY TO TOUCH IT
MOVSI T2,LDLBKA ;THE VOLATILE BREAK-ON-ALL-CHARACTERS BIT
TDNN T2,LDBDCH(U) ;IN CHARACTER MODE?
TDZA T2,T2 ;NO
MOVSI T2,IOLBKA ;YES, REMEMBER THAT FACT
IORM T2,DEVIOS(T1) ;FOR TTYUSR TO FIND LATER
CNCMO2: MOVSI T1,L1LUNR ;UNREAD BIT
ANDCAM T1,LDBBYT(U) ;CLEAR IT SO COMCON GETS CHARACTERS
MOVE T1,[LDLIMI+LDLNEC+LDLDLR+LDLBKA,,LDROSU]
MOVSI T2,LDLCNE ;COMMAND-LEVEL NO ECHO
TDNE T2,LDBDCH(U) ;IF SET,
TLZ T1,LDLNEC ;DON'T CLEAR THIS ONE
ANDCAM T1,LDBDCH(U) ;CLEAR ALL THESE BITS
MOVSI T1,LOLPIM ;AND THIS ONE
ANDCAM T1,LDBOST(U) ;IN STATES WORD
MOVSI T1,LDLBKM
ANDCAM T1,LDBBKB(U)
MOVSI T1,LDLCOM ;AND SET THIS ONE
IORB T1,LDBDCH(U) ; ..
TRNE T1,LDRPTY ;IS THIS LINE PTY-DRIVEN?
PUSHJ P,PTMNMD## ;YES. TELL PTYSER ABOUT IT.
PUSHJ P,SETCHP ;BE SURE REMOTES ARE INFORMED
PUSHJ P,CHKBKC ;FIX BREAK CHARACTERS AFTER LDLBKM
PJRST NOCTRO ;CLEAR ^O AND RETURN
;SUBROUTINE TO SKIP IF TERMINAL IS AT COMMAND LEVEL AND NOT SLAVED
; RETURNS LDBDCH IN T2
COMQ: MOVE T2,LDBDCH(U) ;GET LINE STATE
TLNE T2,LDLCOM ;AT TOP LEVEL?
TLNE T2,LDLSLV ;AND NOT SLAVED?
POPJ P,0 ;NO. JUST RETURN
HRRZ F,LDBDDB(U) ;IS LINE ATTACHED TO A JOB?
JUMPE F,CPOPJ1## ;JUMP IF NOT
PUSH P,T1 ;SAVE AN AC
MOVE T1,DEVMOD(F) ;GET DEVICE ASSIGN BITS
TLNE T1,TTYATC ;ATTACHED TO JOB?
JRST TPOPJ1## ;YES. SKIP RETURN
LDB T1,PJOBN## ;IS JOB NUMBER ZERO?
JUMPE T1,TPOPJ1## ;IF SO,SKIP RETURN
JRST TPOPJ## ;IF NOT ATTACHED, CAN'T DO COMMAND
;ROUTINE TO MAKE THIS TERMINAL VISIBLE TO COMMAND DECODER, IF AT COM LEVEL
;CALL WITH LINE SET UP
COMSET::SE1ENT ;ENTER SECTION 1
PUSHJ P,COMQ ;IS LINE AT COMMAND LEVEL?
POPJ P,0 ;NO. JUST RETURN
SKIPG LDBTOC(U) ;UNLESS OUTPUT IS ACTIVE,
PUSHJ P,CLRPCT ;RESET THE "STOP" LINE COUNTER
MOVSI T1,LDBCMR ;OK. SET REQUEST BIT
COMST1: SCNOFF ;CAN'T LOOK AT LDBDDB(U) HERE
COMSTF::SE1ENT ;ENTER SECTION 1
SKIPL LDBCOM(U) ;WAS COMMAND REQUEST ON?
AOS COMCNT## ;NO. WAKE COMCON
IORM T1,LDBCOM(U) ;SET THE BITS IN LDBCOM(U)
SCNON ;FALL INTO CMDSET
;SUBROUTINE TO SET/CLEAR BIT IN COMMAND MAP
CMDSET::SKIPA T1,[IORM T3,CMDMAP##(T2)]
CMDCLR::MOVE T1,[ANDCAM T3,CMDMAP##(T2)]
SE1ENT ;ENTER SECTION 1
PUSH P,T3 ;SAVE T3
SETZM T3
LDB T2,LDPLNO ;GET LINE #
LSHC T2,-5 ;SET TO WORD ADDRESS
ROT T3,5 ;BIT WITHIN WORD
MOVE T3,BITTBL##(T3) ;GET THE BIT
XCT T1 ;SET OR CLEAR
PJRST T3POPJ## ;RETURN
;HERE TO "GREET" A TERMINAL ON SYSTEM RE/START OR NETWORK CONNECT
;CALL IS:
;
; PUSHJ P,TTFGRT
; RETURN
;
;USES T1
;HERE TO FORCE A GENERAL COMMAND
;CALL IS:
;
; MOVX T1,<CMD>
; PUSHJ P,TTFORC
; RETURN
;
;USES T1
TTFRC1: AOSA (P)
TTFGRT::MOVEI T1,TTFCXH ;DO A .HELLO COMMAND
TTFORC::SE1ENT ;ENTER SECTION 1
DPB T1,LDPCMX ;STORE FORCED COMMAND INDEX
MOVSI T1,LDBCMR+LDBCMF;FORCED COMMAND REQUEST.
JRST COMST1 ;SET COMMAND COUNT, IF NEEDED
TTFCOM:: ;FORCED COMMAND TABLE
PHASE 0
TTFCXC:!SIXBIT /.HALT/ ;CONTROL C
TTFCXD::!SIXBIT /.BYE/ ;DATAPHONE DISCONNECT
TTFCXH::!SIXBIT /.HELLO/ ;DATAPHONE CONNECT
TTFCXR::!SIXBIT /.RESTA/ ;SYSTEM RESTART
TTFCXK:!SIXBIT /KJOB/ ;FORCED KILL JOB
TTFCXI::!SIXBIT /INITIA/ ;INITIALIZING CUSP CALL
TTFCXJ::!SIXBIT /.FCONT/ ;FORCED CONTINUE
TTFCXT:!SIXBIT /.TYPE/ ;RETYPE LINE
TTFCXW:!SIXBIT /USESTA/ ;1 LINE SYSTAT
IFN FTNET,<
TTFCXL::!SIXBIT /.NETLD/ ;AUTO DOWN LINE LOAD OF DAS80'S SERIES.
>
TTFCXS:!SIXBIT /HALT/ ;STOP JOB REGARDLESS OF ^C TRAPPING
TTFCXB:!SIXBIT /.BPT/ ;^D BREAKPOINT TRAP
TTFEXP::!SIXBIT /.EXEC/ ;EXEC PROCESS
IFN FTPATT,<
TTFCXX:!SIXBIT /CTEST/ ;FOR PATCHING
>
DEPHASE
TTFCML==:.-TTFCOM
IFG TTFCML -20,<PRINTX ?TOO MANY FORCED COMMANDS!>
SUBTTL COMMAND LEVEL ROUTINES
;ROUTINE TO SET UP TO READ A COMMAND FROM ANY REQUESTING LINE
;CALL FROM CLOCK LEVEL:
; PUSHJ P,TTYCOM
; NONE FOUND
; FOUND ONE ;F, U SET UP. J HAS JOB # IF ANY,
; ;T2 HAS TYPEIN T2
;MUST BE CALLED IN SECTION 1
TTYCOM::MOVE T1,BITTBL##+<FRCLIN##-<FRCLIN##/^D32>*^D32>
TDNN T1,CMDMAP##+<FRCLIN##/^D32>
SKIPA T1,LINSAV##
MOVEI T1,FRCLIN## ;DO SYSTEM COMMANDS FIRST
MOVEM T1,LINSAV##
CAIL T1,TTPLEN## ;GREATER THAN HIGHEST LINE #?
TTYCM0: SETZB T1,LINSAV## ;YES, START AT LINE 0
LSH T1,-5 ;SHIFT TO RIGHT PLACE
HRLI T1,-TTMAPN##(T1) ;FORM AN AOBJN POINTER
TTYCM1: SKIPE T2,CMDMAP##(T1) ;GET A WORD OF BITS
TTYCM2: JFFO T2,TTYCM3 ;FIND FIRST ONE BIT
AOBJN T1,TTYCM1 ;LOOP TO TOP OF TABLE
SKIPE LINSAV## ;LOOKED AT THE ENTIRE TABLE?
JRST TTYCM0 ;NO, START AT THE BEGINNING
POPJ P,0 ;GIVE FAIL RETURN
TTYCM3: MOVEI T4,(T1) ;COPY WORD #
LSH T4,5 ;SHIFT TO RIGHT PLACE
ADDI T4,(T3) ;ADD IN BIT NUMBER
CAML T4,LINSAV## ;SKIP IF LINE IS TOO SMALL
JRST TTYCM4 ;ELSE FIX # AND PROCESS
TDZ T2,BITTBL##(T3) ;CLEAR BIT
JRST TTYCM2 ;AND TRY NEXT
TTYCM4: MOVEM T4,LINSAV## ;SAVE THIS LINE #
AOS (P) ;GIVE SKIP RETURN
TTCM4A: MOVE U,LINTAB##(T4) ;PICK UP LDB POINTER
TRESCN::SE1ENT ;ENTER SECTION 1
HRRZ F,LDBDDB(U) ;GET DDB ADDRESS IF ANY
JUMPE F,TRESC1 ;JUMP IF NO DDB
MOVE T3,DEVMOD(F)
TLNN T3,TTYATC
TRESC1: TDZA J,J
LDB J,PJOBN##
PUSHJ P,RSTTMR ;RESET THE ADT
MOVE T3,LDBCOM(U) ;KILL OR COMMAND?
TLNN T3,LDBCMF!LDBDET;FORCED COMMAND OR CLEANUP REQUIRED?
TLNN T3,LDBCMK ;NO, FORCED KJOB?
JRST TTYCM7 ;NO.
JRST TTYCM5 ;FORCED KJOB!
;DO FORCED COMMANDS OR CLEANUP 1ST, THEN FORCED KJOBS, THEN TYPED-IN COMMANDS
TTYCM7: MOVEM U,.CPCML## ;MUST BE SAVED WHEN TTCMCA IS USED
SCNOFF
MOVE T1,LDBTIT(U) ;GET TYPEIN CHAR ADR
PUSHJ P,CTISBP ; AND DEFINE IT AS THE INPUT BYTE POINTER
SCNON
HRRI T3," " ;PRIME THE TYI ROUTINE
TLNE T3,LDBCMF ;FORCED COMMAND?
MOVEI T3,12 ;YES. PREVENT EXTRA ARGUMENTS
PUSHJ P,CTISLC ;SAY IT IS LAST CHAR READ
PUSHJ P,FNDPDB## ;ADDRESS OF PDB
JFCL
POPJ P,0
TTYCM5: MOVEI T1,TTFCXC ;FORCE HALT 1ST SINCE IF TTKJOB IS CALLED DURING A COMMAND
SKIPGE JBTSTS##(J) ;MUST BE A JOB. IS IT RUNNING
JRST TTYCM6 ;NO. JUST KILL IT
MOVSI T1,LDBCMK ;CLEAR KILL
ANDCAM T1,LDBCOM(U) ;FLAG
MOVEI T1,TTFCXK
TTYCM6: PUSHJ P,TTFORC ;FORCE COMMAND
;DON'T CALL CMDCLR, OR DELAYED COMMAND WILL NEVER BE SEEN AGAIN
MOVE T4,LINSAV## ;FIND LINE
JRST TTCM4A ;AGAIN
TTKJOB::SE1ENT ;ENTER SECTION 1
PUSHJ P,CNCMOD ;CONSOLE TO COMMAND LEVEL
MOVSI T1,LDBCMK ;SET KILL REQUEST
IORM T1,LDBCOM(U) ;IN LDB
HRRZ F,LDBDDB(U)
SKIPE J,F
LDB J,PJOBN##
AOS COMCNT## ;MAKE COMCON SEE IT
SKIPL JBTSTS##(J) ;SKIP IF JOB IS IN RUN STATE
; THIS DEPENDS UPON:
; 1. RUN BIT BEING SIGN OF JBTSTS
; 2. J=0 IF NO JOB
; 3. JBTSTS+0 = 0
PJRST CMDSET
;TTHALT -- HALT THE JOB ATTACHED TO THE TERMINAL
;
;THIS ROUTINE DOES NOT SET TERMINAL TO COMMAND LEVEL BECAUSE JACCT
;PROGRAMS MAY STILL NEED TO TYPEOUT AND THAT WOULD BLOCK THEM IN TO STATE.
TTHALT: MOVEI T1,TTFCXC ;HALT COMMAND INDEX
PJRST TTFORC ;FORCE THE ^C
;ROUTINES TO ATTACH TERMINAL TO A JOB
;1) CALL WHEN COMMAND DECODER DECIDES TO CREATE A JOB DUE TO
;A COMMAND BEING TYPED IN. THE LDB WILL ALREADY HAVE BEEN
;SET UP, BUT IT IS NOT YET LINKED TO A DDB
;
;CALL: MOVE LINE,ADDRESS OF LDB
; MOVE J,NEW JOB NUMBER
; PUSHJ P,TTYATI
; ERROR RETURN ;ALREADY SOMEONE THERE (DDB POINTS AT HIM), OR
; ;NO MORE FREE DDB'S (DDB CONTAINS 0)
; OK RETURN ;DDB, DDBLDB, AND LDBDDB SET UP
;
;2) CALL FROM COMMAND DECODER ON AN ATTACH COMMAND.
;
;CALL: MOVE LINE,ADDRESS OF LDB
; MOVE J,JOB TO ATTACH TO
; PUSHJ P,TTYATT
; ERROR RETURN ;SOMEONE ALREADY ATTACHED (DDB POINTS TO HIM) OR
; ;NO SUCH DDB (DDB=0)
; OK RETURN ;DDB, LDBDDB, NEW DDBLDB SET UP. OLD DDBLDB CLEARED
TTYATT::SE1ENT ;ENTER SECTION 1
PUSH P,U
PUSHJ P,TTYISA ;SEE IF DDB FOR TARGET JOB CAN BE ATTACHED
JRST LPOPJ## ;NO, CAN'T DO IT
JUMPE T1,TTYAT1 ;JUMP IF DETACHED BUT SIGNAL DETACHING
MOVEM T1,(P) ;SAVE LDB OF TARGET JOB
LDB T1,LDPLNO ;OPERATOR DOING PREEMPTIVE ATTACH
; GET OPERATOR'S LINE NUMBER
EXCH U,0(P) ;GET LDB OF OBJECT JOB
LDB T3,LDPLNO ;GET ITS LINE NUMBER TOO
CAIE T3,0(T1) ;ARE THEY THE SAME? (OPR ATTACHING
; TO HIMSELF?)
PUSHJ P,PTYDET ;NO. DETACH OBJECT JOB, NOW IN LINE.
; MUST RESPECT F
;F NOW POINTS TO JOB BEING
;PICKED UP BY TERMINAL IN 0(P)
JRST TTYAT2 ;GO DO THE ATTACH
TTYAT1: PUSHJ P,SIGDET ;SIGNAL DETACHING
JRST TTYAT2 ;GO DO THE ATTACH
TTYATI::SE1ENT ;ENTER SECTION 1
IFN FTMP,<
PUSHJ P,INTLVL## ;IF AT UUO LEVEL
PUSHJ P,ONCPU0## ;AVOID RACES WITH COMCON
>
PUSH P,U ;SAVE LINE DATA BLOCK ADDRESS
PUSHJ P,TTYSRC ;SEE IF THERE'S ALREADY A DDB. SHOULDNT BE.
PUSHJ P,DDBSRC ;OK. GET A NEW DDB.
JRST LPOPJ## ;ERROR. EITHER TTYSRC WON OR DDBSRC LOST
TTYAT2: MOVE U,0(P) ;GET LDB ADDR FROM STACK
PUSH P,F ;AND SAVE NEW DDB ADDRESS
HRRZ F,LDBDDB(U) ;GET OLD DDB IF ANY
SKIPE F ;ANY THERE?
PUSHJ P,TTYDT1 ;YES. DETACH FROM IT BUT DON'T SET MONITOR CODE
SKIPN U ;SKIP IF LDB WAS FOUND
PUSHJ P,TTYKLQ ;NO, KILL OFF DDB
MOVE F,0(P) ;RESTORE NEW DDB ADDRESS
MOVE U,-1(P) ;GET LDB ADDRESS, FOR DS POINTER
MOVSI T1,LDBCMF
TDNE T1,LDBCOM(U)
JRST TTYAT3
MOVE T1,LDBDCH(U) ;LOOK AT DATA SET BIT
SKIPL LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
TRNN T1,LDRDSD ;OR IF NOT A DATA SET
JRST TTYAT3 ;NO DSCTAB ENTRY
LDB U,LDPDSC ;GET DATASET TABLE INDEX
MOVEI T1,0 ;CLEAR TIME FIELD OF DATASET ENTRY
DPB T1,DSTMPL ; ..
TTYAT3: MOVE U,-1(P) ;ATTACH LDB FROM STACK TO DDB
MOVE T1,[XWD TTYATC,ASSCON] ;SET ATTACHED AND ASSIGNED BITS
IORM T1,DEVMOD(F) ;IN THE DEV DATA BLOCK
HRRM F,LDBDDB(U) ;SET LINK FROM DDB TO LDB
MOVEM U,DDBLDB(F) ;AND LINK FROM LDB TO DDB
DPB J,PJCHN## ;STORE JOB NUMBER IN DDB
HRRZM F,TTYTAB##(J) ;STORE CONTROLLING DDB BY JOB NUMBER
PUSHJ P,SCNNMX ;SET UP PHYSICAL LINE NAME AND PUNIT
IFN FTNET,<PUSHJ P,SETSTA> ;SET CORRECT STATION NUMBER
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;THIS CODE MAKES SURE BATCH BIT STAYS CORRECT
PUSHJ P,CTLJBU## ;GET PTY DDB IF ANY
JUMPL T1,TTYAT5
MOVSI T1,DVDIBP ;GET BATCH PTY BIT
MOVE T2,JBTLIM##(J) ;GET JBTLIM
TDNN T1,DEVCHR(F) ;IS IT A BATCH PTY?
JRST TTYAT4 ;NO
TLON T2,(JB.LBT) ;YES, MAKE IT A BATCH JOB
AOS BATNUM## ;INCREMENT # OF BATCH JOBS
MOVEM T2,JBTLIM##(J) ;RESTORE JBTLIM
TTYAT4:
PUSHJ P,SIGDET ;SIGNAL ATTACH (SAME AS DETACH)
TTYAT5: POP P,F
MOVSI T1,(JB.LTL) ;GET DETACH TIME UNIT BIT
TDNN T1,JBTLIM##(J) ;SEE IF SET
JRST UPOPJ1## ;NO -- LEAVE ALONE
ANDCAM T1,JBTLIM##(J) ;YES -- CLEAR IT
MOVEI T1,0 ;NO TIME UNIT NOW
DPB T1,JBYLTM## ;CLEAR
JRST UPOPJ1## ;SKIP RETURN TO COMCON.
;SUBROUTINE TO LOOK FOR POSSIBLE LINE ALREADY ATTACHED TO TARGET JOB
;ARGS U=LINE ATTACH WAS TYPED OR
; J=JOB NUMBER OF TARGET JOB
;VALUES T1=ADDR OF LDB ATTACHED TO TARGET JOB OR 0 IF NONE
;NON-SKIP RETURN IF NO DDB FOR TARGET JOB OR DDB FOUND BUT MANY NOT ATTACH
;SKIP RETURN IF DDB FOUND AND MAY ATTACH TO IT
TTYISA::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE2## ;SAVE P1 AND P2
PUSH P,U ;SAVE LINE BLOCK ADR OF GUY TYPING COMMAND
PUSHJ P,TTYSRC ;FIND THE DDB CONTROLLING THAT JOB
JRST LPOPJ## ;THERE ISN'T ANY. COMCON HAS GOOFED?
SETZ T1,
JUMPE U,LPOPJ1## ;IF NONE ATTACHED, GO ATTACH.
EXCH U,0(P) ;SOMEONE IS ATTACHED. ONLY THE OPERATOR
;MAY USURP THE EXISTING CONNECTION
PUSH P,F ;SAVE NEW DDB
HRRZ F,LDBDDB(U) ;DDB OF OLD USER
SKIPE T1,F ;IF F=0, MAKE T1 0, SINCE PJOBN IS MEANINGLESS IF F=0
LDB T1,PJOBN## ;HIS JOB NUMBER
LDB P1,LDPLNO ;GET TERMINAL LINE # IN P1
SUBI P1,PTYOFS## ;SUBTRACT OFFSET OF PTY0
JUMPL P1,TTYIS1 ;SEE IF A PTY
CAIGE P1,M.PTY## ; ..
SKIPA F,PTYTAB##(P1) ;IT IS A PTY, GET DDB
TTYIS1: TDZA P1,P1 ;NOT A PTY, USE JOB 0
LDB P1,PJOBN## ;GET JOB OWNING PTY
POP P,F ;RESTORE F
MOVE P2,FFAPPN## ;GET [1,2]
CAME P2,JBTPPN##(T1) ;IS JOB THAT TYPED COMMAND [1,2]?
CAMN P2,JBTPPN##(P1) ;OR COMMAND TYPED BY SON OF OPR?
JRST TPOPJ1## ;YES, ATTACH IS LEGAL
CAME U,OPRLDB## ;IS THIS THE OPR?
JRST TPOPJ## ;NO. DISCARD OBJECT JOB'S LDB FROM
JRST TPOPJ1## ;STACK, AND GIVE ERROR RETURN TO COMCON
;WITH DDB POINTING AT GUY ALREADY ATTACHED
;ROUTINE TO DETACH TERMINAL FROM A JOB.
;CALL: MOVE F,ADDRESS OF TTY DDB TO BE DETACHED
; MOVE U,LDB ADDRESS IF ENTRY AT PTYDTC
; PUSHJ P,TTYDET
; ALWAYS RETURN HERE
;CALLED FROM TTYATT AND COMCON (DETACH COMMAND)
;KILLS DDB IF NOT ATTACHED, ASSIGNED, OR INITED
;CLEARS LINKS TO DDB
;RESPECTS DDB
TTYDTC::TDZA T2,T2 ;FLAG TTYDTC ENTRY
TTYDET::MOVEI T2,1 ;SAME FOR TTYDET
SE1ENT
PUSH P,T2 ;SAVE T2
PUSHJ P,SIGDET
POP P,T2 ;RESTORE IT
MOVE U,DDBLDB(F) ;GET LDB ADDRESS
LDB T1,LDPLNO ;GET LINE NUMBER
CAIN T1,FRCLIN## ;RUNNING ON FRCLIN?
JRST @[IFIW PTYDTC
IFIW PTYDET](T2) ;YES, SKIP LOGGED OUT CHECK
LDB T1,PJOBN## ;GET JOB NUMBER
MOVE T1,JBTSTS##(T1) ;IS HE LOGGED IN?
TLNE T1,JLOG ; ..
JRST @[IFIW PTYDTC
IFIW PTYDET](T2) ;YES, DISPATCH TO PTYDET
LDB T2,PJOBN## ;GET JOB NUM
MOVE T1,LGONAM## ;DON'T CLEAR
CAMN T1,JBTNAM##(T2) ;FOR LOGOUT SINCE USER COULD
JRST TTKJOB ;THEN GET OUT OVER QUOTA
MOVSI T1,JACCT ;CLEAR JACCT
ANDCAM T1,JBTSTS##(T2) ;IN STATUS
JRST TTKJOB ;GO KILL HIM
PTYDTC::SE1ENT ;ENTER SECTION 1
LDB T1,PJOBN## ;GET JOB NUMBER FROM DDB
MOVSI T2,CMWB ;AND COMMAND WAIT BIT
IFN FTMP,<CAME T1,COMJOB##> ;CURRENT JOB IN COMCON?
TDNE T2,JBTSTS##(T1) ;OR JOB IN COMMAND WAIT?
JRST [MOVSI T1,LDBDET ;TELL COMRET TO CLEAN UP
IORM T1,LDBCOM(U) ;JOB/COMMAND AT COMMAND EXIT
PJRST DETCHK] ;WAIT FOR DETACH AND RETURN
PTYDET::SE1ENT ;ENTER SECTION 1
PUSHJ P,TTYDT1 ;DISCONNECT DDB FROM LDB
JUMPE U,TTYKLQ ;IF NO LDB KILL OFF DDB
PUSH P,F ;PRESERVE DDB (LDB LINK GONE AFTER TTYDT1)
PUSHJ P,CNCMOD ;MAKE SURE LDB AT TOP LEVEL
POP P,F ;RESTORE DDB POINTER
;ROUTINE TO KILL DDB IF IT IS AN IDLE TTY DDB
TTYKLQ::PUSH P,T1 ;RESPECT T1
MOVE T1,DEVMOD(F) ;GET DEVICE MODE AND USE BITS
TLNE T1,DVTTY ;IS IT A TTY DDB?
TDNE T1,[XWD TTYATC,ASSPRG] ;YES, ANY REASON TO KEEP DDB?
JRST TPOPJ## ;YES.
PUSHJ P,TTYRL3 ;ANY OTHER REASON TO KEEP DDB?
PUSHJ P,TTYKIL ;NO. GO KILL THE DDB
JRST TPOPJ## ;AND RESTORE T1 ON RETURN
;SUBROUTINE TO DISCONNECT A TERMINAL FROM A JOB WITHOUT SETTING TERMINAL TO MONITOR LEVEL
;THIS IS SO ATTACH UUO WILL LEAVE TERMINAL AT ITS ORIGINAL LEVEL (MONITOR OR USER MODE)
TTYDT1: MOVE U,DDBLDB(F) ;GET LINKED LINE ADDRESS
SETZM DDBLDB(F) ;DISCONNECT LDB FROM DDB
JUMPE U,TTYDTX ;IF NO LDB, KILL OFF DDB
HLLZS LDBDDB(U) ;DISCONNECT DDB FROM LDB
HRRZS DEVNAM(F) ;CLEAR LH OF DEVNAM TO NOT CONFUSE DEVCHR, ETC.
;KEEP RH FOR SYSTAT, ETC.
LDB T1,PJOBN## ;SEE IF THIS JOB WAITING FOR DAEMON
MOVSI T2,(JB.LBT) ;BATCH BIT
TDNE T2,JBTLIM##(T1) ;IF WAS BATCH JOB
SOS BATNUM## ;DECR. BATCH JOB COUNT
ANDCAM T2,JBTLIM##(T1) ;CLEAR BIT SO OPERATOR CAN DETACH
PUSHJ P,TYIEAT ;NO. CLEAR ANY PENDING COMMAND
MOVE T1,LDBDCH(U) ;GET LINE CHARACTERISTICS
TRNE T1,LDRPTY ;A PTY LINE?
PUSHJ P,PTMNMD## ;YES. WAKE CONTROLLER
TTYDTX: POPJ P,
SIGDET: HRROI T1,C$DATT ;GET CONDITION TO BE SIGNALLED
PJRST PSIJOB## ;NOTIFY EACH JCH IN JOB AND RETURN
;ROUTINE TO MAKE SURE A LINE IS DETACHED BEFORE PROCEEDING
;CALL WITH U POINTING AT THE LDB IN QUESTION
DETCHK: PUSH P,J ;SAVE J
MOVE J,.CPJOB## ;SET TO CURRENT JOB
DETCH1: MOVSI T1,LDBDET ;WAITING FOR COMMAND
TDNN T1,LDBCOM(U) ; TO COMPLETE?
JRST JPOPJ## ;NO
S0PSHJ SLEEPF## ;YES, WAIT UNTIL ITS DONE
JRST DETCH1 ;TRY AGAIN
;ROUTINE TO RELEASE A TTY DDB. CALL WITH DDB SET UP.
TTYREL::SE1ENT ;ENTER SECTION 1
MOVE T1,[XWD IOW,IOACT] ;CLEAR OUT S
HRRZS F ;CLEAR LEFT HALF BITS (OUTPB, INPTB, ETC.)
ANDM T1,DEVIOS(F) ; IN CORE
SKIPE DINITF## ;IN SYSINI?
JRST TTYRL2 ;YES--SKIP THIS
PUSHJ P,SAVE1## ;SAVE CHANNEL NUMBER
MOVEI P1,0 ;START AT CHANNEL ZERO
TTYRL0: S0PSHJ NXTCH## ;NEXT CHANNEL (MUST BE CALLED IN SECTION 0, LH F BITS)
JRST TTYRL1 ;ALL CHANNELS HAVE BEEN LOOKED AT
SOS P1 ;ADJUST P1
CAIN P1,@-1(P) ;CHANNEL BEING RELEASED
AOJA P1,TTYRL0 ;YES
CAIE T1,(F) ;NO SAME DDB OPEN ON ANOTHER CHANNEL?
AOJA P1,TTYRL0 ;NO
JRST TTYRS1 ;YES, DON'T MAKE THE DDB GO AWAY
TTYRL1:
TTYRL2: PUSHJ P,TTYRL3 ;SEE IF SHOULD KEEP DDB AROUND
JRST TTYKIL ;NO. GO DISCARD DDB.
JRST TTYRS1 ;YES. KEEP DDB AROUND. RETURN.
TTYRL3: MOVE T1,DEVMOD(F) ;GET MODE BITS
TLNE T1,TTYATC ;IS TTY ATTACHED?
JRST CPOPJ1## ;YES, KEEP DDB AROUND. RETURN+2.
TRNN T1,ASSCON ;IS IT ASSIGNED?
POPJ P, ;NO, DISCARD DDB. RETURN+1.
HLRZ T1,DEVNAM(F) ;GET LH OF PHYSICAL NAME
CAIE T1,'TTY' ;STILL AN ACCESSIBLE NAME?
SKIPE DEVLOG(F) ;OR HAS A LOGICAL NAME?
AOS (P) ;YES TO EITHER. KEEP DDB.
POPJ P, ;NOT REACHABLE. DISCARD.
;ROUTINE TO CLEAR A TTY DDB AND MAKE IT AVAILABLE TO THE POOL
;CALL: MOVE F,ADDRESS OF DEVICE DATA BLOCK KNOWN TO BE THROUGH USE.
; PUSHJ P,TTYKIL
; ALWAYS RETURN HERE
;RESPECTS F & S, CLOBBERS T1
TTYKIL::SE1ENT ;ENTER SECTION 1
SETZM DEVLOG(F) ;CLEAR LOGICAL NAME
MOVSI T1,IOFST ;INITIAL STATE OF S WORD
MOVEM T1,DEVIOS(F) ;PLACE IN CORE STATUS WORD
SKIPE DEVPSI(F) ;USER INTERRUPTING ON THIS
PUSHJ P,PSIRMV## ;YES, REMOVE PSI LINKS
PUSH P,W ;SOME CALLERS EXPECT THIS TO BE PRESERVED
PUSHJ P,CLRDVL## ;NO JOB OWNS IT ANY MORE.
POP P,W ;RESTORE BLOWN AC
PUSH P,U
MOVE U,DDBLDB(F) ;GET LINK TO LINE DATA BLOCK
JUMPE U,TTYKL1 ;BYPASS IF NO LINK.
PUSHJ P,TTYSTC ;PUT LINE AT COMMAND LEVEL
PUSHJ P,TTYCPT ;CLEAR PAPER TAPE BITS
MOVE T1,[LPGCLK] ;CLEAR PAGE BITS
ANDCAM T1,LDBPAG(U) ;SO XON AND XOFF ARE ECHOED PROPERLY
MOVSI T1,LDLBKA ;CLEAR THE BREAK-ON-ALL BIT
ANDCAM T1,LDBDCH(U) ;IN THE DCH WORD
MOVSI T1,LOLSSO ;CLEAR THE STOPPED OUTPUT BIT
ANDCAM T1,LDBOST(U) ;IN THE STATES WORD
PUSHJ P,CLRIM1 ;MAKE SURE NOT IN IMAGE MODE
PUSH P,S ;IN CASE SOME CALLER SOMEWHERE CARES
MOVEI S,0 ;CLEAR ALL THOSE BITS IN LDBDCH
PUSHJ P,UUOLDB ;CLEAR OUT LDB
POP P,S ;THIS IS REALLY SUPERCAUTION
TTYKL1: MOVSI T1,DEPRAS ;TEST FOR DDB RESTRICTED
TDNE T1,DEVSTA(F) ;IS IT A RESTRICTED TTY?
JRST [POP P,U
JRST TTYRS1] ;YES, SO KEEP DDB
SETZM DEVNAM(F) ;CLEAR PHYSICAL NAME
HLLZS LDBDDB(U) ;REMOVE LINK TO DEAD DDB
SETZM DDBLDB(F) ;REMOVE LINK FROM DDB TO LINE DATA BLOCK
MOVE T1,[XWD TTYUSE+TTYATC,ASSCON+ASSPRG]
ANDCAB T1,DEVMOD(F) ;LAST CLEAR THESE, MAKING DDB AVAILABLE
JRST UPOPJ## ;AND RETURN TO CALLER.
;SUBROUTINE CALLED ON RESET FROM UUOCON
TTYRES::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1##
MOVEI P1,JS.NTO
TDNE P1,JBTSTS##(J)
XORB P1,JBTSTS##(J)
ANDI P1,JS.NTO
HLRZ F,SCNDDB+DEVSER ;FIRST REAL TTY DDB
TTYRSA: LDB T1,PJOBN##
CAIE T1,(J)
JRST TTYRSB
JUMPN P1,TTYRSC
SETZB T1,DEVSTS(F)
DPB T1,BYTCNT
TTYRSC: PUSHJ P,TTYRL3 ;SEE IF ANY REASON TO KEEP DDB.
PUSHJ P,TTYKIL ;NO, DISCARD DDB.
TTYRSB: HLRZ F,DEVSER(F)
MOVE T1,DEVMOD(F)
TLNE T1,DVTTY
JUMPN F,TTYRSA
HRRZ F,TTYTAB##(J) ;GET CONTROLLING DDB ADDRESS
JUMPE F,CPOPJ## ;REALLY HAS TO BE ONE
TTYRS1: MOVE S,[IOLBKA,,IOSBKA!IOSTEC!IOSFCS!IOSABS+D] ;GET BITS
;THE FOLLOWING CHECK FOR NOT LOGGED IN, RUNNING "LOGIN"
; IS TO AVOID BREAKING ANCIENT "FEATURE" OF NOECHO GETTING
; SET BY LOGIN COMMAND.
MOVE U,DDBLDB(F) ;LINK TO LDB
JUMPE U,TTYRS2 ;NOT BATCH IS DETACHED
PUSHJ P,PTBTCH##
JRST TTYRS2
MOVE T1,JBTSTS##(J) ;GET THIS STATUS
MOVE T2,JBTPRG##(J) ; AND PROGRAM NAME
TLNN T1,JLOG ;IS HE NOT LOGGED IN?
CAME T2,[SIXBIT/LOGIN/] ; AND RUNNING LOGIN
TTYRS2: IORI S,IOSNEC ;NOT BOTH, WE CAN CLEAR NOECHO
ANDCAB S,DEVIOS(F) ;CLEAR THESE BITS ON RESET
JUMPE U,CPOPJ## ;SKIP IT IF DETACHED
MOVEI T1,0 ;CLEAR THE AUTO
DPB T1,LDPACR ;CRLF COUNTER
DPB T1,LDPAPL ;NOT IN APL MODE ANY MORE
PUSHJ P,CLRCSB ;CLEAR THE CHARACTER STATUS BYTES
PUSHJ P,CLRIM1 ;CLEAR IMAGE MODE
MOVSI T1,LDLBKA ;THE BREAK-ON-ALL-CHARACTERS BIT
ANDCAM T1,LDBDCH(U) ;CLEAR IN LDB SINCE TTYUSR ALREADY CALLED
; AND WILL HAVE SET IT IF IOLBKA WAS SET
PUSHJ P,UUOLDB ;AND MAKE LDB AGREE
PJRST SETCHP ;FORCE CHANGE OF CHARACTERISTICS
;ROUTINE TO RETURN NEXT OUT-OF-BAND STATUS TO PSISER
;RETURNED IN T2
NXTOOB::SE1ENT ;MUST RUN IN SECTION ONE
PUSH P,U ;FOR LDBS
PUSH P,F ;FOR DDBS
SETZ T2, ;FOR FLAGGING WHEN WE FIND STATUS
HRRZ F,TTYTAB##(J) ;GET CONTROLLING TERMINAL
SKIPE U,DDBLDB(F) ;IS HE ATTACHED?
SKIPN LDBOOC(U) ;AND ARE THERE OOB CHARS HERE?
JRST NXTOB1 ;NO SUCH LUCK, MUST LOOP OVER TTYS
PUSHJ P,NXTOBC ;YES, GET A CHARACTER
JRST NXTOB1 ;COULDN'T AFTER ALL
SETZ F, ;FLAG FOR TTY LOOP
JRST NXTOB3 ;GET STATUS AND RETURN IT
NXTOB1: HLRZ F,SCNDDB+DEVSER ;POINT TO FIRST REAL TTY DDB
NXTOB4: SKIPN U,DDBLDB(F) ;IS IT FOR REAL?
JRST NXTOB2 ;NO, LOOK FOR ANOTHER
LDB T1,PJCHN## ;YES, GET ITS OWNER
CAME T1,.CPJCH## ;IS IT FOR US?
JRST NXTOB2 ;NO, LOOK FOR ANOTHER
SKIPN LDBOOC(U) ;ARE THERE ANY OOB CHARS HERE?
JRST NXTOB2 ;NO, KEEP LOOKING
JUMPN T2,NXTOB5 ;DON'T GET IT IF ALREADY HAVE STATUS
PUSHJ P,NXTOBC ;NEED ONE, GET IT
JRST NXTOB2 ;OH, WELL
JRST NXTOB3 ;NOW FIGURE UP THE STATUS
NXTOB2: HLRZ F,DEVSER(F) ;FIND NEXT DDB
MOVSI T1,DVTTY ;BIT TO TEST
TDNE T1,DEVMOD(F) ;IS IT STILL A TTY?
JRST NXTOB4 ;YES, LOOP
JRST FUPOPJ## ;NO, JUST RETURN THE STATUS WE HAVE
NXTOB3: LDB T2,LDPLNO ;GET THE LINE NUMBER
TRO T2,.UXTRM ;MAKE INTO A UDX
TRNN T3,CK.MET ;IS THIS FOR THE SWITCH CHARACTER?
TRZA T3,^-CK.CHR ;NO, KEEP ONLY CHARACTER BITS
MOVEI T3,400000 ;YES, KEEP ONLY A SIGN BIT
HRL T2,T3 ;CHARACTER,,UDX IS STATUS
SKIPE LDBOOC(U) ;ARE THERE MORE ON THIS LINE?
JRST NXTOB5 ;YES, SIGNAL THE CONDITION AGAIN
JUMPE F,NXTOB1 ;NO, LOOK FOR MORE ON OTHER LINES
JRST NXTOB2 ;(NO MATTER WHICH LINE CALLED US)
NXTOB5: PUSH P,T2 ;PRESERVE THE STATUS TO RETURN
SIGNAL C$OOB ;THERE'S ANOTHER OOB CHAR TO RECEIVE
JFCL ;IGNORE DOESN'T WANT RETURN
PUSHJ P,SETUNR ;MAKE SURE WE STAY AWAKE HERE
POP P,T2 ;RESTORE STATUS TO RETURN
JRST FUPOPJ## ;RESTORE STACK ITEMS AND RETURN
NXTOBC: SCNOFF ;AVOID RACES
SOSGE LDBOOC(U) ;ARE THERE STILL MORE TO GIVE?
JRST NXTOBQ ;NO, CLEAN UP
LDCHKR T3,LDBOOT(U),SONPPJ ;FETCH THE CHARACTER
JRST SONPJ1 ;RETURN SUCCESS
NXTOBQ: SETZM LDBOOC(U) ;DON'T LET COUNT GO NEGATIVE
JRST SONPPJ ;GIVE ERROR RETURN
;SUBROUTINE TO RETURN ONE CHARACTER FROM THE INPUT BUFFER. CHARACTER
;RETURNED IN T3.
COMTYI::PUSH P,T2 ;SAVE AC FOR OUTSIDE WORLD
PUSHJ P,CTIGLC ;GET THE LAST CHARACTER
SKIPN T3 ;IS ANYTHING THERE FROM BEFORE?
MOVEI T3,12 ;NO. ASSUME END OF LINE
PUSHJ P,SPCHEK ;YES. WAS IT A BREAK?
JFCL
TLNN T1,CHBRK ; ..
COMTI1: PUSHJ P,CTIGNC ;NO. GET ANOTHER CHARACTER (CCTYI OR ONCE)
ANDI T3,CK.CH7 ;COMCON DOESN'T WANT PARITY
PUSHJ P,SPCHEK ;CONVERT TO CONSISTENT BREAKS
JFCL ;ORDINARY CHARACTER
TLNE T1,CHCRET ;CARRIAGE RETURN?
JRST COMTI1 ;YES. GO GET LINEFEED INSTEAD
TLNE T1,CHBRK ;BREAK?
MOVEI T3,12 ;YES--MAKE INTO LINE FEED
TLNE T1,CHCNC ;IS THIS A CONTROL-C?
MOVEI T3,3 ;YES--CONTROL-C IS STRONGER THAN LF
PUSHJ P,CTISLC ;SAY THAT THIS IS THE "LAST CHAR"
PJRST T2POPJ## ;RESTORE AC T2 AND RETURN
;SUBROUTINE TO SEND 1 CHAR, SENDING CONTROL CHARS AS ^X
;OTHERWISE, SAME AS COMTYO
USEARO::PUSHJ P,SPCHEK ;SPECIAL CHAR?
JRST COMTYO ;NO, FORGET IT
TLNN T1,CHUAE ;ECHO AS ^X?
JRST COMTYO ;NO, GO ECHO NORMALLY
PUSH P,T3 ;SAVE THE CHAR
MOVEI T3,136 ;GET AN ARROW
PUSHJ P,COMTYO ;SEND IT
POP P,T3 ;RESTORE CHAR
TRC T3,100 ;CONVERT TO LETTER
;; JRST COMTYO ;AND GO TYPE IT
;SUBROUTINE TO SEND 1 CHARACTER, CHARACTER IN T3.
;PRESERVES T2 & T3
COMTYO::PUSH P,T2 ;SAVE AC
PUSH P,T3
HRRZ T2,.CPTOA## ;MAKE DISPATCH ADDRESS
PUSHJ P,(T2) ;CALL CCTYO, CTYWAT, OR ONCE ROUTINE
POP P,T3 ;RESTORE
JRST T2POPJ## ; AC'S AND RETURN
;SUBROUTINE FOR FORCE LEFT MARGIN FOR COMCON
COMFLM::HRRZ T3,.CPTOA## ;GET DISPATCH ADDRESS
CAIE T3,CCTYO ;FULL-BLOWN SCNSER DISPATCH?
JRST CRLF## ;NO, JUST TYPE A CRLF ALWAYS
MOVEI T3,MC.FLM ;YES, GET FORCE-LEFT-MARGIN FUNCTION CHAR
SE1ENT ;MUST RUN IN SECTION 1 TO CALL CCTYO8
PUSH P,T2 ;PROTECT T2
PUSHJ P,CCTYO8 ;TYPE META CHARACTER
JRST T2POPJ## ;RESTORE AC AND RETURN
;ROUTINE TO SET LDLBKA IN LDBDCH AND INFORM FE IF NECESSARY
SETBKA: MOVSI T1,LDLBKA ;GET THE BIT
TDNE T1,LDBDCH(U) ;IS IT SET ALREADY?
POPJ P, ;YES
IORM T1,LDBDCH(U) ;NO, SET IT
PJRST SETBMC ;AND GO TELL FE
;ROUTINE TO CLEAR LDLBKA IN LDBDCH AND INFORM FE IF NECESSARY
CLRBKA: MOVSI T1,LDLBKA ;GET THE BIT
TDNN T1,LDBDCH(U) ;IS IT CLEAR ALREADY?
POPJ P, ;YES
ANDCAM T1,LDBDCH(U) ;NO, CLEAR IT
PJRST SETBMC ;AND GO TELL FE
;ROUTINE TO SWITCH TERMINAL TO USER PROGRAM LEVEL AND START USER RUNNING
TTYUSW::TDZA S,S ;DON'T CLEAR WAIT BITS
TTYUSR::MOVE S,[XWD IOW,IOACT] ;CLEAR WAIT BITS
SE1ENT ;ENTER SECTION 1
HRRZ F,LDBDDB(U) ;GET ATTACHED DDB IF ANY
JUMPE F,TTYUS1 ;JUMP IF NOT ATTACHED
ANDCAB S,DEVIOS(F) ; ..
TLNE S,IOLBKA ;NEED TO RE-SET BREAK ON ALL BIT?
PUSHJ P,SETBKA ;YES, GO SET IT
MOVSI S,IOLBKA ;NOW CLEAR OUT
ANDCAB S,DEVIOS(F) ; ANNOYING TEMP BIT
PUSHJ P,UUOLDB ;MAKE LINE AND DEVIOS AGREE
TTYUS1: MOVE T1,LDBDCH(U) ;GET DEVICE BITS
TRNE T1,LDRPTY ;IS THIS A PTY?
PUSHJ P,PTMNMZ## ;YES. TELL CONTROLLER
MOVSI T1,LDLCOM ;PUT TERMINAL IN USER MODE
ANDCAM T1,LDBDCH(U) ;MAY BE DETACHED, BUT WILL WAIT
; AT UUO LEVEL IF NEEDED
PJRST SETRUN## ;SET USER'S RUN BIT AND RETURN
;ROUTINE TO SET TERMINAL TO COMMAND LEVEL
TTYSTC::SE1ENT ;ENTER SECTION 1
MOVE T2,LDBDCH(U) ;SEE IF THIS LINE IS SLAVED
TLNE T2,LDLSLV ;SLAVED?
JRST TTYST1 ;YES, DON'T REALLY SET COMMAND MODE
PUSH P,LDBBY2(U) ;PRESERVE L2RECS AROUND CNCMOD
PUSHJ P,CNCMOD ;AND GET TO COMMAND LEVEL
POP P,T1 ;GET L2RECS WORD BACK
ANDI T1,L2RECS ;WE ONLY CARE ABOUT THIS BIT
IORM T1,LDBBY2(U) ;RESTORE IF WAS SET
TTYST1:
IFN FTMIC,<PUSHJ P,MICWAK> ;WAKE MIC IF NECESSARY
IFE FTMIC,<MOVE T1,LDBDCH(U)> ;GET DCH BITS AGAIN
TRNN T1,LDRPTY ;PTY-DRIVEN LINE?
JRST TTYST3 ;NO, DON'T DO PTY STUFF
PUSHJ P,PTMNMD## ;YES. TELL CONTROLLER
JRST TTYST2 ;AND GO POKE IT FOR OUTPUT
TTYSTR::SE1ENT ;ENTER SECTION 1
MOVE T1,LDBDCH(U) ;GET DEVICE BITS
TRNE T1,LDRPTY ;IS IT A PTY?
TTYST2: PUSHJ P,PTYPE## ;YES. WAKE THE PTY CONTROLLER
TTYST3: PUSHJ P,COMQ ;AT COMMAND LEVEL?
PJRST NOCTRO ;NO. JUST CLEAR ^O BIT
PUSHJ P,TYIEAT ;YES. CLEAR THE COMMAND IN CASE MORE
PUSHJ P,STRTDL ;ECHO ONE DEFERRED LINE IF NECESSARY
SKIPLE LDBBKC(U) ;ANY MORE COMMANDS?
PUSHJ P,COMSET ;MAYBE. SET BIT IF AT COM LEVEL
PJRST NOCTRO ;CLEAR OSU AND RETURN
;HERE AT COMPLETION OF A COMMAND
TTYCMR::SE1ENT ;ENTER SECTION 1
PUSH P,T1 ;SAVE PREVIOUS LDPCMX
TRNN F,-1 ;ANY JOB?
PUSHJ P,TTYCPT ;NO. CLEAR PAPER-TAPE BITS
AOS T1,LINSAV##
CAIL T1,TTPLEN##
SETZM LINSAV##
HLL T2,LDBCOM(U) ;GET COMMAND REQUEST BITS
POP P,T1 ;COMMAND JUST FINISHED
LDB T3,LDPCMX ;CURRENT
CAME T1,T3 ;CHANGED?
TLNN T2,LDBCMF ;FORCED
SKIPA ;NO CHANGE OR NOT FORCED
POPJ P, ;NEW FORCED-DO IT
MOVEI T1,L2RECS ;SET EAT-COMMAND-SYNC BIT
TLNN T2,LDBCMF ;(UNLESS FORCED COMMAND)
IORM T1,LDBBY2(U) ;IN LINE DATA BLOCK
MOVSI T1,LDBCMR+LDBCMF;CLEAR COMMAND REQUEST BITS
IFN FTFDAE,<
TLNE T2,LDBFDX ;DOING FILDAE EXIT PROCESSING?
TLZ T1,LDBCMF ;YES, LEAVE LDBCMF ALONE
>
ANDCAB T1,LDBCOM(U) ;IN BASE WORD OF LDB
MOVE T1,LDBDCH(U) ;GET THE LINE'S CHARACTERISTIC
TLNN T1,LDLBKA+LDLIMI;ARE WE BREAKING ON ALL CHARACTERS
; OR IN IMAGE MODE?
JRST TTCMR1 ;NO, CONTINUE ON
SKIPLE LDBTIC(U) ;YES, DO WE HAVE ANY CHARACTERS
; IN THE INPUT BUFFER?
PUSHJ P,RCVWAK ;YES, WAKE THE JOB
;NO,...
TTCMR1::SE1ENT ;ENTER SECTION 1
MOVE T1,LDBCOM(U) ;GET THE LINES LDBCOM & CONTINUE
TLNN T1,LDBCMK ;FORCED KJOB PENDING?
IFN FTMIC,< ;IF MIC
PUSHJ P,CMDCLR ;NO, CLEAR COMMAND BIT
PJRST MICWAK ;WAKE MIC UP IF NEC & RETURN TO COMCON
> ;END OF IF MIC
IFE FTMIC,< ;IF NOT MIC
PJRST CMDCLR ;NO, CLEAR COMMAND BIT
POPJ P,0 ;YES, DO NOT CLEAR COMMAND BIT
> ;END OF IF NOT MIC
SUBTTL SUBROUTINES FOR COMCON OR UUO LEVEL
;COMMON UUO LEVEL ROUTINES
;TYO7W IS USED TO TAKE A 7-BIT CHARACTER IN T3
; GO INTO I/O WAIT IF JOB DETACHED OR IF THE LINE'S
; OUTPUT BUFFER IS RATHER BIG, THEN PLACE THE CHARACTER IN OUTPUT
; STREAM, AND START OUTPUT IF NEEDED.
;TYO9W IS SAME, BUT ASSUMES PARITY AND NINTH BIT ARE AS DESIRED.
;TYO CHOOSES ONE OF THE ABOVE, DEPENDING ON MODE IN S
;CALL TYO9W WITH SIGN BIT OF T3 SET TO AVOID BLOCKING. SIGN BIT CLEARED IF CHAR ACTUALLY OUTPUT
; (USED TO AVOID WTP STOPED ON CALL FROM TTMORE)
;CALL WITH DDB SET UP, CHARACTER IN T3.
;IF CALLED AT TYO, S MUST BE SET UP ALSO
TYO: TRNN S,I!PIMMOD ;IMAGE MODE USE OWN PARITY
TYO7W: ANDI T3,CK.CHR
TYO9W: MOVE S,DEVIOS(F)
TRNE S,IODERR ;^C TYPED ON TTYNNN
JRST [TLZ T3,(1B0) ;FLAG WE GOT CHAR
POPJ P,]
MOVSI S,IO ;INDICATE OUTPUT
IORB S,DEVIOS(F) ;..
MOVE U,DDBLDB(F) ;GET LINE ADDR IF ANY
JUMPN U,TYOX ;ATTACHED, PROCEED
JUMPL T3,CPOPJ ;IF ASYNCHRONOUS RETURN
PUSHJ P,CKATOW ;WAIT FOR ATTACH
SKIPA
TYOX: PUSHJ P,UUOLDB
MOVE T1,TTFREN## ;MAKE SURE THERE'S SOME CHARACTER SPACE LEFT
CAIGE T1,3 ;LEAVE 3 CHUNKS FOR SAFETY
JRST [JUMPGE T3,TYONFC ;NO,WAIT
POPJ P, ] ;UNLESS ASYNCH
MOVE T1,LDBTOC(U) ;GET OUTPUT STREAM LENGTH
CAML T1,TIWRNN ;IS HE OVER QUOTA?
JRST [JUMPGE T3,TYOOBF ;WAIT IF ATTACHED
POPJ P, ]
IFN FTMIC,<
IFN FTMLOG,<
SKIPN LDBLOT(U) ;IS HE LOGGING
JRST TYO9M ;NO
ADD T1,LDBLOC(U)
CAIL T1,^D100
JRST MICLGX ;GO WAKE UP MIC
TYO9M:> ;END OF FTMLOG CONDITIONAL
>;END IFN FTMIC
TLZ T3,(1B0) ;FLAG WE GOT CHARACTER
MOVE T1,LDBDCH(U) ;CHECK FOR OUTPUT SUPPRESS
SKIPL LDBOFL(U)
TRNE T1,LDROSU ; ..
POPJ P,0 ;NO. JUST RETURN DUE TO ^O
TYO9A: SCNOFF ;NO RACES
STCHK T3,LDBTOP(U),SONPPJ ;STORE CHARACTER IN CHUNKS
AOS LDBTOC(U) ;COUNT UP OUTPUT STREAM LENGTH
SCNON ;ALLOW INTERRUPTS
IFN FTMIC,< ;IF MIC
PUSHJ P,MICPOS ;YES SET UP AND CHECK POSITION
> ;END OF IF MIC
PJRST TOPOKE ;START OUTPUT FOR THE LINE
;HERE IF NO FREE CHUNKS
TYONFC: PUSH P,T3 ;ACS USED BY SETSLP
PUSH P,U
MOVEI T1,5 ;SLEEP FOR 5 SEC.
S0PSHJ SLEEP## ; ..
POP P,U ;RESTORE ACS
HRRZ F,LDBDDB(U)
POP P,T3
JRST TYO9W
IFN FTMIC&FTMLOG,<
MICLGX: PUSHJ P,MICWAK
JUMPL T3,TYO9M ;DON'T BLOCK IF FROM TTMORE
> ;END OF FTMLOG CONDITIONAL
;HERE IF OUTPUT BUFFER FULL
TYOOBF: PUSHJ P,TOWAT1
JRST TYO9W
;SUBROUTINE TO SETUP A BYTE COUNT AND POINTER TO A USER'S BUFFER
;CALLING SEQUENCE:
; MOVE S,DEVIOS(F)
; HRRZ P1,USER VIRTUAL ADDRESS OF BUFFER
; PUSHJ P,SRLPTR
;
;ON RETURN P1 IS A BYTE POINTER TO THE USER BUFFER AND P2 IS THE MAXIMUM
;BYTE COUNT FOR THE BUFFER. PRESERVES T1-T4.
SRLPTR::ADD P1,[POINT 7,1,35] ;ASSUME ASCII MODE (AND SKIP .BFCNT WORD)
TRNE S,PIMMOD!A8 ;PACKED IMAGE OR 8-BIT MODE?
HRLI P1,(POINT 8,,35) ;YES, USE 8-BIT BYTES
TRNE S,I ;REGULAR IMAGE MODE?
HRLI P1,(POINT 36,,35) ;YES, USE 36-BIT BYTES
TRNN S,I!PIMMOD!A8 ;ASCII MODE?
IMULI P2,5 ;YES, 5 BYTES PER WORD
TRNE S,PIMMOD!A8 ;PACKED IMAGE OR 8-BIT MODE?
LSH P2,2 ;YES, 4 BYTES PER WORD
POPJ P,
;SUBROUTINE FOR COMMAND LEVEL OUTPUT
CCTYO:: SE1ENT ;ENTER SECTION 1
ANDI T3,CK.CHR ;CCTYO DOESN'T DO IMAGE
;CCTYO8 IS LIKE TYO9W, BUT FOR LDB NOT DDB
CCTYO8: JUMPE U,CPOPJ## ;U MUST BE SET UP
SKIPG T2,TTFREN## ;SPACE IN STRINGS?
JRST CCTYO2 ;NO. QUIT.
CAIL T2,20
SKIPN TTFTAK ;IS THERE A FREE LIST?
JRST CCTYO2 ;NO--PUNT
PUSHJ P,UUOLVL## ;ARE WE WILLING TO BLOCK?
JRST CCTYO1 ;NO, LET IT GO BY
HRRZ T1,LDBDDB(U) ;CHECK DDB
JUMPE T1,CCTYO1 ;CAN'T WAIT IF NONE
MOVE T1,LDBTOC(U) ;GET COUNT
CAML T1,TIWRNN ;YES. SPACE IN THIS GUY'S AREA?
JRST CCTYO3 ;NO
CCTYO1: TLZ T3,(1B0) ;GOT CHARACTER
JRST TYO9A ;YES. GO TYPE IT.
CCTYO2: PUSHJ P,UUOLVL## ;MAKE SURE IT'S OK TO BLOCK
POPJ P, ;FORGET ABOUT OUTPUT IF NOT
CCTYO3: JUMPL T3,CPOPJ## ;DON'T BLOCK IF REQUESTED ASYNCHRONOUS
PUSH P,T3 ;YES, PRESERVE CHARACTER
PUSH P,U ;AND LINE
MOVEI T1,2 ;TWO SECONDS
S0PSHJ SLEEPF## ;WAIT FOR SOME SPACE TO APPEAR
POP P,U ;RESTORE LINE
POP P,T3 ;AND CHARACTER
JRST CCTYO8 ;AND TRY IT AGAIN
;SUBROUTINE TO CLEAR PAPER TAPE INPUT BITS, RETURNS LDBDCH IN T1
TTYCPT::SE1ENT ;ENTER SECTION 1
MOVSI T1,L2LTAP ;CLEAR TTY TAPE COMMAND BIT
ANDCAM T1,LDBBY2(U) ;IN BY2
MOVEI T1,L2RXON ;CLEAR XON IN EFFECT
ANDCAB T1,LDBBY2(U) ;AND RETURN NEW STATUS
POPJ P, ;RETURN
SUBTTL CTY ROUTINES
$LOW ;MUST BE IN THE LOW SEGMENT FOR ONCE-ONLY
;SUBROUTINE TO PRINT ON CTY IN EMERGENCY OR ONCE-ONLY
; WHEN INTERRUPT SYSTEM CANNOT BE USED OR TRUSTED
;CALL: MOVEI T1,ADR OF ASCIZ MESSAGE
; PUSHJ P,CTYTYP
; ALWAYS RETURN
CTYTYP::HRLI T1,440700 ;FORM BYTE POINTER
CTYTYL: ILDB T3,T1 ;GET NEXT CHARACTER
JUMPE T3,LCPOPJ ;END OF MESSAGE?
;(CPOPJ IS IN HISEG, SO DON'T USE IT)
PUSHJ P,CTYWAT ;NO, PRINT IT ON CTY AND WAIT
JRST CTYTYL ;GO GET NEXT CHAR.
;ROUTINE RESIDING IN LOSEG TO COMPUTE PARITY.
; USED ONLY FOR EMERGENCY CTY OUTPUT ROUTINES.
; USES T1
CTYPAR: MOVEI T1,(T3)
LSH T1,-4 ;FOLD INTO LOW 4 BITS
XORI T1,(T3)
TRCE T1,14 ;CHECK BITS 32 AND 33
TRNN T1,14
TRC T3,200 ;IF EVEN PARITY COMPLEMENT RESULTS
TRCE T1,3
TRNN T1,3
TRC T3,200 ;IF EVEN PARITY COMPLEMENT RESULTS
POPJ P, ;RETURN
;STILL IN $LOW
;SUBROUTINE FOR ERROR MESSAGE TO CTY DURING PARITY ERROR STOP
;CALL: MOVEI T3,CHARACTER
; PUSHJ P,CTYWAT
; RETURN AFTER CHARACTER HAS BEEN TYPED
;NOTE: DOES NOT USE INTERRUPT SYSTEM SO MESSAGE WILL GET OUT BEFORE HALT
;THIS SUB CALLED BY COMTYO WHEN COMTOA PATCHED
CTYWAT::PUSH P,T1
PUSHJ P,CTYPAR ;COMPUTE PARITY WITH LOSEG ROUTINE
IFN FTKS10,<
SKIPE CTYOWD ;CAN WE TYPE YET ?
JRST .-1 ;WAIT A WHILE
TRO T3,CTYOVL ;VALID FLAG
MOVEM T3,CTYOWD ;PUT UP FOR FRONT END TO SEE IT
RDAPR T1 ;GET PROCESSOR PIA
ANDI T1,SP.PIA ;LEAVE ONLY THE PIA
WRAPR SP.SSF+SP.IFE(T1) ;INTERRUPT THE FRONTEND
SKIPE CTYOWD ;WAIT FOR CTY TO BE IDLE
JRST .-1 ;OTHERWISE HALT OR RESET WILL CLOBBER LAST CHAR
JRST OPRFI2 ;OK TO RETURN
>;IFN FTKS10
IFN FTKL10,<
PUSHJ P,SPCTYO## ;SEND CHAR OVER
PUSHJ P,SPCWTO## ;WAIT FOR OUTPUT TO COMPLETE
JRST .-1
JRST OPRFI2 ;RESTORE T1 AND RETURN
>;END IFN FTKL10
;STILL IN $LOW
;SUBROUTINE TO ADD A DELAY FOR SLOW CTY'S
;CALL WITH:
; MOVEI T3,CHAR
; PUSHJ P,OPRFIL
;USED ONLY WITH PI SYSTEM OFF
OPRFIL::ANDI T3,CK.CH7 ;ONLY CHAR BITS
PUSH P,T1 ;SAVE T1
MOVEI T1,0 ;ASSUME NO FILLERS
CAIN T3,12 ;LF GETS
MOVEI T1,CTYDLF## ;8 TICKS
CAIN T3,15 ;CR GETS
MOVEI T1,CTYDCR## ;18 TICKS
JUMPE T1,OPRFI2 ;RETURN
ADDM T1,TIME## ;UPDATE TIME
PUSH P,T2 ;SAVE T2 FOR APR STATUS
IFN FTKS10,<
OPRFI1: RDAPR T2 ;GET CLOCK FLAG
TRNN T2,SP.ITI ;DID CLOCK TICK ?
JRST OPRFI1 ;NOT YET
ANDI T2,77 ;REDUCE TO PI ASSIGNMENTS
WRAPR SP.CSF+SP.ITI(T2) ;CLEAR CLOCK FLAG
>;IFN FTKS10
IFN FTKL10,<
OPRFI1: CONSO TIM,TI.ITD ;CLOCK "TICK" ?
JRST OPRFI1 ;NOT YET
CONO TIM,@ONCKLT## ;YES, CLEAR AND SET FOR ANOTHER "TICK"
>;END IFN FTKL10
SOJG T1,OPRFI1 ;LOOP FOR WHOLE TIME
POP P,T2 ;ADJUST STACK
OPRFI2: POP P,T1 ;--
LCPOPJ: POPJ P, ;LOCAL CPOPJ FOR USE WHEN HISEG ISN'T MAPPED
$HIGH ;BACK TO THE HIGH SEGMENT
SUBTTL DDB ROUTINES
;ROUTINE TO FIND A FREE TTY DEVICE DATA BLOCK
;CALL FROM CLOCK LEVEL TO DO AN ATTACH ON A NEW JOB, OR
;FROM UUO LEVEL ON AN INIT OF A NEW LINE.
;CALL: NO ARGUMENTS
; PUSHJ P,DDBSRC
; ERROR RETURN ;NONE AVAILABLE. F=0. T1 CLOBBERED
; OK RETURN ;ADDRESS IN F, TTYUSE SET IN DEVMOD
; ;RESPECTS J,U,T2.
; ;IF YOU DECIDE NOT TO USE DDB, YOU BETTER
; ;FREE IT UP AGAIN.
DDBSRC: PUSHJ P,DDBSR0 ;TRY TO GET A DDB
SKIPA ;LOST -- TRY AGAIN
PJRST CPOPJ1## ;WE WON
DDBSR0: HLRZ F,SCNDDB+DEVSER ;FIRST REAL TTY DDB
DDBSRA: MOVSI T1,TTYUSE ;FLAG THAT A DDB ISN'T FREE
SCNOFF ;MAKE SURE NO CONFLICT HERE
TDNN T1,DEVMOD(F) ;IS THIS DDB FREE?
JRST DDBSR1 ;YES. GO GRAB IT.
SCNON ;NO. REENABLE PI SYSTEM
HLRZ F,DEVSER(F) ;LINK DOWN THE DDB CHAIN
MOVE T1,DEVMOD(F) ;MAKE SURE STILL A TTY DDB
TLNE T1,DVTTY ;IS IT?
JUMPN F,DDBSRA ;YES. (UNLESS END OF CHAIN)
MOVEI F,0 ;NO MORE TTY DDB'S. WE LOSE.
POPJ P,0 ;RETURN NON-SKIP, WITH 0 IN DDB
DDBSR1: IORM T1,DEVMOD(F) ;SET BIT SO WE HAVE THE DDB
SCNON ;NOW PI'S CAN HAPPEN AGAIN
PUSHJ P,CLRDVL## ;CLEAR JOB NO. IN CASE OF JUNK
MOVE T1,[XWD TTYATC,ASSCON+ASSPRG] ;LIKEWISE MODE BITS
ANDCAM T1,DEVMOD(F) ; ..
MOVSI T1,DEPRAS ;GET THE RESTRICTED ASSIGN BIT
ANDCAM T1,DEVSTA(F) ;MAKE SURE IT'S CLEARED
SETZM DEVLOG(F) ;AND LOGICAL NAME
MOVSI T1,IOFST ;AND INITIAL S WORD
MOVEM T1,DEVIOS(F) ;WHICH SHOULD LEAVE IT PRETTY CLEAN
JRST CPOPJ1## ;SKIP RETURN. WE HAVE A DDB.
;ROUTINE TO FIND A TTY DDB WHICH IS ATTACHED TO, I.E.
;CONTROLLING, A PARTICULAR JOB NUMBER.
;
;CALLED AT COMMAND LEVEL BY ATTACH COMMAND, AND AT UUO LEVEL
;BY REFERENCES TO DEVICE "TTY" OR TTCALLS, ETC.
;
;CALL: MOVE J,JOB NUMBER DESIRED
; PUSHJ P,TTYSRC
; ERROR RETURN. ;NOT FOUND. AC'S U,F,S NOT GUARANTEED
; NORMAL RETURN ;U, S AND F SET UP. NOTE THAT THIS DOES
; ;!NOT! IMPLY THAT ANYONE IS ATTACHED. THAT IS,
; ; U MAY CONTAIN A ZERO
;
; ;CLOBBERS T1
TTYSRC::JUMPLE J,CPOPJ## ;NOBODY CONTROLS JOB ZERO. YOU ARE CONFUSED.
HRRZ F,TTYTAB##(J) ;GET CONTROLLING TTY DDB ADDRESS
JUMPE F,CPOPJ## ;RETURN IF NONE
MOVE T1,DEVMOD(F) ;GET DEVICE BITS FROM DDB
TLNN T1,TTYATC ;IS THIS THE CONTROLLING TTY?
POPJ P,0 ;NO. IT WAS A SLAVE OR SOMETHING.
MOVE U,DDBLDB(F) ;YES. GET THE LDB LINK (MAY BE 0)
MOVE S,DEVIOS(F) ;AND I/O STATUS WORD
JRST CPOPJ1## ;GIVE SUCCESS RETURN.
;ROUTINE CALLED WHEN DEVSRC CAN'T FIND DEVICE XXX (IN T1), AND
; IT WANTS TO SEE IF IT IS A PHYSICAL TTY. GETDDB CHECKS NAME,
; AND IF IT SHOULD BE A TTY, LOOKS FOR ITS DDB, OR MAKES ONE.
;
;CALL: MOVE J,JOBNUMBER OR JCH
; PUSH P,J
; MOVE T1,SIXBIT DEVICE NAME, ALLEGEDLY A PHYSICAL TTY NAME
; PUSHJ P,GETDDB
; ERROR RETURN, NOT A TTY OR THERE ARE NO DDB'S AVAILABLE.
; OK RETURN. IT IS A TTY, AND F AND U ARE NOW SET TO IT.
;RESPECTS T1 ON THE OK RETURN ONLY
;J WILL BE POPPED ON EITHER RETURN.
;CALL AT GETDDJ IF J HAS NOT YET BEEN PUSHED.
;
;CALLED FROM DEVSRC, SO MAY BE AT UUO OR CLOCK LEVEL
GETDDB::POP P,J ;BALANCE STACK (RESTORE JCH)
GETDDJ::SE1ENT ;ENTER SECTION 1
PUSH P,J ;SAVE JCH FOR CALLERS WHO CARE
ANDI J,JOBMSK## ;MAKE SURE OF JOB NUMBER FOR US
IFN FTMP,<
PUSHJ P,INTLVL## ;IF AT UUO LEVEL
PUSHJ P,ONCPU0## ;AVOID RACES WITH COMCON
>
PUSHJ P,TTYPHY ;LOOK FOR THIS PHYSICAL NAME
JRST JPOPJ## ;IT ISNT A TTY
JUMPN F,GETDB5 ;IS THERE A DDB ALREADY?
;IF SO, SOMEONE HAS CALLED GETDDB WHO
; COULD HAVE CALLED DEVSRC.
PUSHJ P,CHKFLN ;CHECK FOR LEGAL ACCESS TO FRCLIN
PUSHJ P,DDBSRC ;NO. NEED A NEW DDB. TRY TO GET ONE.
JRST JPOPJ## ;NONE AVAILABLE. FAIL RETURN
HRRM F,LDBDDB(U) ;SUCCESS. SET LINKS TO AND FROM DDB
MOVEM U,DDBLDB(F) ; AND LINE DATA BLOCK.
PUSHJ P,SCNNMX ;FILL IN REAL NAME AND PUNIT
IFN FTNET,<PUSHJ P,SETSTA> ;PUT STA # IN DDB
GETDB5: MOVE T1,DEVNAM(F) ;RESTORE REAL NAME TO T1
JRST JPOPJ1## ;AND GIVE SUCCESSFUL RETURN FROM GETDDB
;ROUTINE TO CHECK FOR LEGAL ACCESS TO FRCLIN.
;CALL: MOVE U,LDB ADDRESS
; PUSHJ P,CHKFLN
; RETURN HERE IF NOT FRCLIN OR LEGAL ACCESS
; RETURN HERE IF ACCESS NOT LEGAL
;DESTROYS T1
CHKFLN: LDB T1,LDPLNO ;GET LINE NUMBER
CAIE T1,FRCLIN## ;IS IT FRCLIN?
POPJ P, ;NO, GIVE OK RETURN
PUSHJ P,SAVT## ;SAVE T1-T4 FOR SAFETY
MOVSI T1,JP.POK ;MUST HAVE POKE PRIVILEGE OR BE
PJRST PRVBIT## ;BE LOGGED INTO [1,2] OR JACCT
;SUBROUTINE TO PUT PHYSICAL NAME INTO T2 FOR U WHOSE LDB IS IN U
;EVEN THOUGH THERE MAY BE NOTHING IN F OR LDBDDB
TTYNAM::SE1ENT ;ENTER SECTION 1
PUSH P,[SIXBIT /CTY/];SEE IF CTY
MOVEI T1,LDRCTY
TDNE T1,LDBDCH(U)
JRST T2POPJ## ;YES.
LDB T1,LDPLNO
MOVSI T3,'TTY' ;NO. CHANGE TO TTY
MOVEM T3,0(P) ;ON STACK
MOVSI T3,(POINT 6,0,17) ;SETUP SIXBIT BYTE POINTER TO
HRRI T3,0(P) ;NAME ON THE STACK
S0PSHJ SCNNMR ;AND CALL SAME ROUTINE AS SCNNMX DOES
PJRST T2POPJ## ;PUT ANSWER IN T2
;AND RETURN FROM TTYNAM
;SUBROUTINE TO FIND LDB FOR A PHYSICAL NAME, IF ITS A TTY
;AND LOAD F WITH LINKED DATA BLOCK, IF ANY, BUT DON'T MAKE ONE IF NONE YET
;SKIP RETURN IF ITS A TTY
TTYPHX: PUSHJ P,TSTOPR## ;SEE IF OPR AND FUDGE T1
PUSHJ P,SAVE2##
PUSH P,T1 ;SAVE NAME
MOVE P1,BOOTCT##
CAMN T1,[SIXBIT /CTY/] ;IS CTY WANTED?
JRST TTYPH1 ;YES. GO USE TCONLN
HLLZ P1,T1 ;GET FIRST THREE CHARACTERS
CAMN P1,[SIXBIT /TTY/] ;ARE THEY TTY?
TRNN T1,770000 ;AND ALSO IS FOURTH CHAR NON-BLANK?
PJRST TPOPJ## ;NO. NOT A LEGAL NAME.
MOVSI P2,(<POINT 6,0(P),17>) ;POINTER TO READ CHARS
MOVEI P1,0 ;INITIALIZE LINE TO 0
TTYPH4: ILDB T1,P2 ;GET A SIXBIT CHARACTER FROM NAME
JUMPE T1,TTYPH2 ;JUMP IF END OF NAME.
TRC T1,"0"-40 ;CONVERT SIXBIT TO BINARY
CAILE T1,7 ;IS IT AN OCTAL DIGIT?
JRST TPOPJ## ;NO. BAD CHAR IN NAME
ASH P1,3 ;MULTIPLY BY 8
ADDI P1,0(T1) ;ADD IN THIS DIGIT
TLNE P2,770000 ;CHECK FOR MORE DIGITS
JRST TTYPH4 ;LOOP FOR MORE DIGITS
TTYPH2: CAMLE P1,P3 ;IS IT A LEGAL HARDWARE LINE #?
JRST TPOPJ## ;NO. TOO BAD.
TTYPH1: MOVE U,LINTAB##(P1) ;GET LINE DATA BLOCK ADDRESS
SE1XCT <HRRZ F,LDBDDB(U)> ;GET ATTACHED DDB, IF ANY.
JRST TPOPJ1## ;GOOD RETURN
TTYPHY::PUSH P,P3 ;SET UP FOR PHYSICAL ONLY
MOVEI P3,TCONLN##
TTYPHZ: PUSHJ P,TTYPHX ;CALL COMMON SUBROUTINE
SOS -1(P) ;REMEMBER NON-SKIP RETURN
POP P,P3 ;BY PROPAGATING IT
JRST CPOPJ1##
TTYALL::PUSH P,P3 ;TRY ALL-PHYSICAL & VIRTUAL
MOVEI P3,TTPLEN##-1
JRST TTYPHZ
;SUBROUTINE TO FIND TTY FOR A JOB IN J (TTYFND) OR FOR
; CURRENT JOB (TTYFNU)
;RETURN WITH F AND U SET UP.
;GOES TO ERROR IF NO TTYDDB FOR THE JOB.
TTYFNU::MOVE J,.CPJOB## ;GET CURRENT UUO LEVEL JOB NUMBER
TTYFND::PUSHJ P,TTYSRC ;FIND THE JOB'S TTY DDB, ALSO U AND S
STOPCD CPOPJ##,DEBUG,NDJ, ;++NO DDB FOR JOB
POPJ P,0 ;SUCCESS. RETURN.
;SUBROUTINE TTYFUW (TELETYPE FIND FOR CURRENT USER AND WAIT), TO
;FIND CURRENT USER'S TTY AND WAIT FOR IT TO COME OUT OF OUTPUT
;WAIT, AND BE ATTACHED.
;SUBROUTINE TOWAIT, TO WAIT FOR TYPEOUT ACTIVITY TO (NEARLY) COMPLETE,
;IF NECESSARY.
TTYFUW::SE1ENT ;ENTER SECTION 1
PUSHJ P,TTYFNU ;FIND USER'S TTY
PUSHJ P,CKATTO ;CHECK THAT IT'S ATTACH. WAIT IF NOT.
IFN FTMIC,< ;IF MIC
MOVE T1,LDBMIC(U) ;CHECK FOR ERROR RESPONSE OR RESPONSE CODE SYNC
TLNE T1,LDLRSP!LDLRSY
POPJ P,0 ;IF HE WANTS RESPONSE STUFF DO NOT TO
> ;END OF IF MIC
;ROUTINE TO WAIT FOR NEARLY EMPTY OUTPUT BUFFER. CALL ONLY AT UUO LEVEL
TOWAIT: MOVE S,[XWD TTYOUW+IO+IOW,IOACT] ;SET ACTIVE & WAITING FIRST TO AVOID COMPLETION
IORM S,DEVIOS(F) ;BETWEEN TEST FOR COMPLETION & IOACT SET
MOVE T1,LDBTOC(U) ;GET COUNT OF TYPE-OUT CHARACTERS WAITING.
CAIL T1,10 ;OVER 7?
JRST TOWAT2 ;YES. HAVE TO WAIT
ANDCAB S,DEVIOS(F) ;NO. NOT WAITING, SO TURN OFF BITS
POPJ P, ;& RETURN
TOWAT1: MOVE S,[XWD TTYOUW+IO,IOACT] ;FLAG OUTPUT WAIT ACTIVITY
TOWAT2: IORB S,DEVIOS(F) ;IN THE DEVICE DATA BLOCK
PUSHJ P,PTSTRT ;WAKE UP SUBJOB, IF ANY
S0PSHJ WSYNC## ;WAIT FOR IO TO COMPLETE
MOVE U,DDBLDB(F) ;SET UP LDB IN CASE DETACH/ATTACHAPPENED WHILE WAITING
JUMPE U,[MOVE U,DEVMOD(F) ;LDB PTR GONE, GET STATUS WORD
TLNE U,TTYATC ;WAS THIS THE CONTROLLING TTY?
JRST TTYFUW ;YES, GO LOOK FOR IT
MOVSI S,TTYOUW+IO+IOW ;GET IO WAIT BITS
ANDCAB S,DEVIOS(F) ;AND CLEAR THEM
SETZ U, ;NOTE NO TTY FOR THE DDB
POPJ P,] ;NO, AN I/O DEVICE RETURN WITH IODERR SET
POPJ P, ;AND RETURN
PTSTRT: JUMPE U,CPOPJ## ;IN CASE U NOT SET UP
MOVEI T1,LDRPTY ;GET PTY BIT
TDNE T1,LDBDCH(U) ;IS THIS ONE
PJRST PTYPE## ;YES, WAKE UP CONTROLLER
POPJ P, ;NO, RETURN
;CO-ROUTINE TO SET FOR ERROR MESSAGES TO CTY DURING ONCE OR NORMAL
;TIMESHARING. PRESERVES .CPTOA AND ALL ACS EXCEPT T1.
CTYERM::PUSH P,U ;SAVE AC'S LIKE ADVERTISED
PUSH P,F
PUSHJ P,TTYERC ;SET UP U FOR CTY OUTPUT
PUSH P,.CPTOA## ;SAVE TYPEOUT ROUTINE ADDRESS
MOVEI T1,CTYWAT ;ASSUME SYSTEM STARTUP
SKIPN DINITF## ;ONCE-ONLY CHECK
MOVEI T1,CCTYO ;TIMESHARING
MOVEM T1,.CPTOA## ;SET TYPEOUT ROUTINE
PUSHJ P,@-3(P) ;CALL THE CALLER
SKIPA ;NON-SKIP RETURN
AOS -4(P) ;SKIP RETURN
POP P,.CPTOA## ;RESTORE TYPEOUT ROUTINE
POP P,F ;RESTORE AC'S
POP P,U
ADJSP P,-1 ;REMOVE CALLER'S PC
POPJ P, ;RETURN TO CALLER'S CALLER
;SUBROUTINE TTYERP TO FIND TTY DDB FOR A MONITOR ERROR MESSAGE.
;CALL WITH J SET TO JOB NUMBER TO BE TYPED AT.
;IF JOB IS ZERO, OR IF DESIRED JOB IS DETACHED, TTYERP RETURNS
;WITH U SET TO OPERATOR'S CONSOLE, AND F SET FROM IT,
;BUT OF COURSE THAT DDB MAY BE ZERO, SINCE MAY BE NO JOB AT OPR.
TTYERP::PUSHJ P,TTYSRC ;FIND THE TTY DDB IF POSSIBLE
JRST TTYERO ;NONE THERE. MAYBE JOB 0. GO FIND OPR
JUMPN U,CPOPJ1## ;SKIP RETURN TO SIGNAL LDB FOUND
TTYERO::SKIPE U,OPRLDB## ;GET OPERATOR LINE FROM ONCE
JRST TTYERX ;FINISH UP
TTYERC:: ;SETUP FOR CTY TYPEOUT
IFN FTMP,<
SKIPGE U,BOOTCP## ;GET BOOT CPU NUMBER
MOVE U,.CPCPN## ;US IF NOT YET SETUP
IMULI U,.CPLEN## ;MAKE CDB OFFSET FROM CPU0
HRRZ U,.C0CTN##(U) ;GET BOOT CTY LINE NUMBER
> ;END IFN FTMP
IFE FTMP,<
HRRZ U,.CPCTN## ;USE THE CTY LINE NUMBER
>
MOVE U,LINTAB##(U) ;AND POINT TO ITS LDB
TTYERX: SE1ENT ;ENTER SECTION 1
SKIPE F,U ;U MAY BE ZERO IF LINTAB NOT SET UP
HRRZ F,LDBDDB(U) ;GET DDB ADR, IF ANY.
POPJ P,0 ;AND RETURN FROM TTYERP
;SUBROUTINES TO SET UP LINE AND MAKE SURE ATTACHED.
;CALL WITH DDB SET UP, FROM UUO LEVEL ONLY.
;RETURN WHEN ATTACHED AND AT USER LEVEL, WITH LINE SET UP.
;ONE ROUTINE FOR INPUT, ONE FOR OUTPUT, ONE FOR OUTPUT AND USER LEVEL
CKATTI:
IFN FTRSP,<PUSHJ P,RSPTIR##> ;RECORD RESPONSE SATISFIED BY TTY INPUT UUO
CKATT0: MOVSI S,IO ;INDICATE INPUT
ANDCAB S,DEVIOS(F) ;SET UP STATUS WORD
MOVE U,DDBLDB(F) ;GET LINE BLOCK ADDR
JUMPN U,CKATI1 ;IF THERE, GO ON
CKATIW: MOVSI S,IO+TTYOUW ;MUST WAIT FOR ATTACH
ANDCAM S,DEVIOS(F) ;CLEAR DIRECTION BIT
MOVEI S,IOACT ;AND SET WAIT BIT FOR INPUT
IORB S,DEVIOS(F) ; ..
S0PSHJ WSYNC## ;WAIT FOR ATTACH
JRST CKATT0 ;GET LINE SET UP AND RETURN.
CKATI1: MOVE T1,DEVMOD(F) ;SEE IF TTY IS CONTROLLING JOB.
TLNE T1,TTYATC
JRST CKATI2 ;YES.
MOVSI T1,LDLCOM ;NO. MAKE IT BE
ANDCAM T1,LDBDCH(U) ;AT USER LEVEL
CKATI2: MOVE T1,LDBDCH(U) ;GET DEVICE BITS
TLNE T1,LDLCOM ;AT COMMAND LEVEL?
JRST CKATIW ;YES. CAN'T DO INPUT.
PUSHJ P,TYIEAT ;NO. SKIP ANY COMMANDS
PJRST UUOLDB ;AND GO ADJUST LINE BITS.
CKATOU: PUSHJ P,CKATTO ;FIRST MAKE SURE A LINE ATTACHED TO DDB
MOVE T1,LDBDCH(U) ;DEVICE BITS
TLNN T1,LDLCOM ;IS LINE AT COMMAND LEVEL?
POPJ P,0 ;NO. USER LEVEL. RETURN.
MOVE T1,DEVMOD(F) ;COMMAND LEVEL. SEE IF CONTROLLER OR I/O DEVICE
TLNN T1,TTYATC ;..
POPJ P,0 ;I/O DEVICE. LET IT THROUGH.
PUSHJ P,TOWAT1 ;CONTROLLER. WAIT SO DON'T CLOBBER COMMANDS
JRST CKATOU ;THEN TRY AGAIN FOR USER LEVEL
CKATTO: MOVSI S,IO ;INDICATE OUTPUT
IORB S,DEVIOS(F) ;SET UP STATUS WORD
MOVE U,DDBLDB(F) ;GET LINE ADDR IF ANY
JUMPN U,UUOLDB ;IF HAVE ONE, SEE IF TOP LEVEL
CKATOW: PUSHJ P,TOWAT1 ;WAIT FOR OUTPUT DONE. (WHICH
; IS FORCED ON ATTACH)
JRST CKATTO ;AND SET UP LINE, TO RETURN.
UUOLDB::SE1ENT ;ENTER SECTION 1
MOVE T2,LDBOST(U) ;FOR TRACKING CHANGES
MOVSI T1,LOLPIM ;GET PIM MODE BIT
TRNN S,PIMMOD ;IS THIS PACKED IMAGE MODE?
JRST [ANDCAM T1,LDBOST(U) ;NO, CLEAR BIT IN THE LDB
JRST UUOLD2] ;AND CONTINUE
TRZ S,IOSABS ;NO BREAK SETS IF PIM
TDNE T1,LDBOST(U) ;IS IT ALREADY SET?
JRST UUOLD2 ;YES, DON'T NEED TO DO THIS AGAIN
SCNOFF ;NO, KEEP OTHERS OUT WHILE WE SET UP FOR PIM
IORM T1,LDBOST(U) ;YES, SET IN STATES WORD
MOVE T1,LDBTIP(U) ;GET PUTTER
MOVEM T1,LDBECT(U) ;ADVANCE ECHO TAKER
MOVE T1,LDBECC(U) ;COUNT OF UNECHOED CHARACTERS
ADDM T1,LDBTIC(U) ;UPDATE AS IF ECHOED
MOVE T1,LDBIEC(U) ;NOT-IN-STREAM UNECHOED CHARACTERS
ADDM T1,LDBIIC(U) ;UPDATE AS IF ECHOED
SETZM LDBECC(U) ;NO MORE TO BE ECHOED
SETZM LDBIEC(U) ;AND NO MORE CK.NIS TO BE ECHOED
SCNON ;ALLOW OTHERS AGAIN
UUOLD2: XOR T2,LDBOST(U) ;GET CHANGE MASK
TLNE T2,LOLPIM ;DID WE CHANGE PIM STATUS?
PUSHJ P,SETCHP ;YES, POKE THE FRONT END
MOVSI T1,LDLBKM ;USER DEFINED BREAK SET IN USE BIT
MOVE T2,LDBBKB(U) ;FOR TRACKING CHANGES
TRNE S,IOSABS ;TERMINAL IN BREAK SET SPECIFIED MODE?
JRST [IORM T1,LDBBKB(U) ;YES, LITE THE BIT IN THE LDB
JRST UUOLD1] ; AND CONTINUE
ANDCAM T1,LDBBKB(U) ;CLEAR THE BIT IN THE LDB
UUOLD1: XOR T2,LDBBKB(U) ;GET CHANGE MASK
TLNE T2,LDLBKM ;DID WE CHANGE THE BREAK-SET BIT?
PUSHJ P,CHKBKC ;YES, GET BREAK COUNTS RIGHT
MOVEI T1,0 ;MAKE LDB AGREE WITH S
MOVE T2,LDBDCH(U) ;REMEMBER OLD CHARACTERISTICS
TLNE T2,LDLCNE ;IF COMMAND-LEVEL NO ECHO,
TLO T1,LDLNEC ;SUPPRESS ECHOING
TRNE S,A8 ;8-BIT ASCII MODE?
TLO T1,LDL8BI ;YES, 8-BIT INPUT MODE
TRNE S,IOSTEC ;TRUTH-IN-ECHOING SET?
TLO T1,LDLDLR ; YES
TRNE S,IOSFCS ;FULL-CHARACTER-SET SET?
TLO T1,LDLFCS ; YES
TRNN S,PIMMOD ;IS THIS PACKED IMAGE MODE?
TRNE S,IOSNEC ;OR NO ECHO BY PROGRAM?
TLO T1,LDLNEC ; YES
;THIS SHOULD NO LONGER BE NEEDED, ONLY TT?CHK SHOULD SET/CLEAR IT
; TRNE S,IOSBKA ;SINGLE CHARACTER MODE?
; TLO T1,LDLBKA ; YES
IORM T1,LDBDCH(U) ;SET THOSE NEEDING SETTING
; TLC T1,LDLNEC+LDLFCS+LDLDLR+LDLBKA+LDL8BI
TLC T1,LDLNEC+LDLFCS+LDLDLR+LDL8BI
ANDCAB T1,LDBDCH(U) ;AND CLEAR THE OTHERS
CAME T2,T1 ;DON'T SEND STATUS IF NO CHANGE
PJRST SETCHP ;NOTE THAT TERMINAL CHARACTERISTICS CHANGED
POPJ P, ;NO CHANGE
;HERE FROM UUOCON WHEN A TTY HAS BEEN INITED.
TTYOPN::MOVE U,DDBLDB(F) ;GET LDB ADDRESS
JUMPE U,TPOPJ1## ;FORGET IT IF DETACHED
SE1JRST ;CAN'T USE SE1ENT BECAUSE OF CROCK
; OF BEING CALLED WITH T1 ON THE STACK
MOVSI T2,LDLCOM ;GET COMMAND LEVEL BIT
MOVSI T1,TTYATC ;IS TTY CONTROLLING THE JOB?
TDNN T1,DEVMOD(F) ;OR IS IT AN I/O DEVICE?
ANDCAM T2,LDBDCH(U) ;I/O PUT IT AT USER LEVEL
PUSHJ P,UUOLDB ;SETUP THE LDB FROM S
PUSHJ P,SETCHP ;MAKE SURE THE FRONT END KNOWS ABOUT THIS
JRST @[0,,TPOPJ1##] ;AND RETURN IN SECTION 0 ALWAYS
;TWAITI -- WAIT FOR INPUT (CHARACTER OR LINE MODE)
TWAITI: TRNE S,IOSBKA ;BREAK ON ALL CHARACTERS?
JRST TWAITC ;YES, WAIT FOR A SINGLE CHARACTER
;FALL INTO TWAITL (EVEN FOR IMAGE MODES)
;TWAITL -- WAIT FOR AN INPUT LINE
TWAITL:
SKIPE LDBTOC(U) ;IF NO OUTPUT IN PROGRESS,
PUSHJ P,PTBTCH## ;AND THIS IS NOT A PTY
TRNA
PUSHJ P,TOWAT1
PUSHJ P,CLRPCT ;RESET THE "STOP" LINE COUNTER
PUSHJ P,CKATTI ;FIRST WAIT FOR ATTACH. SET DDB AND LINE
PUSHJ P,TTLCHK ;CHECK FOR A LINE BEING PRESENT
JRST TWATLK ;BE SURE
POPJ P, ;LINE PRESENT, RETURN
TWATL1: PUSHJ P,TIWAIT ;NO. GO WAIT FOR ONE.
TRNE S,IODERR ;GOT A ^C?
POPJ P, ;YES, LINE PRESENT
PUSHJ P,CKATTI ;MAKE SURE DIDN'T DETACH DURING WAIT
PUSHJ P,TTLCHK
JRST TWATLK
POPJ P,
TWATLK: MOVE S,[XWD IOW,IOACT] ;FLAG ACTIVE AND WAITING SO
IORB S,DEVIOS(F) ;INTERRUPT WILL NOT FIND HIM ACTIVE
PUSHJ P,TTLCHK ;BUT NOT WAITING. THEN LOOK AGAIN
JRST TWATL1 ;NOTHING ARRIVED SINCE LAST TEST
MOVE S,[XWD IOW,IOACT] ;SOMETHING DID SNEAK IN!
ANDCAB S,DEVIOS(F) ;SO FORGET ABOUT WAITING
POPJ P,
;SUBROUTINE TO WAIT FOR SINGLE CHARACTER INPUT
TWAITC:
SKIPG LDBTOC(U) ;IF NO OUTPUT IN PROGRESS,
PUSHJ P,CLRPCT ;RESET THE "STOP" LINE COUNTER
PUSHJ P,CKATTI ;MAKE SURE ATTACHED
PUSHJ P,TTCCHK ;CHECK FOR A INPUT BEING PRESENT
JRST TWATCK ;BE SURE
POPJ P, ;INPUT PRESENT, RETURN
TWATC1: PUSHJ P,TIWAIT ;NO. GO WAIT FOR ONE.
TRNE S,IODERR ;GOT A ^C?
POPJ P, ;YES, INPUT PRESENT
PUSHJ P,CKATTI ;MAKE SURE DIDN'T DETACH DURING WAIT
PUSHJ P,TTCCHK
JRST TWATCK
POPJ P,
TWATCK: MOVE S,[XWD IOW,IOACT] ;FLAG ACTIVE AND WAITING SO
IORB S,DEVIOS(F) ;INTERRUPT WILL NOT FIND HIM ACTIVE
PUSHJ P,TTCCHK ;BUT NOT WAITING. THEN LOOK AGAIN
JRST TWATC1 ;NOTHING ARRIVED SINCE LAST TEST
MOVE S,[XWD IOW,IOACT] ;SOMETHING DID SNEAK IN!
ANDCAB S,DEVIOS(F) ;SO FORGET ABOUT WAITING
POPJ P,
;TTICHK -- CHECK IF ANY INPUT IS AVAILABLE, LINE OR CHARACTER MODE
;CALL IS:
;
; PUSHJ P,TTICHK
; NO INPUT AVAILABLE
; INPUT IS AVAILABLE
;
;THE CALLER MUST SETUP U, F, AND S APPROPRIATELY (TTLCHK AND TTCCHK
;DON'T REQUIRE F AND S, BUT TTICHK DOES).
;
;TTLCHK IS THE ROUTINE THAT HANDLES REGULAR ASCII LINE MODE, AS
;AS THE IMAGE MODES, TTCCHK HANDLES ASCII CHARACTER MODE.
TTICHK: TRNE S,IOSBKA ;BREAK ON ALL CHARACTERS MODE?
JRST TTCCHK ;YES, LOOK FOR JUST A SINGLE CHARACTER
;NO, FALL INTO TTLCHK (EVEN FOR IMAGE MODES)
;TTLCHK -- CHECK IF AN INPUT "LINE" IS AVAILABLE
TTLCHK::PUSHJ P,CLRBKA ;CLEAR BREAK ON ALL CHARACTERS BIT
TTLCK2: TRNN F,-1 ;DO WE REALLY HAVE A DDB?
SETZ S, ;NO DDB, NO I/O STATUS
SE1ENT ;ENTER SECTION 1
PUSHJ P,TICAVL ;ANY INPUTTABLE CHARACTERS?
TRNN S,I!PIMMOD ;YES, IMAGE MODE OF SOME SORT?
SKIPLE LDBBKC(U) ;LINE MODE, ANY LINES AVAILABLE?
JRST CPOPJ1## ;INPUT AVAILABLE
MOVE T2,LDBTIC(U) ;GET CHARACTERS
SUB T2,LDBIIC(U) ;IGNORE THOSE NOT PRESENT
PUSHJ P,CHKTIF ;AT THE END OF A FIELD (USER SPECIFIED LINE)?
CAIL T2,^D70 ;NO, NO LINES, GOT LOTS OF CHARACTERS?
JRST CPOPJ1## ;YES, CLOSE ENOUGH, WAKE UP USER
MOVSI T2,L1LUNR ;UNREAD WAITING BIT
TDNE T2,LDBBYT(U) ;SEE IF TEMPORARILY ASYNCH
JRST CPOPJ1## ;YES, INPUT IS AVAILABLE
MOVE T2,LDBDCH(U) ;DEVICE BITS
TLNE T2,LDLIMI ;NO. IMAGE INPUT STATE?
TLNN S,FRCEND ;YES. ALSO TIMED OUT?
PJRST TTLWAK ;START DEFERED ECHO AND WAKE MIC IF NEEDED
JRST CPOPJ1## ;IMAGE TIME OUT, WAKE UP HIGHER-UPS
;TTCCHK -- CHECK IF AN ASCII CHARACTER IS AVAILABLE
TTCCHK: PUSHJ P,SETBKA ;SET "BREAK ON ALL CHARACTERS" IN LDB
PUSHJ P,TICAVL ;ANY REAL CHARACTERS AVAILABLE?
JRST CPOPJ1## ;YES, SKIP RETURN
MOVSI T1,L1LUNR ;UNREAD WAITING BIT
TDNE T1,LDBBYT(U) ;SEE IF TEMPORARILY ASYNCH
JRST CPOPJ1## ;YES, INPUT IS AVAILABLE
; PJRST TTCWAK ;START DEFERRED ECHO AND WAKE MIC IF NEEED
;TTCWAK -- WAKE MIC FOR CHARACTER MODE
;TTLWAK -- WAKE MIC FOR LINE MODE
TTCWAK: TDZA T1,T1 ; CHARACTER MODE
TTLWAK: MOVEI T1,1 ;LINE MODE
PUSHJ P,@[EXP <IFIW STRTDC>,<IFIW STRTDL>](T1) ;START DEFERRED ECHO
IFN FTMIC,<
SKIPE LDBMIC(U) ;MIC CONTROLLED TTY?
PUSHJ P,MICWAK ;WAKE UP MASTER MIC
>
POPJ P, ;RETURN
;TICAVL -- CHECK FOR AVAILABLE CHARACTERS IN LDBTIC
;NON-SKIP FOR YES,
;SKIP FOR DELAY
;USES T1
TICAVL::SE1ENT ;ENTER SECTION ONE
SCNOFF ;NO INTERRUPTS WHILE LOOKING
MOVE T1,LDBTIC(U) ;GET INPUT COUNT
CAMLE T1,LDBIIC(U) ;MORE THAN DELETED?
JRST SONPPJ ;YES, RETURN SUCCESS IMMEDIATELY
CAMN T1,LDBIIC(U) ;SANITY CHECK, DO THEY MATCH?
JRST TICAV1 ;STILL MIGHT BE SOME EXPANDING
JUMPE T1,INPCH1 ;IF SHOULD BE ZERO, DO ALTERNATE SANITY CHECK
STOPCD .+1,INFO,TMDELI, ;++ TOO MANY <DEL>S IN INPUT
MOVEM T1,LDBIIC(U) ;MAKE COUNTS MATCH
JRST SONPJ1 ;AND SEE WHAT HAPPENS
TICAV1: MOVE T1,LDBBY3(U) ;GET EXPANSION BITS
TLNN T1,L3LIHD!L3LIPD ;ARE WE EXPANDING INPUT?
JRST SONPJ1 ;NO, NOTHING AVAILABLE
JRST SONPPJ ;YES, SOMETHING'S STILL THERE
;ECCAVL -- CHECK FOR INPUT AVAILABLE FROM ECHO STREAM
;NON-SKIP FOR YES,
;SKIP FOR DELAY
;USES T2
ECCAVL::SCNOFF ;NO INTERRUPTS WHILE LOOKING
MOVE T2,LDBECC(U) ;GET COUNT OF UNECHOED CHARACTERS
CAMLE T2,LDBIEC(U) ;MORE THAN DELETIONS?
JRST SONPPJ ;YES, GIVE AVAILABLE RETURN
CAME T2,LDBIEC(U) ;DO THEY MATCH?
STOPCD .+1,INFO,TMDELE, ;++ TOO MANY DELETIONS FROM ECHO
MOVEM T2,LDBIEC(U) ;MAKE THEM MATCH
MOVE T2,LDBBY3(U) ;GET EXPANSION BITS
TLNE T2,L3LEHD!L3LEPD ;ARE WE EXPANDING?
JRST SONPPJ ;STILL HAVE SOME IF SO
JRST SONPJ1 ;SAY NONE AVAILABLE
;SUBROUTINE TIWAIT TO WAIT FOR SOME INPUT, AND SEND XON IF NEEDED.
TIWAIT:
IFN FTMIC,< ;IF MIC
SKIPE LDBMIC(U) ;MIC RUNNING FOR THIS LINE?
PUSHJ P,MICWAK ;YES, WAKE MIC IF NECESSARY
> ;END OF IF MIC
MOVEI T1,LDRPTY ;IS THIS LINE PTY-DRIVEN?
TDNE T1,LDBDCH(U) ;CHECK IN THE LDB CHARACTERISTICS
PUSHJ P,PTYOW## ;YES. GO MARK THIS WAIT.
MOVSI S,IO+TTYOUW ;MARK DIRECTION AS INPUT.
ANDCAB S,DEVIOS(F) ;CLEAR IN CORE
MOVEI T1,IMGTIM ;TIMEOUT FOR IMAGE MODE
TRNE S,I ;TERMINAL IN IMAGE MODE?
DPB T1,LDPTIM ;YES. STORE TIMEOUT TIME
PUSHJ P,CHKXON ;SEND X-ON IF NEEDED
S0JRST WSYNC## ;WAIT FOR INPUT
;SUBROUTINE TO START DEFERRED ECHO
;CALL
; MOVEI T2,BIT (EITHER L1RDEL FOR LINE OR L1RDEC FOR CHARACTER)
; PUSHJ P,STRTDE
; <ALWAYS RETURNS HERE>
STRTDC::SE1ENT ;ENTER SECTION 1
MOVE T2,[L1LUNR,,L1RDEC] ;THE ALLOW-ONE-CHARACTER-TO-ECHO BIT
TDNN T2,LDBBYT(U) ;IS BIT ALREADY SET, OR
PUSHJ P,TICAVL ;IF SOME CHARACTER(S) ALREADY ECHOED
POPJ P, ;YES, DON'T ECHO ANY MORE
JRST STRTDE ;COMMON CODE
STRTDL::SE1ENT ;ENTER SECTION 1
MOVE T2,[L1LUNR,,L1RDEL] ;THE ALLOW-ONE-LINE-TO-ECHO BIT
TDNN T2,LDBBYT(U) ;IS IT ALREADY SET, OR
SKIPLE LDBBKC(U) ;ARE ANY LINES AVAILABLE?
POPJ P, ;YES, DON'T ECHO ANY MORE
STRTDE::SE1ENT ;ENTER SECTION 1
HRRZS T2 ;GET RID OF L1LUNR
IORM T2,LDBBYT(U) ;SET BIT ALLOWING LINE OR CHARACTER
MOVEI T2,L1RDEM ;GET DEFERRED ECHO MODE BIT
SKIPL LDBBKB(U) ;BREAK MASK IS ALWAYS DEFERRED
TDNE T2,LDBBYT(U) ;DEFERRED?
SKIPG LDBECC(U) ;AND INPUT WAITING?
PJRST CHKXON ;NOT DEFERRED, OR NO INPUT WAITING
; MAKE SURE WE ARE ACCEPTING INPUT
PJRST TOPOKE ;GET OUTPUT STARTED
;ROUTINE TO CHECK IF AN XOFF HAS BEEN SENT OUT
;AND IF SO, TO SEND AN XON.
;CALLED BY:
; PUSHJ P,CHKXON
; RETURN HERE ALWAYS (CLOBBERS T1,T3)
CHKXON::SE1ENT ;ENTER SECTION 1
MOVSI T1,LPLXOF ;IS PAGE MODE ENABLED?
TDNN T1,LDBPAG(U) ;GUARANTEE XON IF TALKING TO
;ANOTHER COMPUTER
POPJ P, ;XON IS NOT NEEDED
CHKXN1: MOVE T1,LDBTIC(U) ;GET # OF INPUT CHARS
ADD T1,LDBECC(U) ;PLUS THOSE TO BE ECHOED
CAILE T1,^D80 ;TOO MANY?
POPJ P, ;YES, GO AWAY
MOVSI T1,LPLXOF ;CLEAR XOFF BIT
ANDCAM T1,LDBPAG(U) ;SO ONLY ONE XON IS SENT
MOVEI T3,IRRCSA ;CODE FOR CHUNK SPACE AVAILABLE (SEND XON)
MOVEI T1,ISRREM ;INDEX FOR REMOTE HANDLER
PUSHJ P,@LDBISR(U) ;TRY TO CRANK IT UP AGAIN
SKIPA T2,FLPXON ;NON-SKIP MEANS WE MUST SEND THE XON
PJRST TOPOKE ;XON ALREADY SENT, JUST QUEUE THE TERMINAL
PUSHJ P,SETXNP ;SET THE XON FILLER
PJRST TOPOKE ;START TERMINAL MOVING
;ROUTINE TO GET DDB OUT OF TI WAIT IF NEEDED
;CALLED BY:
; MOVE J,JOB #
; PUSHJ P,CLRTI
; RETURN HERE
;RESPECTS T1,T2
CLRTI:: PUSH P,T1 ;SAVE SOME AC'S
PUSH P,T2
LDB T1,PJBSTS## ;GET WAIT STATE CODE
CAIE T1,TIOWQ## ;IN TI WAIT?
JRST CLRTI1 ;NO--EXIT
PUSHJ P,TTYSRC ;FIND TTY DDB
JRST CLRTI1 ;NO DDB?
MOVE T1,[IOW,,IOACT]
ANDCAM T1,DEVIOS(F)
CLRTI1: POP P,T2
JRST TPOPJ##
IFN FTMPXSER,<
;SUBROUTINE TO RETURN TTY OUTPUT FEASIBILITY FOR A MPX-CONTROLLED TTY
;CALL WITH F/ADDRESS OF TTY DDB
;RETURN WITH T1/0 IF NO OUTPUT OR 1 IF OK TO OUTPUT
TTYOFE::SE1ENT ;ENTER SECTION 1
MOVE T2,DDBLDB(F) ;ADDRESS OF TTY LDB
MOVE T1,LDBTOC(T2) ;COUNT OF OUTPUT CHARACTERS STILL WAITING
HLL T1,LDBOST(T2) ;STATE BITS
TDNE T1,[LOLSTP+777740] ;IF ^S'ED OR MORE THAN 32 CHARACTERS
TDZA T1,T1 ;SAY OUTPUT NOT FEASIBLE
MOVEI T1,1 ;OTHERWISE GIVE GO AHEAD
POPJ P, ;RETURN TO MPXSER
;SUBROUTINE TO INITIALIZE TTY-SPECIFIC VALUES WHEN CONNECTING A TTY TO AN
;MPX CHANNEL
;CALL WITH F/ADDRESS OF TTY DDB
;RETURN CPOPJ ALWAYS
TTYMPX::SE1ENT ;MAY NEED TO REFERENCE LDB
PUSH P,U ;PRESERVE LDB AC
PUSH P,F ;AND DDB AC (LH JUNK)
HRRZS F ;CLEAR LH FOR NZS INDEXING
SETZM DEVXTR(F) ;DISCARD PARTIAL OUTPUT BUFFER
MOVE S,DEVIOS(F) ;GET I/O MODE
TRNN S,I ;IMAGE MODE?
JRST FUPOPJ## ;NO, NOTHING ELSE TO DO
MOVEI T1,ASSCON ;ASSIGNED-BY-CONSOLE BIT
TDNN T1,DEVCHR(F) ;IS IT LIT?
JRST TTYMPE ;NO, DON'T LIGHT LDLIMI (IMAGE NOT ALLOWED)
MOVE U,DDBLDB(U) ;POINT TO LDB
MOVSI T1,LDLIMI ;GET IMAGE MODE BIT
IORM T1,LDBDCH(U) ;SET IN LDB
PUSHJ P,SETCHP ;INFORM FE'S
JRST FUPOPJ## ;RETURN TO MPXSER
TTYMPE: MOVEI S,IOIMPM ;ERROR FOR IMAGE MODE NOT ALLOWED (SEE TTYINE)
IORB S,DEVIOS(F) ;SET IT FOR MPXSER TO SEE
JRST FUPOPJ## ;RETURN TO MPXSER
> ;END IFN FTMPXSER
;ROUTINE TO PUT SIXBIT NAME IN DEVNAM(DDB), AND TO SET PUNIT.
;CALL: SET DDB TO DEVICE DATA BLOCK TO RECEIVE THE NAME AND UNIT
; SET LINE TO LINE DATA BLOCK WHERE LINE NUMBER WILL BE FOUND
; AND SET OR CLEAR IMAGE BIT IN DEVMOD DEPENDING ON
; WHETHER THIS LINE WILL BE PTY-DRIVEN OR NOT
; PUSHJ P,SCNNMX
; RETURN
;CLOBBERS T1 AND T3
SCNNMX: PUSH P,T2 ;SAVE T2
PUSHJ P,TTYNAM ;BUILD NAME OF DEVICE
MOVEM T2,DEVNAM(F) ;STORE IN DDB
POP P,T2 ;RESTORE T2
LDB T1,LDPLNO ;GET PHYSICAL LINE NUMBER
DPB T1,PUNIT## ;AND STORE IT IN THE DDB
SETZM DEVSTS(F)
MOVEI T3,<1_I> ;GET IMAGE MODE BIT.
IORM T3,DEVMOD(F) ;SET IT IN THE DDB
MOVE T1,LDBDCH(U) ;GET DEVICE BITS
TRNE T1,LDRPTY ;IS THIS A PTY?
ANDCAM T3,DEVMOD(F) ;YES. CLEAR THE BIT.
POPJ P,0 ;RETURN FROM SCNNMX
;SUBSIDIARY ROUTINE TO DO RADIX PRINT TO CORE.
SCNNMR: IDIVI T1,10 ;DEVICE NAMES ARE OCTAL
HRLM T1+1,0(P) ;STORE A DIGIT ON STACK
SKIPE T1 ;NEED MORE DIGITS?
S0PSHJ SCNNMR ;YES. GO MAKE THEM.
HLRZ T1,0(P) ;RETRIEVE A DIGIT FROM STACK
ADDI T1,"0"-40 ;CONVERT TO SIXBIT
IDPB T1,T3 ;STORE IN OBJECT WORD (DEVNAM)
POPJ P,0 ;POP UP TO SCNNMR OR BACK TO SCNNMX
IFN FTNET,<
;ROUTINE TO LOCATE A NEW TTY DDB
SETSTA: PUSHJ P,FNDSTA ;FIND STATION
DPB T1,PDVSTA## ;PUT STA # IN DEVICE LOC FIELD
POPJ P, ;RETURN
FNDSTA::SE1ENT ;ENTER SECTION 1
MOVE T1,LDBDCH(U) ;GET TTY BITS
TRNN T1,LDRPTY ;TERMINAL A PTY LINE?
JRST DDBRL ;NO - BRANCH FOR REAL TERMINAL
LDB T1,LDPLNO ;YES, GET LINE NUMBER ONLY
SUBI T1,PTYOFS## ;DECREMENT TO PTY LINE NUMBER
PUSH P,F ;SAVE TTY DDB FOR A SECOND
MOVE F,PTYTAB##(T1) ;GET PTY DDB
LDB T1,PDVSTA## ;GET LOCATION OF PTY
JRST FPOPJ## ;RESTORE TTY DDB AND RETURN TO CALLER
DDBRL: SKIPL LDBTTW(U) ;ANF NETWORK TERMINAL?
.CREF LTLANF ;(CREF REFERENCE TO REAL SYMBOL)
JRST DDBRL1 ;NO, MUST BE A LOCAL TERMINAL
LDB T1,LDPRNN ;YES, GET THE REMOTE NODE NUMBER
JUMPE T1,DDBRL1 ;LOCAL(?)
POPJ P, ;RETURN.
DDBRL1: MOVE T1,JBTLOC## ;LOCAL STATION
POPJ P, ;RETURN
> ;END IFN FTNET
;ROUTINE TO RESET DEVOPR TO THE CTY IF A REMOTE LINE
;THIS IS USED BY ROUTINES WHICH MIGHT DETACH OR HOST
;AWAY A REMOTE LINE WHEN THAT LINE WAS DEVOPR.
;CALL: MOVE U, LDB ADDRESS
; PUSHJ P,TTYOPR
;PRESERVES ALL ACS EXCEPT T1
TTYOPR::JUMPE U,CPOPJ## ;RETURN IF NO LDB
MOVSI T1,LTLREM ;REMOTE BITS
CAMN U,OPRLDB## ;CURRENT LINE DEVOPR?
TDNN T1,LDBTTW(U) ;AND REMOTE?
POPJ P, ;NOT OPR OR HARDWIRED LINE
PUSH P,U ;SAVE U
PUSH P,T2 ;SAVE T2
MOVE U,BOOTCT## ;CURRENT CTY LINE NUMBER
MOVE U,LINTAB##(U) ;GET ITS LDB ADDRESS
MOVE T1,@LDBDDB(U) ;AND DEVICE NAME
PUSHJ P,STDOPR ;SET DEVOPR, NETOPR
JFCL ;CAN'T FAIL
POP P,T2 ;RESTORE T2
POP P,U ;RESTORE U
POPJ P, ;RETURN
;ROUTINE TO ESTABLISH DEVICE OPR IF POSSIBLE
;CALL: MOVE T1,DEVICE NAME
; PUSHJ P,STDOPR
;RETURN CPOPJ IF ILLEGAL
;SKIP RETURN WITH DEVICE CHANGED
STDOPR::PUSHJ P,TTYPHY ;LOOK FOR THIS PHYSICAL NAME
POPJ P, ;FAILED IF NOT POSSIBLE
MOVEM U,OPRLDB## ;SAVE NEW LDB ADDRESS
MOVEM T1,DEVOPR## ;SAVE NEW NAME
JRST NETOPR## ;TELL NETWORK THAT OPR CHANGED
SUBTTL ROUTINES FOR PTY
;PTYPUT IS CALLED FROM PTYSER TO PLACE A CHARACTER IN A TERMINAL INPUT
;BUFFER AS THOUGH THE TERMINAL HAD BEEN TYPED ON. NO ECHOING IS ALLOWED,
;THOUGH AND THIS ROUTINE IS A SIMPLIFIED VERSION OF RECINT AND
;XMTECH, TO MAKE THE CHARACTERS VISIBLE TO THE CONTROLLED JOB WITHOUT ECHOING
;CALL
; MOVE T3,CHAR
; MOVE T1,CHAR BITS FROM SPCHEK
; PUSHJ P,PTYPUT
; ERROR RETURN
; NORMAL RETURN
CNTRLO==17
PTYPUT::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;PRESERVE P1
MOVSI P1,LDLFSP ;THE FULL-SCNSER-SERVICE BIT
TDNE P1,LDBTTW(U) ;IS THIS PTY BEING A TTY?
JRST PTYPT1 ;YES, LET SCNSER DO CHARACTER HANDLING
TLNE T1,CHALT ;POSSIBLE ALTMODE?
PUSHJ P,RIALTO ;YES, CONVERT IF WANTED
MOVE P1,T1 ;SAVE BITS IN P1
CAIN T3,CNTRLO
PJRST FLPCNO
IFN FTMIC,< ;IF MIC
SKIPE LDBMIC(U)
CAIE T3,1 ;CONTROL A COUNTS AS ^C TO MIC
> ;END OF IF MIC
CAIN T3,3 ;CONTROL C?
JRST PTYCC ;YES. SPECIAL CHECKING
CAIN T3,"T"-100
JRST PTYCT
PTYINA:
MOVSI T2,L2LCCS ;NOT CONTROL C, SO
ANDCAM T2,LDBBY2(U) ;CLEAR SYNC BIT
IFN FTMIC,< ;IF MIC
SKIPE T2,LDBMIC(U)
JRST PTYMCK
> ;END OF IF MIC
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
PTYPT1: MOVE T2,LDBTIC(U) ;IS THIS LINE ALREADY FULL?
CAIG T2,^D200 ; ..
SKIPG TTFREN## ;OR LISTS EXHAUSTED?
POPJ P,0 ;YES. DISCARD CHAR
SKIPN TTFTAK ;ANY FREELIST
POPJ P,0 ;NO--PUNT
AOS (P) ;GOING TO GIVE GOOD RETURN NOW
MOVSI T2,LDLFSP ;THE FULL-SCNSER-PTY BIT
TDNE T2,LDBTTW(U) ;IS THIS UNDER FULL SCNSER CONTROL?
PJRST RECPTY ;YES, ENTER AT THE TOP
IFN FTMIC,< ;IF MIC
MOVE T1,P1 ;SETUP CHARACTER BITS FOR MICECH
SKIPE LDBMIC(U)
PUSHJ P,MICECH ;SAY COL1 TO MIC
> ;END OF IF MIC
SCNOFF ;NO INTERRUPTION
STCHK T3,LDBTIP(U),SONPPJ ;STORE CHARACTER
TLNE P1,CHBRK ;IS THIS A BREAK CHARACTER?
PUSHJ P,SETBKU ;YES, STORE LAST BREAK POINTER
LDCHK T3,LDBECT(U),PTYPT5 ;TAKE CHARACTER NEEDING ECHO
TLNE P1,CHBRK ;BREAK CHAR?
AOS LDBBKC(U) ;YES. COUNT BREAKS
AOS T2,LDBTIC(U) ;ADVANCE TYPEIN COUNT
PTYPT5: SCNON ;ALLOW INTERRUPTS AGAIN
MOVE T4,LDBDCH(U) ;GET DEVICE FLAGS
TLNE T4,LDLBKA ;TERMINAL IN BREAK-ON-ALL MODE?
PUSHJ P,RCVWKQ ;YES. WAKE JOB IF WAITING
PUSHJ P,CHKTIB ;ENOUGH TO WAKE ON?
TLNE P1,CHBRK ;OR A BREAK CHARACTER?
PUSHJ P,ECHBRK ;YES. WAKE THE JOB
POPJ P, ;SUCCESSFUL RETURN TO PTYSER
;MORE OF PTYPUT. SPECIAL CODE FOR CONTROL C
PTYCC:
IFN FTMIC,< ;IF MIC
PUSH P,P1 ;SAVE CHARACTER BITS (USED BY MICPRC)
SKIPE T1,LDBMIC(U) ;MIC CONTROLLED?
PUSHJ P,MICPRC ;YES. LET MIC KNOW
POP P,P1 ;RESTORE POSSIBLY UPDATED CHARACTER BITS
> ;END OF IF MIC
PUSHJ P,RIDLN ;YES. DO SO.
JFCL ;DON'T CARE IF ANY WERE ECHOED
MOVSI T1,L2LCCS ;SECOND CONTROL C?
TDNE T1,LDBBY2(U) ; ..
PUSHJ P,CNCCHK ;YES. FORCE CONTROL C IF POSSIBLE
JRST PTYCC1 ;NOT SECOND--GO SET BIT
JRST PTYCC4 ;NO. (JACCT) JUST PASS THE CHARACTER
PUSHJ P,TSETI1 ;YES. CLEAR BUFFERS
PUSHJ P,TSETBO ; ..
JRST CPOPJ1##
PTYCC4: PUSHJ P,TTHALT ;FORCE .HALT COMMAND
PTYCC1: MOVSI T1,L2LCCS ;SET "^C LAST IN" BIT
IORM T1,LDBBY2(U) ;SET BIT FOR NEXT TIME
JRST PTYPT1 ;AND GO STORE CONTROL C IN INPUT BUFFER
;HERE ON ^O TO PTY
FLPCNO: MOVEI T1,LDROSU ;FLIP THE ^O BIT WHEN PTY OR REMOTE
XORM T1,LDBDCH(U) ;SENDS ^O
PUSHJ P,TSETBO ;CLEAR THE OUTPUT BUFFER
PJRST XMTWAK ;WAKE JOB IF IN OUTPUT WAIT
PTYCT: PUSHJ P,DOCTLT
JRST PTYINA
JRST TTFRC1
JRST CPOPJ1##
;SUBROUTINE TO SET DEFAULT TERMINAL CHARACTERSTICS
;CALLING SEQUENCE:
; MOVEI T1,TERMINAL TYPE INDEX
; MOVE U,ADDRESS OF THE LDB
; PUSHJ P,SETTTC
; ALWAYS RETURN HERE
SETTTC::SE1ENT ;ENTER SECTION 1
SETZM LDBATR(U) ;UNKNOWN ATTRIBUTES
SETZM LDBAT2(U) ; ...
SETZM LDBAT3(U) ; ...
DPB T1,LDPTTT ;STORE TERMINAL TYPE
MOVE T2,CTTWDT##(T1) ;GET SIXBIT NAME FOR TYPE
MOVEM T2,LDBTTN(U) ;PRESUME FOR THE MODEL NAME
HLRZ T1,CTATAB##(T1) ;CONVERT TTY INDEX TO CLASS INDEX
LDB T2,TTPWID ;WIDTH
DPB T2,LDPWID ;STORE THAT
LDB T2,TTPLNB ;LENGTH
DPB T2,LDPLNB ;SET TTY LENGTH NN
DPB T2,LDPSTB ;SET TTY STOP NN
MOVSI T3,LPLSBL ;TTY SBELL
CAIE T2,0 ;IF A PAGE SIZE SPECIFIED,
IORM T3,LDBPAG(U) ;THEN SET SBELL
LDB T2,TTPFLC ;FILLER CLASS
DPB T2,LDPFLC ;STORE THAT
LDB T2,TTPFRM ;FORM FEED
DPB T2,LDPFRM ;STORE THAT
LDB T2,TTPTAB ;TABS
DPB T2,LDPTAB ;STORE THAT
LDB T2,TTPLCT ;LOWER CASE
DPB T2,LDPLCT ;STORE THAT
LDB T2,TTPALT ;ALTMODE CONVERSION
DPB T2,LDPALT ;STORE THAT
LDB T2,TTPXNF ;XONOFF
DPB T2,LDPXNF ;STORE THAT
LDB T2,TTPNFC ;NO CRLF
DPB T2,LDPNFC ;STORE THAT
LDB T2,TTPDLV ;DEC LEVEL
DPB T2,LDPDLV ;STORE THAT
LDB T2,TTPALV ;ANSI PART OF DEC LEVEL
DPB T2,LDPALV ;STORE THAT
MOVE T2,CCATAB##(T1) ;GET CLASS ATTRIBUTES
MOVEM T2,LDBATR(U) ;SET THEM
LDB T1,LDPTTT ;GET TYPE INDEX AGAIN
HRRZ T2,CTATAB##(T1) ;GET POINTER TO XOR MASK
SKIPE T2 ;IF PRESENT,
MOVE T2,(T2) ;FETCH MASK
XORM T2,LDBATR(U) ;UPDATE ATTRIBUTES
POPJ P, ;RETURN
TTPWID: POINT 8,CCCTAB##(T1),7
TTPLNB: POINT 8,CCCTAB##(T1),15
TTPFLC: POINT 2,CCCTAB##(T1),17
TTPALV: POINT 4,CCCTAB##(T1),21
TTPDLV: POINT 4,CCCTAB##(T1),25
TTPFRM: POINT 1,CCCTAB##(T1),26
TTPTAB: POINT 1,CCCTAB##(T1),27
TTPLCT: POINT 1,CCCTAB##(T1),28
TTPXNF: POINT 1,CCCTAB##(T1),29
TTPALT: POINT 1,CCCTAB##(T1),30
TTPNFC: POINT 1,CCCTAB##(T1),31
;NET-RELATED LDB MANAGEMENT
IFN FTNET,<
;GETLDB ROUTINE TO SEARCH FOR A FREE DDB/LDB FOR ANF/NRT/LAT/ETC.
;CALL MOVSI T1,LTL??? ;SERVER-TYPE (LTLREM-BITS)
; MOVEI T3,<ADDRESS OF ISR DISPATCH TABLE>
; PUSHJ P,GETLDB
;RETURN CPOPJ ;NO TERMINALS FREE
; CPOPJ1 ;FOUND A FREE LDB/DDB U=LDB
GETLDB::MOVSI T2,LTLUSE ;THE LINE-IN-USE FLAG
SKIPA T4,NETRTY## ;GET THE POINTER TO THE REMOTE LDBS
;LOOP LOOKING FOR A FREE LDB
GETLD0: SCNON ;FREE UP THE INTERLOCK
GETLD1: MOVE U,LINTAB##(T4) ;GET THE LDB POINTER
TDNN T2,LDBTTW(U) ;IS THIS LINE IN USE?
JRST GETLD4 ;NO, TRY TO GRAB IT
AOBJN T4,GETLD1 ;YES, KEEP LOOKING FOR A FREE LINE
POPJ P, ;FAILURE RETURN, NO FREE LDBS
GETLD4: SCNOFF ;NOW IS A GOOD TIME TO INTERLOCK THIS
TDNE T2,LDBTTW(U) ;IS LDB REALLY HONESTLY AND TRULY FREE?
JRST GETLD0 ;NO - FOOLED YOU!
IOR T1,T2 ;MAKE NEW OWNERSHIP FLAGS
MOVSI T2,LTLREM ;ALL FORMS OF POSSIBLE OWNERS
ANDCAM T2,LDBTTW(U) ;CLEAR OUT OLDE OWNERSHIP INFO
IORM T1,LDBTTW(U) ;MARK IN USE BY NEW OWNER
HRRM T3,LDBISR(U) ;NEW DISPATCH TABLE
SCNON ;CLEAR INTERLOCK
SETZM LDBREM(U) ;CLEAR ANF WORDS
SETZM LDBREM+1(U) ;..
SETZM LDBREM+2(U) ;..
SETZM LDBREM+3(U) ;..
SETZM LDBREM+4(U) ;..
IFN FTDECN!FTENET,<SETZM LDBNRT(U)> ;CLEAR NRT/CTERM/LAT WORD
SETZM LDBPBK(U) ;CLEAR THE PIM BREAK SET TOO!
SETZM LDBISB(U) ;CLEAR THE BAUD SPEED AND FLAGS
SETO T1, ;WE CAN RUN ON ANY CPU. USE -1 FOR NOW
DPB T1,LDPCPU ;IN LDB
PUSHJ P,LDBCLR ;CLEAR OUT MOST OF THE REST OF THE LDB
PJRST CPOPJ1## ;SUCCESS RETURN WITH U=LDB
;STILL IFN FTNET
;FRELDB ROUTINE TO RETURN ANF/NRT/LAT/ETC. LDB TO FREE POOL
FRELDB::MOVEI T1,APCUNK ;GET UNKNOWN STATUS CODE
DPB T1,LDPAPC ;SET ASYNC PORT CHARACTERISTICS
MOVSI T1,LTLUSE ;THE LDB-IN-USE FLAG
TDNN T1,LDBTTW(U) ;WAS LDB REALLY IN USE?
STOPCD .+1,DEBUG,LDBNIU;++LDB NOT IN USE
;BEFORE BLASTING THE LDB, MAKE SURE NO ONE ELSE IS TRYING TO USE IT FOR
;ANYTHING - E.G., THAT A LAT TERMINAL IS NOT ANF-SET-HOSTED AWAY
SKIPGE LDBREM(U) ;IS THIS TERMINAL VTM'ED AWAY?
PJRST VTMFRE## ;YES, MUST ALLOW NETVTM TO CLEAN UP FIRST
; (AFTER NETVTM HAS DISCONNECTED IT WILL
; COME BACK TO FRELDB AGAIN)
;LDB HAS NO OUTSTANDING LIENS, MARK IT AS DEFUNCT
ANDCAM T1,LDBTTW(U) ;MARK THE LDB AS FREE NOW
MOVSI T1,NULQUE## ;JUNK QUEUE HEADER
MOVEM T1,LDBQUH(U) ;MAKE SURE NOBODY TRIES TO DO ITS TYPEOUT
POPJ P, ;AND THAT'S THAT
> ;END IFN FTNET
;DETLDB ROUTINE TO DETACH A TERMINAL FROM THE JOB
; (USUALLY CALLED PREPARATORY TO CALLING FRELDB)
;CALL MOVEI U,LDB
; MOVEI T1,ERRORCODE
; PUSHJ P,DETLDB
;RETURN CPOPJ
DETLDB::PUSH P,F ;SAVE F
HRRZ F,LDBDDB(U) ;GET THE DDB
JUMPE F,DETLD3 ;EXIT IF NO DDB
MOVSI T2,DEPRAS ;RESTRICTED ASSIGNMENT BIT
ANDCAM T2,DEVSTA(F) ;MAKE SURE IT'S CLEAR FOR TTYKIL
LDB J,PJOBN## ;GET THE JOB NUMBER
MOVE T2,DEVMOD(F) ;CHARACTERISTICS
TLNE T2,TTYATC ;CONSOLE TERMINAL?
JRST DETLD1 ;YES, DETACH IT
MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL ;ERROR BITS
IORB S,DEVIOS(F) ;LITE THEM FOR THE OWNER OF THIS TERMINAL
DPB T1,PDVESE## ;STORE EXTENDED I/O STATUS CODE
JRST DETLD2 ;DON'T DETACH TERMINAL USED AS AN I/O DEVICE
DETLD1: MOVEI T1,TTFCXD ;NOW FORCE A
PUSHJ P,TTFORC ;.BYE COMMAND
DETLD2: PUSHJ P,PSIDWN## ;SIGNAL DEVICE DOWN
DETLD3: PUSHJ P,TSETBE ;CLEAR OUT INPUT CHUNK STREAM
PUSHJ P,TSETBO ;CLEAR OUT OUTPUT CHUNK STREAM
JRST FPOPJ## ;EXIT
;HERE TO CLEAR OUT CHARACTER AND CHUNK PARAMETERS FOR LDBINI AND VTMLOC
LDBVRS::SCNOFF ;SET INTERLOCK WHILE MUNGING ON THE CHUNKS
PUSHJ P,TYIVRG ;INITIALIZE INPUT CHUNK STREAM
PUSHJ P,TYEVRG ;INITIALIZE ECHO CHUNK STREAM
PUSHJ P,TYOVRG ;INITIALIZE OUTPUT CHUNK STREAM
SCNON ;ALL SET
PUSHJ P,TSETBE ;CLEAR INPUT BUFFER
IFN FTMIC,<SETZM LDBMIC(U)> ;CLEAR MIC WORD
PUSHJ P,CLRCSB ;NO SPECIAL CHARACTER STATUS
SETZM LDBCHM(U) ;CLEAR OUT ANY OLD VALUES
MOVEI T1,21 ;CTRL-Q
DPB T1,LDPUNP ;UNPAUSE CHARACTER
MOVEI T1,33 ;ESCAPE
DPB T1,LDPESC ;THE ESCAPE CHARACTER
MOVEI T1,34_8!15 ;^\^M
DPB LDPSWI ;THE DEFAULT SWITCH SEQUENCE
POPJ P, ;RETURN
;TWO SUBROUTINES TO INITIALIZE THE LDB. LDBCLR SETS UP THE BITS FROM
;INITIAL STATE FOUND IN LINTAB, THEN FALLS INTO LDBINI. LDBINI JUST
;CLEARS AS REQUIRED ON 140 RESTART.
;BOTH SHOULD BE CALLED WITH LINE SET UP.
LDBCLR::SE1ENT ;ENTER SECTION 1
LDB T2,LDPLNO ;GET LINE NUMBER
MOVEI T1,PTYLTB## ;GET PTY 'LINTAB' BITS
CAIG T2,TCONLN## ;IF NOT A PTY,
MOVEI T1,CTYLTB## ;GET CTY 'LINTAB' BITS
CAIGE T2,FRCLIN## ;IF NOT FORCELINE, A CTY, OR A PTY,
MOVEI T1,TTYLTB## ;THEN GET TTY 'LINTAB' BITS
CAIN T2,FRCLIN## ;IF FORCELINE,
SETZ T1, ;SET NO BITS
CAIL T2,M.TLTL## ;IS IT A LOCAL LINE?
JRST LDBCL1 ;NO, DON'T CHECK FOR DATASETS
LSHC T2,-5 ;YES, SPLIT APART WORD & BIT NUMBERS
LSH T3,-^D<36-5> ;RIGHT-JUSTIFY BIT INDEX
MOVE T3,BITTBL##(T3) ;GET ACTUAL BIT
TDNE T3,DSDTAB##(T2) ;IS THIS LINE A DATASET?
TRO T1,TTVDSD## ;YES, TURN ON 'LINTAB' DATASET BIT
LDBCL1: DPB T1,LDPVR2 ;STORE THEM AROUND THE LDB
LSH T1,-5 ; ..
DPB T1,LDPVR1 ; ..
LSH T1,-6 ; ..
DPB T1,LDPFLC ;LAST IS THE FILLER CLASS
MOVSI T1,LTLREM!LTLUSE!LDLFSP ;INITIALLY UNKNOWN TERMINAL TYPE
ANDM T1,LDBTTW(U)
MOVEI T1,APCUNK ;WITH UNKNOWN APC CHARACTERISTICS
DPB T1,LDPAPC ; . . .
SETZM LDBATR(U) ;AND NO KNOWN ATTRIBUTES
LDBINI::SE1ENT ;ENTER SECTION 1
MOVSI T1,LDBCMR+LDBCMK;CLEAR COMMAND REQUEST BITS
ANDCAM T1,LDBCOM(U) ;IN LINE DATA BLOCK
MOVE T1,[LDIBCM]
ANDCAM T1,LDBBYT(U) ;CLEAR MOST BYTES
MOVE T1,LDIDCM ;CLEAR DEVICE CHARACTERISTICS
ANDCAM T1,LDBDCH(U) ; AS APPROPRIATE
MOVSI T1,LDLIDL ;GET THE IDLE BIT
IORM T1,LDBDCH(U) ;WHICH SHOULD NORMALLY BE SET
MOVSI T1,L2LCLR ;CLEAR NECESSARY BITS IN LDBBY2
ANDCAM T1,LDBBY2(U) ; ..
SETZM LDBBY3(U) ;KEEP NOTHING HERE
LDB T3,LDPLNO ;COPY LINE NUMBER
MOVSI T1,LDLCOM ;ASSUME AT COMMAND LEVEL
MOVSI T2,LILCFE!LIL7BT ;BITS TO PRESERVE
ANDM T2,LDBISB(U) ;CLEAR ALL OTHERS
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
CAMN T3,BOOTCT## ;THIS THE CTY
TRO T1,LDRCTY ;YES--SET CTY BIT
CAILE T3,TCONLN## ;ABOVE TCONLN?
TRO T1,LDRPTY ;YES. SET PTY BIT
IORM T1,LDBDCH(U) ;PUT THESE BITS IN THE LDB
MOVE T1,[LPGCLI] ;LDBPAG BITS TO BE CLEARED
ANDCAM T1,LDBPAG(U) ;...
MOVSI T1,LPLXNF ;INITIALIZE TERMINAL TO HANDLE XON/XOFF
IORM T1,LDBPAG(U) ;...
SETZM LDBLSW(U) ;NO IDEA OF TERMINAL LENGTH/STOP PARAMETERS
MOVSI T3,L1LOFL ;OFF LINE BIT
MOVEI T1,ISROFL
PUSHJ P,@LDBISR(U)
IORM T3,LDBOFL(U)
PUSHJ P,LDBVRS ;CLEAR OUT SOME CHUNK AND CHARACTER PARAMETERS
LDB T1,LDPLNO ;GET LINE NUMBER AGAIN
CAIN T1,FRCLIN## ;IF FRCLIN,
SKIPA T2,TTTWDT## ;USE '.FORCE'
MOVE T2,DEFTTT## ;NO--USE DEFAULT TERMINAL TYPE
PUSHJ P,TTUTYP## ;TRY TO SET IT
STOPCD .,STOP,DEFTTI, ;++DEFAULT TTY TYPE INVALID
; PJRST APCSET ;SET THE ASYNC PORT CHARACTERISTICS AND RETURN
SUBTTL SET THE ASYNCHRONOUS PORT CHARACTERISTIC (APC)
; APC CODES
APCUNK==:0 ;UNKNOWN
APCHWD==:1 ;HARDWIRED
APCDSD==:2 ;DATASET LINE
APCTSN==:3 ;TSN
APCGAN==:4 ;GANDALF
APCADL==:5 ;AUTODIALER
APCMCM==:6 ;MICOM
APCNRT==:7 ;DECNET NRTSER LINE
APCLAT==:10 ;LAT-SERVER LINE
APCCTM==:11 ;DECNET CTERM LINE
APCMAX==:11 ;HIGHEST KNOWN APC TYPE
; SET THE APC FOR NON-ANF10/DECNET LINES
APCSET::SE1ENT ;ENTER SECTION 1
LDB T1,LDPAPC ;GET CURRENT APC SETTING
JUMPN T1,CPOPJ## ;RETURN IF ALREADY HAVE APC
MOVEI T1,APCHWD ;ASSUME A HARDWIRED LINE
MOVEI T2,LDRDSD ;DATA SET BIT
TDNE T2,LDBDCH(U) ;SET?
MOVEI T1,APCDSD ;YES
DPB T1,LDPAPC ;STORE APC
POPJ P, ;RETURN
SUBTTL IMPURE DATA
$LOW
ECHCNT: 0 ;CLOCK REQUEST QUEUE COUNTER
TTBASE::0 ;FIRST WORD IN TERMINAL BUFFER SPACE
DSCNUM: BLOCK 2 ;PHONE NUMBER BEING DIALLED, OR LAST DIALLED
.GTSCN::
;SCNSER RESPONSE DATA
%SCNRI::0 ;(0) NUMBER OF CHARS (EXCLUDES MIC) RECEIVED
%SCNXI::0 ;(1) NUMBER OF CHARS (INCLUDES FILL) XMITTED
%SCNEI::0 ;(2) NUMBER OF CHARS ECHOED (SUBSET OF %SCNXI)
TIWRNN::EXP TTIBRK## ;(3) MAX BUFFER SIZE
%SCNAL::0 ;(4) NUMBER OF ACTIVE LINES
RPIMWN::EXP TTPWRN## ;(5) PIM BUFFER SIZE
EXP RECINT ;(6) FOR MONITOR TEST
EXP XMTINT ;(7) PROGRAMS
EXP 0 ;(10) WAS TYPEX
TTFTAK::0 ;(11) FIRST FREE CHUNK
TTFPUT::0 ;(12) LAST FREE CHUNK
RCQHIT: EXP 0 ;(13) TOTAL RECINT CONFLICTS
RQFCNT: EXP 0 ;(14) CHARACTERS LOST DUE TO QUEUE OVERFLOW
TICCNT: EXP 0 ;(15) TIMES WE COULD HAVE DONE TIC STOPCD
SCNMXL==:<<.-.GTSCN-1>B26>
;THE CHARACTER QUEUE FOR RECINT (GLOBAL FOR SYSINI)
RCQCNT::EXP 0 ;COUNT OF CHARACTERS IN QUEUE
RCQPTR::EXP 0 ;QUEUE PUTTER
RCQTKR::EXP 0 ;QUEUE TAKER
RCQBEG::BLOCK RCQMAX ;THE CHARACTER QUEUE
RCQEND: BLOCK 1 ;THE END OF THE CHARACTER QUEUE
IFN FTXMON&FTMP,<
;THE LIST OF FREE EDITOR BLOCKS
EDTBLQ: BLOCK 1
> ;END IFN FTXMON&FTMP
XLIST ;LITERALS UNDER XLIST
$LIT
LIST
SCNEND: END