1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-01 01:19:17 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

11137 lines
388 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE SCNSER - TERMINAL SCANNER SERVICE V1060
SUBTTL R CLEMENTS/RCC/DAL/PMW/EJW/WRS/RCB 28-JUNE-88
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,1060
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
.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
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-06 FREE
;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
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
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,SAVE3## ;SAVE P1-P3
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
TTINI2: MOVE U,LINTAB##(P1) ;SET UP AN LDB
MOVEI T1,(P2) ;GET FORCED COMMAND INDEX
TDNE P3,LDBTTW(U) ;IF ALLOCATED,
PUSHJ P,TTFORC ;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
SKIPE 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,LDBTOT(U) ;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,LDBECT(U) ;GET CHARACTER TO RE-DO
MOVE T1,T3 ;COPY CHARACTER
ANDI T1,CK.CHR ;MASK DOWN
MOVE T1,CHTABL(T1) ;GET BITS
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
CAIE T3,"?" ;IS IT A "?"
CAMN T3,T2 ; OR THE ERROR CHARACTER
CAIA ;YES, HANDLE MIC'S RESPONSE
JRST XMTOK ;NO IGNORE
MOVSI T2,LDLRSY!LDLCHK;SET THE SYNC
IORB T2,LDBMIC(U)
TLNN T2,LDLRSP ;BEEN THIS WAY BEFORE
JRST XMTECH ;YES JUST DO ECHOING
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
SKIPA ;YES TO EITHER
JRST XMTECH ;NO FORGET IT
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 RESPONCE
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: 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: MOVSI T2,LOLREO ;ASSUME FOR OUTPUT
TLNN T1,CHFILO ;WAS IT?
MOVSI T2,LOLREE ;NO, FOR ECHO
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,MMOWN## ;DO WE HAVE THE MM?
PUSHJ P,INTLVL## ;NO, CAN WE AFFORT TO WAIT FOR IT?
JRST SCNED0 ;GGVMM IS OK, SKIP FUNNY BUSINESS
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 ;SETTING, 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 ;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: MOVEI T1,LDROSU ;CLEAR CONTROL O BIT
ANDCAM T1,LDBDCH(U) ;SO DATA WILL BE SEEN
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: MOVEI T1,LDRPTY ;A PTY?
TDNE T1,LDBDCH(U)
PUSHJ P,PTYOW## ;YES, TELL BATCON
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
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
SETZB T1,LDBMIC(U) ;CLEAR DOWN LDBMIC
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)
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?
TLO T2,LDLCHK!LDLERC;YES - SET ITS FLAGS
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
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
MOVE T1,JBTSTS##(T1) ;GET JOB STATUS WORD
TRNN T1,JDC ;DCORE COMMAND WAITING?
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