Trailing-Edge
-
PDP-10 Archives
-
tops10_704_monitoranf_bb-x140c-sb
-
10,7/mon/nrtser.mac
There are 3 other files named nrtser.mac in the archive. Click here to see a list.
TITLE NRTSER - DECnet Network Remote Terminal Service V066
SUBTTL W. G. Nichols/WGN/RCB, 7 JUL 87
SALL
SEARCH D36PAR,SCPAR,NETPRM,F,S,MACSYM
D36SYM ;Fix problems with MACSYM in DECnet-36
$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 1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1982,1988>
VNRTSER==:066
NRTOBJ==^D23 ;NRTSRV OBJECT TYPE
CTHOBJ==^D42 ;CTERM HOST OBJECT
CTSOBJ==^D24 ;CTERM SERVER OBJECT
NRTINT==3 ;JIFFIES BETWEEN NRT SERVICE CHECKS
; The length of the record and the max record we will send are separately
; defined so that the compiled-in record buffer can be larger than the
; actual record we send so that we can poke the max to a larger value for
; performance tests to systems we know can handle the size.
NRTROL==^D500 ;BYTES IN OUTPUT NRT RECORD
NRTMXC==^D500 ;MAX LENGTH OF RECORD WE WILL SEND
NRTRIL==^D90 ;BYTES IN INPUT NRT RECORD
CTHMSZ==^D139 ;MINIMUM ACCEPTABLE SEGMENT SIZE ON CTERM LINK
IFG NRTMXC-NRTROL,NRTMXC==NRTROL ;ASSURE WE DON'T GET CARRIED AWAY
SUBTTL Table of contents
; TABLE OF CONTENTS FOR NRTSER
;
;
; SECTION PAGE
; 1. Table of contents......................................... 3
; 2. Definitions
; 2.1 External References............................... 4
; 3. Register & Macro Definitions.............................. 5
; 4. CTERM Protocol Definitions................................ 6
; 5. NRT Data Base Definitions................................. 21
; 6. Impure Storage............................................ 22
; 7. LDBISR Dispatch Table..................................... 23
; 8. NRTINI - Initialization................................... 24
; 9. NRTSTO - Called every Jiffy via .CPSTO.................... 25
; 10. NRTSEC - Called every second via .CPSTO................... 26
; 11. NJFRxx - Routines to handle each DECnet link state........ 27
; 12. Subroutines
; 12.1 NRTNSF - Call SCLINK's SCTNSF..................... 83
; 12.2 NRTREL - Release a Link........................... 84
; 12.3 NGTLDB - Get an LDB for NRTSER.................... 85
; 12.4 NGVLDB - Give an LDB back to ANF.................. 86
; 12.5 NRTWAK - Subroutine to do the WAKEs............... 87
; 12.6 NRTHBR - Subroutine to do the HIBERs.............. 88
; 13. Subroutine
; 13.1 NRTLFC - Get a NRT Line number from channel....... 89
; 14. NRTGWD - Get Some Words................................... 90
; 15. NRTFWD - Free Some Words.................................. 91
; 16. End of Program............................................ 92
COMMENT @
Theory of Operation
Except for NRTINI, called by SYSINI, NRTSER runs only at clock level,
and then only on one CPU, so it needs little more interlocking.
Every jiffy, NRTSTO gets called along with all the other queued
drivers in the system via a call in CLOCK1 through .CPSTO. NRTSTO
checks that it is on the boot CPU and then counts down an interval
timer. The timer is reinitialized to some small number, say 3, every
time it expires.
NRTSTO only runs after its interval counter expires for two reasons:
it imposes less overhead if it runs less often, and it lets more input
& output build up and thus fills the DECnet messages better than it
would if it ran more frequently. It is important that it run often
enough that the user not see any delay, the optimum setting seems to
be around 3 to 5 jiffies.
When the interval timer expires, NRTSTO checks two queues for service
requests:
1) NRTSTO calls TOTAKE to dequeue any LDBs which may have output
pending. NRTSTO loops over these LDBs, calling NRTLKS
(NRT Link Service) on each. If an LDB has output available
and the associated DECnet link cannot take any output, NRTLKS
just forgets about it: it will get a DECnet 'interrupt' from
that link when output is again OK.
2) NRTSTO then calls SCTPSQ to see if there has been any DECnet
activity. This activity could be: a) input available, b)
output newly OK on this link, or c) the link has changed
state.
@
SUBTTL Definitions -- External References
;ENTRY declarations for LINK
ENTRY NRTSTO ;CALLED VIA .CPSTO EVERY JIFFY
;These are the external references to the D36COM library of routines.
EXT DNSWDS ;SMEAR SOME WORDS
;Here are the references to SCLINK.
EXT SCTNSF ;NSP. FUNCTION PROCESSING (Section 1)
EXT MAKSJB ;MAKE AN SJB
EXT SCTWKQ ;ENQUEUE THIS SLB FOR SCTPSQ CALL
EXT SCTPSQ ;DEQUEUE NEXT SLB FOR PSI INTERRUPT
;Here are some external references to TOPS-10 things.
EXT CPOPJ ;RETURN
EXT CPOPJ1 ;SKIP RETURN
SUBTTL Register & Macro Definitions
;NRTSER uses standard TOPS-10 register definitions with the exception
;that R is redefined as CX, the super-temp for macros.
;
;The register defintions from D36PAR are ignored herein.
CX==R ;SUPER-TEMP AC FOR MACROS
.SAC==CX ;SOME USE THIS NAME INSTEAD
;Register Conventions in NRTSER
;
; M usually points to an SAB, SCLINK arg block
; W usually points to a NRB, NRT data block
SUBTTL CTERM Protocol Definitions
;Define a helper macro for making masks out of network bits
DEFINE NETBIT(FIRST,LAST),<<B'LAST!<B'LAST-B'FIRST>>>
;The values B0-B15 are defined in NETPRM, and are the 16-bit network
; bit and byte-order equivalents of our <n>Bm notation's "m" offsets.
BYTMSK==NETBIT(0,7) ;A NETWORK BYTE
WRDMSK==NETBIT(0,15) ;A NETWORK WORD
SGNBIT==B15 ;THE SIGN BIT OF A NETWORK WORD
;Define the Foundation message types
.FMILL==0 ;ILLEGAL MESSAGE TYPE
.FMBND==1 ;BIND-REQUEST
.FMUNB==2 ;UNBIND
.FMREB==3 ;RE-BIND (*ILLEGAL*)
.FMBAC==4 ;BIND-ACCEPT
.FMENM==5 ;ENTER-MODE
.FMEXM==6 ;EXIT-MODE
.FMCFM==7 ;CONFIRM-MODE
.FMNOM==10 ;NO-MODE
.FMCMD==11 ;COMMON DATA (CTERM MESSAGES)
.FMMDD==12 ;MODE DATA
;Define the O/S types for a Bind message
O.UNSP==0 ;UNSPECIFIED
O.RT11==1 ;RT-11
O.RSTS==2 ;RSTS/E
O.RSXS==3 ;RSX-11S
O.RSXM==4 ;RSX-11M
O.RSXD==5 ;RSX-11D
O.IAS==6 ;IAS
O.VMS==7 ;VAX/VMS
O.T20==10 ;TOPS-20
O.T10==11 ;TOPS-10
O.OS8==12 ;OS-8
O.RTS8==13 ;RTS-8
O.RSXP==14 ;RSX-11M+
;Define the valid Protocol types for a Bind-Request message
PT%RST==B0 ;RSTS/E HOMOGENEOUS NETWORK TERMINALS
PT%RSX==B1 ;RSX-11 HOMOGENEOUS NETWORK TERMINALS
PT%VMS==B2 ;VMS HOMOGENEOUS NETWORK TERMINALS
PT%PIM==B3 ;PIM (TOPS-10/TOPS-20) HOMOGENEOUS TERMINALS
PT%CTM==B4 ;CTERM HETEROGENEOUS TERMINALS
;Define the valid Options flags for a Bind-Request message
OP%HIA==B0 ;HIGH-AVAILABILITY SYSTEM
;Define the valid parameters for a CTERM Protocol Initiate message
.PIILL==0 ;ILLEGAL PROTOCOL PARAMETER
.PIMMS==1 ;MAXIMUM ACCEPTABLE MESSAGE SIZE
.PIIBS==2 ;MAXIMUM ACCEPTABLE INPUT BUFFER SIZE
.PISUP==3 ;PROTOCOL MESSAGES SUPPORTED BIT MASK
;Define the various minimum acceptable parameter values
MT.SUP==NETBIT(1,14) ;MUST SUPPORT MESSAGES ^D1-^D14
HSTMMS==^D90 ;HOSTS MUST BE ABLE TO ACCEPT 90-BYTE MESSAGES
SRVMMS==^D139 ;REQUIRED MESSAGE SIZE ACCEPTABLE BY SERVERS
MINIBS==^D80 ;SERVERS MUST ALLOW AN 80-CHAR INPUT BUFFER
IFL NRTRIL-HSTMMS,<NRTRIL==HSTMMS
PRINXT % NRTRIL EXPANDED TO HSTMMS>
;Define the Unbind reasons
.UBILL==0 ;ILLEGAL UNBIND REASON
.UBICV==1 ;INCOMPATIBLE VERSIONS OF THE PROTOCOL(S)
.UBNPA==2 ;NO PORTAL AVAILABLE
.UBUUR==3 ;USER UNBIND REQUEST
.UBDSC==4 ;TERMINAL DISCONNECTED
.UBTIU==5 ;REQUESTED LOGICAL TERMINAL IN USE
.UBNST==6 ;NO SUCH TERMINAL
.UBPED==7 ;PROTOCOL ERROR DETECTED
;Define the CTERM message types
.CMILL==0 ;ILLEGAL MESSAGE TYPE
.CMPIN==1 ;CTERM PROTOCOL INITIATE
.CMSRD==2 ;START-READ
.CMRDD==3 ;READ DATA
.CMOOB==4 ;OUT-OF-BAND CHARACTER
.CMUNR==5 ;UNREAD
.CMCTA==6 ;CLEAR ALL TYPEAHEAD
.CMWRT==7 ;WRITE
.CMWRC==10 ;WRITE COMPLETE
.CMDOS==11 ;DISCARD-OUTPUT STATE
.CMRCH==12 ;READ CHARACTERISTICS
.CMCHR==13 ;CHARACTERISTICS (WRITE/RESPOND)
.CMCHK==14 ;CHECK INPUT COUNT
.CMICT==15 ;INPUT COUNT
.CMIST==16 ;INPUT STATE
;Define the CTERM characteristics that can be set and read via the
;CHARACTERISTICS messages.
;First, the types of characteristics:
.CTCFP==0 ;FOUNDATION PHYSICAL
.CTCFL==1 ;FOUNDATION LOGICAL
.CTCMH==2 ;CTERM MODE HANDLER
;Also define the various format types used for the characteristics
.FTASD==0 ;ASCIC FORMAT
.FTBYT==1 ;SINGLE-BYTE CHARACTERISTIC
.FTINT==2 ;DOUBLE-BYTE CHARACTERISTIC
.FTCCA==3 ;COMPOUND: CHARACTER ATTRIBUTES
SYN .FTBYT,.FTBOL ;BOOLEANS ARE BYTES
SYN .FTINT,.FT2BY ;2-BYTE MASKS ARE DOUBLE-BYTES
;Define a macro to make it easy to define characteristics and their associated
;formats. Defines .CCnam and FT.nam for each invocation.
DEFINE X(NAM,FMT),<
IF1,<IFDEF .CC'NAM,<PRINTX ? DUPLICATE CHARACTERISTIC .CC'NAM>>
FT.'NAM==.FT'FMT
.CC'NAM==<XX==XX+1>>
;Note that characteristic zero is illegal for each of the three types
XX==.CTCFP_8 ;START DEFINING THE PHYSICAL CHARACTERISTICS
X RSP,INT ;RECEIVE SPEED
X TSP,INT ;TRANSMIT SPEED
X CSZ,INT ;CHARACTER SIZE
X CPE,BOL ;CHARACTER PARITY ENABLED
X CPT,INT ;CHARACTER PARITY TYPE
PAR.EV==1 ;EVEN PARITY
PAR.OD==2 ;ODD PARITY
PAR.SP==3 ;SPACE PARITY
PAR.MK==4 ;MARK PARITY
X MSP,BOL ;MODEM SIGNALS PRESENT (DATASET)
X ABR,BOL ;AUTO-BAUD RECOGNITION
X EMG,BOL ;ENTER-MANAGEMENT GUARANTEED
X SW1,ASD ;SWITCH-CHARACTER 1
X SW2,ASD ;SWITCH-CHARACTER 2
X 8BC,BOL ;8-BIT CHARACTER-SET TERMINAL
X EME,BOL ;ENTER-MANAGEMENT ENABLED
.CMXFP==XX ;MAXIMUM FOR FOUNDATION PHYSICAL
XX==.CTCFL_8 ;START DEFINING THE LOGICAL CHARACTERISTICS
X MWA,BOL ;MODE WRITING ALLOWED
X TAM,2BY ;TERMINAL ATTRIBUTES MASK
TA%KNO==B0 ;TYPE IS KNOWN TO SENDER'S SYSTEM
TA%DIS==B1 ;DISPLAY TERMINAL
X TTN,ASD ;TERMINAL TYPE NAME
X OFC,BOL ;OUTPUT FLOW CONTROL (TTY XONOFF)
X OPS,BOL ;OUTPUT PAGE STOP (TTY STOP)
X FCP,BOL ;FLOW-CHARACTER PASSTHROUGH
X IFC,BOL ;INPUT FLOW CONTROL
X LNE,BOL ;LOSS NOTIFICATION ENABLED
X WID,INT ;CARRIAGE WIDTH
X LEN,INT ;FORMS LENGTH
X SSZ,INT ;STOP SIZE
X CRF,INT ;C-R FILL
X LFF,INT ;L-F FILL
X WRP,INT ;WRAP HANDLING
WP.NON==1 ;NO WRAPPING AT ALL
WP.TRC==2 ;TRUNCATE AT RIGHT MARGIN
WP.PHY==3 ;HARDWARE IS WRAPPING AND WE'RE TRACKING IT
WP.SFT==4 ;FULL SOFTWARE WRAPPING
X HTM,INT ;HORIZONTAL TAB MODELING
HT.PHY==1 ;PHYSICAL TABS
HT.SIM==2 ;SOFTWARE-SIMULATED TABS
X VTM,INT ;VERTICAL TAB MODELING
VT.PHY==1 ;HARDWARE VT
VT.SIM==2 ;SOFTWARE SIMULATION OF VT
VT.MAP==3 ;TURN INTO FF AND HANDLE AS PER .CCFFM
X FFM,INT ;FORM FEED MODELING
FF.PHY==1 ;HARDWARE FF
FF.SIM==2 ;SOFTWARE-SIMULATED FF
.CMXFL==XX ;MAXIMUM FOR FOUNDATION LOGICAL
XX==.CTCMH_8 ;BEGIN MODE-HANDLER CHARACTERISTICS
X IGN,BOL ;IGNORE INPUT
X CAT,CCA ;CHARACTER ATTRIBUTES
X COP,BOL ;CONTROL-O PASSTHROUGH
X RAI,BOL ;RAISE INPUT
X ECH,BOL ;NORMAL ECHO
X IER,BOL ;INPUT ESCAPE-SEQUENCE RECOGNITION
X OER,BOL ;OUTPUT ESCAPE-SEQUENCE RECOGNITION
X CNT,INT ;INPUT-COUNT MESSAGE STATE
CN.NON==1 ;NEVER SEND INPUT-STATE MESSAGES
CN.NRD==2 ;SEND INPUT-STATE ONLY IF NO READ OUTSTANDING
CN.ALL==3 ;ALWAYS SEND INPUT-STATE MESSAGES
X APE,BOL ;AUTO-PROMPT ENABLED
X EPM,BYT ;ERROR-PROCESSING MASK
EP%LBK==B0 ;LINE BREAK PROCESSING
EP%FRM==B1 ;FRAMING ERROR PROCESSING
EP%PAR==B2 ;PARITY ERROR PROCESSING
EP%OVR==B3 ;RECEIVER OVERRUN PROCESSING
.CMXMH==XX ;MAXIMUM FOR CTERM MODE HANDLER
;Define the flag bits that form the MASK and BITS fields of .CCCAT
CA.OOB==B0!B1 ;OUT-OF-BAND TYPE
.OBNOT==0 ;NOT O-O-B AT ALL
.OBCLR==1 ;IMMEDIATE CLEAR
.OBDFR==2 ;DEFERRED CLEAR
.OBHEL==3 ;IMMEDIATE HELLO
CA.INC==B2 ;INCLUDE FLAG FOR .OBHEL
CA.SDO==B3 ;SETS DISCARD-OUTPUT IF ON & OOB
CA.ECH==B4!B5 ;ECHO FORM (FOR CONTROL CHARACTERS)
CA.SLF==B4 ;ECHO AS SELF
CA.STD==B5 ;ECHO IN STANDARD FORM
;(CA.STD HAPPENS BEFORE CA.SLF)
CA.ENB==B6 ;ENABLE ANY SPECIAL FUNCTIONS IT MIGHT HAVE
CA.MSK==CA.ENB!CA.ECH!CA.SDO!CA.INC!CA.OOB ;SETTABLE BITS
;Define the flags field for a start-read message
SR.UND==B0!B1 ;UNDERFLOW HANDLING
.SRIGN==0 ;IGNORE UNDERFLOW
.SRBEL==1 ;RING BELL ON UNDERFLOW
.SRTRM==2 ;TERMINATE ON UNDERFLOW
SR.CTA==B2 ;CLEAR-TYPEAHEAD IF ON
SR.FMT==B3 ;DO FANCY CR/LF FORMATTING IF ON
SR.VPT==B4 ;TERMINATE ON VERTICAL POSITION CHANGE
SR.CON==B5 ;THIS IS A CONTINUATION READ
SR.RAI==B6!B7 ;RAISE-INPUT HANDLING
.SRUNS==0 ;UNSPECIFIED, USE CHARACTERISTIC
.SRSLC==1 ;SINGLE-READ ALLOW LOWER CASE
.SRSUC==2 ;SINGLE-READ FORCE UPPER CASE
SR.CCD==B8!B9!B10 ;CONTROL-CHARACTER DISABLE FIELD
.SRNON==0 ;NONE ARE DISABLED
.SRLIN==1 ;THE LINE CHARACTERS (^R & ^U) ARE DISABLED
.SREDI==2 ;THE EDITING CHARACTERS ARE DISABLED
.SRALL==3 ;ALL BUT XON/XOFF ARE DISABLED
SR.NEC==B11 ;NO-ECHO FOR THIS READ DESPITE CHARACTERISTIC
SR.ECT==B12 ;ECHO TERMINATORS
SR.TMR==B13 ;TIMER FIELD IS SPECIFIED
SR.TRM==B14!B15 ;TERMINATOR MASK SPECIFICATION
.SRUPT==0 ;USE PREVIOUSLY SPECIFIED MASK
.SRUNT==1 ;USE NEW TERMINATOR MASK (SUPPLIED)
.SRUUT==2 ;USE THE 'UNIVERSAL' TERMINATOR MASK
;(SECOND WORD--REALLY ONLY THIRD BYTE)
S2.IER==B0!B1 ;INPUT ESCAPE-SEQUENCE RECOGNITION
.SRUNS==0 ;UNSPECIFIED, USE CHARACTERISTIC
.SRSIE==1 ;SINGLE-READ IGNORE ESCAPES
.SRSRE==2 ;SINGLE-READ RECOGNIZE ESCAPES
;Define the flags that come with a Read-Data message
RD.TRM==NETBIT(0,3) ;TERMINATION REASON CODE
.RDTRM==0 ;TERMINATOR CHARACTER SEEN
.RDVES==1 ;VALID ESCAPE SEQUENCE
.RDIES==2 ;INVALID ESCAPE SEQUENCE
.RDOOB==3 ;OUT-OF-BAND CHARACTER
.RDIBF==4 ;INPUT BUFFER FULL
.RDTMO==5 ;TIMED-OUT
.RDUNR==6 ;UNREAD RECEIVED
.RDUND==7 ;DELETION UNDERFLOW
.RDTOK==10 ;ABSENTEE TOKEN
.RDVPC==11 ;VERTICAL POSITION CHANGE
.RDLBK==12 ;LINE BREAK ERROR
.RDFRM==13 ;FRAMING ERROR
.RDPAR==14 ;PARITY ERROR
.RDOVR==15 ;RECEIVER OVERRUN
RD.IIP==B4 ;INPUT IS PRESENT (INPUT-STATE PIGGYBACK)
;Define the bits that can be sent with a Write message
WR.LOK==B0!B1 ;THE LOCK/UNLOCK FIELD
.WRULK==0 ;UNLOCK AT START
.WRLOK==1 ;LOCK & LEAVE LOCKED
.WRLTU==2 ;LOCK AT START THEN UNLOCK AT END
.WRLUR==3 ;.WRLTU FOLLOWED BY REDISPLAY OF INPUT
WR.FMT==B2 ;DO FANCY CR/LF FORMATTING IF ON
WR.CDS==B3 ;CLEAR DISCARD STATE
WR.BOM==B4 ;THIS IS FIRST PART OF WRITE MESSAGE
WR.EOM==B5 ;THIS IS LOGICAL END OF WRITE MESSAGE
WR.PRE==B6!B7 ;PREFIX CHARACTER HANDLING
.WRIGN==0 ;IGNORE THE FIELD
.WRNLC==1 ;FIELD IS NEW-LINE COUNT
.WRCHR==2 ;FIELD IS A CHARACTER
WR.PST==B8!B9 ;POSTFIX CHARACTER HANDLING
;USES SAME VALUES AS WR.PRE
WR.VFY==B10 ;VERIFY BY SENDING A WRITE-COMPLETE WHEN DONE
WR.BIN==B11 ;BINARY (TRANSPARENT) WRITE OF CHARACTERS
;Define the flags that come with a Discard-State message
DS.CDS==B0 ;CLEAR DISCARD STATE IF ON, SET IF OFF
;Define the flags that come with an input state message
IS.IIP==B0 ;INPUT IS NEWLY PRESENT IF ON, ABSENT IF OFF
;Define the flags that come with an Out-of-Band message
OB.DIS==B0 ;SET DISCARD-OUTPUT STATE TRUE
;Define the flag bits that can be sent with an Unread message
UR.OIE==B0 ;WHEN LIT, ONLY CANCEL THE READ IF THERE ARE NO
; CHARACTERS AVAILABLE (AT ALL)
;Helper macro to build byte strings to send over the network
DEFINE BYTSTR (PFX,BYTES),<
IFNB<BYTES>,<
IFDEF PFX'S,<CONCAT PFX'S,<,>>
IFNDEF PFX'S,<
CCLEAR PFX'S
CONCAT PFX'S,<BYTE (8)>
PFX'LEN==0
>
CONCAT PFX'S,<BYTES>
IRP BYTES,<PFX'LEN==PFX'LEN+1>
>
IFB<BYTES>,<
PFX'S
PURGE PFX'S
>>;END DEFINE BYTSTR
;Define macros to build the Characteristics messages
FORX. <CSC,PIM,IMI>,PFX,<
DEFINE PFX(NAM,VAL),<
BYTSTR(PFX,<.CC'NAM,.CC'NAM/B8>)
IFE FT.'NAM-.FTBYT,< BYTSTR(PFX,<VAL>) >
IFE FT.'NAM-.FTINT,< BYTSTR(PFX,<<VAL>,<VAL>/B8>) >
IFE FT.'NAM-.FTCCA,< BYTSTR(PFX,<<VAL>/B8,CA.MSK,<VAL>>) >
IFE FT.'NAM-.FTASD,<
..'PFX==0
IRPC VAL,<..'PFX==..'PFX+1>
BYTSTR (PFX,\..'PFX)
IRPC VAL,< IFIDN<VAL><">,< BYTSTR(PFX,"""") >
IFDIF<VAL><">,< BYTSTR(PFX,"VAL") >
>
>
> ;END DEFINE PFX
> ;END OF FORX.
;Define macro to build the Parameters portion of our Protocol Initiate message
DEFINE CPI(NAM,VAL),<
BYTSTR(CPI,.PI'NAM)
...CPI==<VAL>
..CPI==0
REPEAT 5,<;;VALUE MUST FIT IN A WORD, AFTER ALL
IFN ...CPI,<
..CPI==..CPI+1
...CPI==...CPI_-8>
>
BYTSTR(CPI,\..CPI)
...CPI==<VAL>
REPEAT ..CPI,<
BYTSTR(CPI,\...CPI)
...CPI==...CPI_-8
>
> ;END DEFINE CPI
;Define macro to send selector sequence for our Read Characteristics message
DEFINE RSC(NAM,CHR),<
BYTSTR(RSC,<.CC'NAM,.CC'NAM/B8>)
IFE FT.'NAM-.FTCCA,< BYTSTR(RSC,CHR) >
> ;END DEFINE RSC
SUBTTL NRT Data Base Definitions
;The NRB is the NRT Data Block. One is allocated for each active
;link to hold data associating the DECnet link with an LDB.
DEFINE CMNBLK<
WORD LDB ;PTR TO ASSOCIATED LDB
HWORD CHN ;DECnet CHANNEL NUMBER
HWORD STS ;CURRENT STATUS OF DECnet LINK
HWORD SIZ ;MAX CHARS IN A SEGMENT ON THIS LINK
FIELD FLG,18 ;FLAGS
BIT CFG ;SET IF CONFIG MSG HAS BEEN SENT
BIT REL ;THIS NRB IS BEING RELEASED
BIT CTM ;SET IF THIS IS A CTB, NOT A NRB
BIT RLS ;WANT UNBIND SENT (DISCONNECTING)
BIT XOF ;SCNSER REQUESTED NO DRQ'S FOR A WHILE
>
BEGSTR NR ;USUALLY INDEXED BY W
CMNBLK ;STANDARD PART OF BLOCK ONLY
;FIELD FLG,18 ;WHERE WE ARE (5 BITS IN)
;NRT-SPECIFIC ITEMS FROM HERE ON
BIT TMO ;CONNECT TIMED OUT BY SCNSER
ENDSTR
BEGSTR CT
CMNBLK ;INCLUDE STANDARD PORTION OF BLOCK
;FIELD FLG,18 ;WHERE WE ARE (5 BITS IN)
;CTERM-SPECIFIC ITEMS FROM HERE ON
BIT BND ;BIND-ACCEPT RECEIVED (FOUNDATION RUNNING)
BIT SPI ;SENT PROTOCOL INIT (CTERM LEVEL)
BIT RPI ;RECEIVED PROTOCOL INIT (CTERM RUNNING)
BIT RCS ;READ CHARACTERISTICS SENT
BIT CHP ;NEED TO SEND CHARACTERISTICS MSG
BIT CSD ;CHARACTERISTICS SEQUENCE DONE (LINK IS READY)
BIT DRQ ;DATA REQUEST OUTSTANDING (START-READ MSG)
BIT ECH ;THIS DRQ IS ECHOING
BIT OBC ;OUT-OF-BAND CHANGE (RE-CALC BREAK MASK)
BIT BMC ;BREAK MASK CHANGE
BIT CTG ;CHARACTER TO GO (CTCHO IS VALID)
BIT URA ;UNREAD ACTIVE (FOR CTHDRQ)
BIT DRZ ;LAST DATA REQUEST WAS OF ZERO EFFECT
WORD IFM,4 ;16. BYTES OF INPUT FOUNDATION MESSAGE STORAGE
WORD MW1 ;A WORD FOR MESSAGE PROCESSORS
WORD IML ;LENGTH OF COMMON DATA STRING IN PROGRESS
WORD IFL ;BUFFER COUNTDOWN FOR RE-READING CTIFM
FIELD FLM,18 ;CTERM MODE FLAGS
BIT RUN ;CTERM IS RUNNING ON THIS LINK
BIT MI0 ;THE MODE PROCESSOR HAS ALREADY BEEN INITIALIZED
BIT MI1 ;THE MESSAGE HANDLER HAS SKIPPED ITS FILLER
BIT CIB ;NEED TO CLEAR THE INPUT BUFFER
BIT DRI ;DATA REQUEST INVALID (CAME AFTER IRRCIB)
BIT BAD ;KNOWN BAD PROTOCOL (VMS)
FIELD CHO,9 ;CHARACTER TO OUTPUT (WHEN CHANGING IMAGE STATE)
FIELD IFT,8 ;INPUT FOUNDATION TYPE (MESSAGE IN PROGRESS)
FIELD IMT,8 ;INPUT CTERM MODE TYPE (MESSAGE IN PROGRESS)
FIELD MIJ,8 ;'JUNK' MESSAGE BYTES THAT NEED TO BE SKIPPED
FIELD MB1,8 ;FIRST RANDOM BYTE FOR SUB-MESSAGE PROCESSING
FIELD IBS,8 ;MAXIMUM INPUT BUFFER SIZE REMOTE CAN HANDLE
FIELD UBR,4 ;UNBIND REASON
FIELD RLN,18 ;REMOTE'S LINE NUMBER
FIELD ROS,18 ;REMOTE'S O/S TYPE
ENDSTR
BEGSTR CH,CT.LST ;LAST CHARACTERISTICS SENT TO REMOTE
WORD BKM,8 ;LAST BREAK MASK SENT
FIELD WID,8 ;TTY WIDTH
FIELD LNB,8 ;TTY LENGTH
FIELD TTT,8 ;TTY TYPE INDEX
FIELD FLG,12 ;SINGLE-BIT VALUES
BIT LCT ;RAISE INPUT
BIT ECH ;NO ECHO
BIT DIS ;DISPLAY
BIT XNF ;XON/XOFF
BIT 8BT ;EIGHT-BIT TERMINAL
BIT IMI ;IMAGE I/O MODE
BIT PIM ;PACKED IMAGE MODE
ENDSTR
CT.LEN==CH.LST ;EACH CTB NEEDS TO INCLUDE A CH BLOCK
SUBTTL Impure Storage
$LOW ;IMPURE STUFF
NRTDFT::EXP <FLD(^D9,PDGOL) ! FLD(^D16,PDDQT) ! FLD(^D50,PDIPR)>
NRTINL: EXP NRTINT ;NUMBER OF JIFFIES BETWEEN NRT SERVICES
NRTINC: BLOCK 1 ;NRT INTERVAL COUNTER, SEE NRTSTO
NRTINA: EXP M.NIDL## ;AUTO-DISCONNECT TIMER VALUE (POKABLE)
NRTMAX::EXP NRTMXC ;MAX SIZED RECORD WE'LL SEND (POKABLE)
NRTRTQ: BLOCK 2 ;QUEUE HEADER FOR LDBQUE
NRTPSQ: BLOCK 1 ;NON-ZERO IF DECnet NEEDS SERVICE
NRTCWL::BLOCK 1 ;NUMBER OF NRT LINKS IN CW STATE
CTHCWL::BLOCK 1 ;NUMBER OF CTERM LINKS IN CW STATE
NRTCHP::BLOCK 1 ;POINTER TO NRT CHANNEL TABLE
NRTCHL: BLOCK 1 ; AND ITS LENGTH (WORDS)
NRTSJP::BLOCK 1 ;PTR TO NRT'S SJB (ACCESS FROM SEC 1)
NRTSAP: BLOCK 1 ;PTR TO NRT'S SAB (SEC 0/1 ADDR)
NRTBLW: BLOCK 1 ;SAVED NRB PTR FOR BLOCKED LINK
NRTBLP: BLOCK 2 ;SAVED BYTE PTR " " "
NRTBLC: BLOCK 1 ;SAVED BYTE COUNT " " "
NRTRCO: BLOCK <<NRTROL+3>/4> ;PLACE TO BUILD OUTPUT RECORD
NRTRCI: BLOCK <<NRTRIL+3>/4> ;PLACE TO BUILD INPUT RECORD
CTHIFP: BLOCK 1 ;INPUT POINTER FOR FOUNDATION BUFFERS
CTHCDP: BLOCK 1 ;OUTPUT POINTER FOR COMMON DATA MESSAGES
CTHCDL: BLOCK 1 ;WORD USED TO FIND LENGTH OF CTERM OUTPUT DATA
CTH6BW: BLOCK 1 ;WORD USED TO ACCUMULATE SIXBIT
CTHBUL: BLOCK 1 ;WORD USED TO BYPASS USELESS MESSAGES
$HIGH
SUBTTL LDBISR Dispatch Table
NRTDSP::JRST CPOPJ## ;( 0)ILLEGAL NOW. DON'T USE!!
JRST CPOPJ## ;( 1)MODEM CONTROL
JRST NRTSEC ;( 2)ONCE A SECOND CALL (NOT PER TTY)
JRST CPOPJ## ;( 3)INITIALIZE
JRST CTHCHP ;( 4)CHANGE HARDWARE PARMS
JRST CPOPJ## ;( 5)LINE PARM CONTROL
JRST CPOPJ## ;( 6)SET TERMINAL ELEMENT
JRST NRTREM ;( 7)STUFF FOR REMOTE TERMINALS
JRST CPOPJ1## ;(10)IS LINE DEFINED ON STATION (YES)
CTHCHP==SETCHP## ;LET SCNSER DO IT
NRTREM: SKIPN T1,LDBNRT##(U) ;IS THIS LINE CONTROLLED BY NRTSER?
RET ;NO, FORGET IT
CAILE T3,IRRINV ;MAKE SURE THE ISRREM SUB-CODE IS IN RANGE
CAILE T3,IRROOB ;DO WE UNDERSTAND IT?
RET ;NO, IGNORE IT
PUSHJ P,SAVR## ;PRESERVE FOR TOP-LEVEL CALLERS
TMNE NRCTM,(T1) ;YES, BUT IS IT RUNNING CTERM PROTOCOL?
JRST CTHREM ;YES, CTERM HANDLES MORE OF THESE REQUESTS
PJRST @.(T3) ;NO, NRT, DISPATCH FOR IT
IFIW CTHCSL ;(1) CHUNK SPACE LOW
IFIW CPOPJ ;(2) CHARACTER NOT STORED (RECHLT)
IFIW CPOPJ ;(3) OUTPUT SUPPRESSION CHANGE (DON'T CARE)
IFIW CTHCSA ;(4) CHUNK SPACE AVAILABLE
IFIW NRTRM1 ;(5) DISCONNECT (TRMOP. .TODNT)
IFIW CPOPJ ;(6) CLEAR INPUT BUFFER (CLRBFI) (CAN'T DO)
IFIW NRTRM1 ;(7) DISCONNECT TIMEOUT
IFIW CPOPJ ;(10) BREAK MASK CHANGED
IFIW CPOPJ ;(11) OOB SET CHANGED
NRTRM1: MOVX R,NRRLS ;GET RELEASE BIT
CAIN T3,IRRTMO ;WAS THIS A TIMEOUT?
TXO R,NRTMO ;YES, FLAG THAT ALSO
IORM R,NR.FLG(T1) ;SET OUR FLAGS FOR NRTLKS
PJRST TOPOK1 ;QUEUE & SUCCEED
CTHREM: PJRST @.(T3) ;DISPATCH FOR CTERM
IFIW CTHCSL ;(1) CHUNK SPACE LOW
IFIW CTHCNS ;(2) CHARACTER NOT STORED
IFIW CTHOSU ;(3) OUTPUT SUPPRESSION CHANGE
IFIW CTHCSA ;(4) CHUNK SPACE AVAILABLE
IFIW CTHDSC ;(5) DISCONNECT (TRMOP. .TODSF)
IFIW CTHCIB ;(6) CLEAR INPUT BUFFER (CLRBFI)
IFIW CTHTMO ;(7) DISCONNECT TIMEOUT
IFIW CTHBMC ;(10) BREAK MASK CHANGED
IFIW CTHBMC ;(11) OOB SET CHANGED
CTHCSL: SETONE CTXOF,(T1) ;REMEMBER SCNSER ASKED FOR AN XOFF
RETSKP ;TELL IT NOT TO SEND ONE
CTHCNS==CPOPJ## ;DON'T HANDLE UNTIL WE CAN MANAGE INPUT BLOCKING
CTHOSU: MOVX T2,CTCTG ;CHARACTER-TO-GO BIT
MOVX T3,CTCSD ;CHARACTERISTICS-SEQUENCE-DONE BIT
TDNE T3,CT.CSD(T1) ;IF CTCTG IS FOR NORMAL DATA,
ANDCAM T2,CT.CTG(T1) ;THEN DON'T SEND THE DEFERRED CHARACTER
RET ;AND DEFER TO CLOCK LEVEL SERVICE
CTHCSA: SETZRO CTXOF,(T1) ;OK TO SEND DRQ'S AGAIN (ACCORDING TO SCNSER)
PJRST TOPOK1 ;QUEUE FOR SERVICE AND SKIP THE CONTROL-Q
CTHDSC: SKIPA T2,[.UBUUR] ;USER UNBIND REQUEST
CTHTMO: MOVEI T2,.UBDSC ;TERMINAL DISCONNECTED
TMNE CTBAD,(T1) ;IF SUB-STANDARD PROTOCOL,
MOVEI T2,.UBUUR ;BE NICE AND DON'T MAKE VMS HANG UP ON THE USER
STOR T2,CTUBR,(T1) ;SAVE UNBIND REASON
PJRST TOPOK1 ;QUEUE & SUCCEED
CTHCIB: SETONE CTCIB,(T1) ;LIGHT BIT FOR NRTLKS
PJRST TOPOKE## ;RETURN TO SCNSER, QUEUEING FOR SERVICE
CTHBMC: SETONE CTOBC,(T1) ;RE-CALCULATE THE BREAK TABLE
TOPOK1: AOS (P) ;RETURN SUCCESS
PJRST TOPOKE## ;BUT ALSO QUEUE FOR SERVICE
SUBTTL NRTINI - Initialization
;Here to set up NRT host object for DECnet
;
;Call:
; RET ;ALWAYS
;
;Here to initialize the NRT data base
NRTINI::SAVEAC <M,W> ;CALLED FROM SYSINI
SEC1 ;NRTSER RUNS IN SECTION 1
HLRE T1,NETRTY## ;GET LENGTH OF AOBJN PTR TO NET LDBS
MOVMS T1 ;MAKE POSITIVE
AOJ T1, ;LEAVE ROOM FOR RELEASE TIMING
MOVEM T1,NRTCHL ;SAVE CHANNEL TABLE LENGTH
CALL NRTGWD ;GET WORDS FOR OUR CHANNEL TABLE
BUG. HLT,NRTSJM,NRTSER,SOFT,<No memory for NRT's SJB>,,<
Cause: This BUG is not documented yet.
>,NRTINI
MOVEM T1,NRTCHP ;STORE POINTER TO CHANNEL TABLE
MOVX T1,SA.LEN ;LENGTH OF AN SAB
CALL NRTGWD ;GET WORDS FOR OUR SA BLOCK
BUG. HLT,NRTSAB,NRTSER,SOFT,<No memory for NRT's SAB>,,<
Cause: This BUG is not documented yet.
>,NRTINI
MOVEM T1,NRTSAP ;STORE POINTER TO SCLINK ARG BLK
MOVEM T1,M ;NORMALLY USE M TO POINT TO SAB
;We will elect No Flow Control on incoming links.
; Default Goal Quota Input %
MOVE T1,NRTDFT ;GET DEFAULT GOAL,QUOTAS
SETZM NRTSJP ;IN CASE WE FAIL, SIGNAL TO OTHERS
SNCALL (MAKSJB##,MS.HGH) ;GO MAKE AN SJB
BUG. HLT,NRTSJB,NRTSER,SOFT,<No memory for NRT's SJB>,,<
Cause: This BUG is not documented yet.
>,NRTINI
SETONE SJPRV,(T1) ;TURN ON PRIVED BIT IN SJB
MOVEM T1,NRTSJP ;SAVE POINTER TO OUR SJB
STOR M,SJSAB,(T1) ;SAVE SAB PTR FOR SCLINK
RET ;RETURN
SUBTTL NRTSTO - Called every Jiffy via .CPSTO
;Called every jiffy to handle DECnet Network Remote Terminals
;
;Call:
; RET ;ALWAYS
;
;Changes M,W,U and T1 through T4
NRTSTO::
IFN FTMP,<XCT .CPSK0## ;SKIP IF WE'RE ON POLICY CPU
RET ;NO, ONLY RUN ONCE A JIFFY!
>
SOSG NRTINC ;HAS INTERVAL COUNTER EXPIRED YET?
SKIPN NRTSJP ;YES, HAS NRTINI BEEN CALLED?
RET ;NO
MOVE T1,NRTINL ;YES, GET INTERVAL LENGTH
MOVEM T1,NRTINC ;REINITIALIZE THE INTERVAL COUNTER
SEC1 ;NRTSER RUNS IN SECTION 1
IFE FTXMON,<
DNCALL (NRTSTX) ;CALL REST IN DECNET CONTEXT
RET ;DONE
>
NRTSTX: SKIPE NRTBLW ;IS THERE A BLOCKED LINK?
JRST [CALL NRTUNB ; YES, UNBLOCK IT
JRST NRTST3 ; STILL BLK'D, SEE IF WE CAN FREE ANY
JRST .+1] ;ALL CLEAR NOW, TRY FOR MORE OUTPUT
SKIPN NRTCWL ;ANY CONNECT WAITERS?
CALL NRTNEP ;NO, MAKE ANOTHER IF WE CAN
SKIPN CTHCWL ;ANY CONNECT WAITERS?
CALL CTHNEP ;NO, MAKE ANOTHER IF WE CAN
;We know that we can safely take at least one link with TOTAKE, since
;there is now no other blocked link, so the worst that can happen
;is that this link will become blocked and we'll have to try it again.
NRTST1: MOVEI T1,NRTRTQ ;GET THE QUEUE HEADER
CALL TOTAKE## ;GET U := TERMINAL NEEDING SERVICE
JRST NRTST2 ;IF NONE, THEN ALL DONE
SKIPE W,LDBNRT##(U) ;GET POINTER TO ITS NRB
CALL NRTLKS ;SERVICE THE LINK, IF ITS STILL THERE
JRST NRTST1 ;GO SEE IF ANY MORE TERMINALS TO START
;Loop over lines DECnet wants to service
NRTST2: SETZ T1, ;LOAD UP A ZERO
EXCH T1,NRTPSQ ;CLEAR FLAG SAYING DECnet WANTS US
JUMPE T1,NRTST4 ;LEAVE IF DECnet DIDN'T WANT SERVICE
NRTST3: MOVE T1,NRTSJP ;POINTER TO NRT'S SJB (EXTENDED ADDR)
SNCALL (SCTPSQ##,MS.HGH) ;ANY SERVICE NEEDED? (EXTENDED CALL)
NRTST4: RET ;NO, ALL DONE FOR THIS INTERVAL
HRRZ T1,T2 ;YES, GET CHANNEL NUMBER
MOVE T3,T1 ;COPY CHANNEL NUMBER
ADD T3,NRTCHP ;ADD IN BASE ADDR OF CHANNEL TABLE
SKIPG W,(T3) ;GET PTR TO NRB, ANYTHING THERE?
JRST NRTST3 ;NO, NO LONGER INTERESTED
OPSTR <CAME T1,>,NRCHN,(W) ;CHECK CHANNEL NUMBER
BUG. CHK,NRTSET,NRTSER,SOFT,<SCTPSQ returned wrong channel info>,,<
Cause: This BUG is not documented yet.
>,NRTST3
CALL NRTLKS ;SERVICE THE LINK
JRST NRTST3 ;LOOP OVER LINKS NEEDING SERVICE
SUBTTL NRTSEC - Called every second via .CPSTO
;Called every second to handle DECnet Network Remote Terminals
;
;Call:
; U/ Pointer to LDB
; RET ;ALWAYS
;
;Changes M,W,U and T1 through T4
;
;This routine is called at clock level (as are all NRTSER routines
;except NRTWAK) so it does not need an interlock from NRTSTO.
NRTSEC::
IFN FTMP,<
XCT .CPSK0## ;SKIP IF WE'RE ON POLICY CPU
RET ;NO, ONLY RUN ONCE A SECOND!
>
SAVEAC <W,U,P1,P2>
SEC1 ;NRTSER RUNS IN SECTION 1
SKIPN NRTBLW ;ANY BLOCKED LINK?
JRST NRTSE1 ;NO
IFE FTXMON,<
DNCALL (NRTSCX) ;NEED DECNET CONTEXT
RET
>
NRTSCX: CALL NRTUNB ;YES, TRY TO UNBLOCK IT
RET ;CAN'T, DECnet IS BLOCKED
NRTSE1:
RET
SUBTTL NJFRxx - Routines to handle each DECnet link state
;Routine to service a link according to its DECnet state
;Call
; W/ Pointer to NRB
; U/ Pointer to LDB
;
;Return:
; RET ;ONLY RETURN
NRTLKS: TMNE NRREL,(W) ;IS THIS NRB BEING RELEASED?
PJRST NRTREL ;YES, COMPLETE THE PROCESS
MOVE M,NRTSAP ;POINT TO NRT'S SAB
MOVX T1,.NSFRS ;READ STATUS FUNCTION CODE
MOVEI T2,3 ;NUMBER OF ARGS PASSED
CALL NRTNSF ;READ LINK STATUS, STORE IT IN NRB
PJRST NRTREL ;ERROR, CLEAN UP
LOAD T1,NRSTS,(W) ;GET LINK'S STATUS WORD
LOAD T1,NSSTA,+T1 ;GET THE STATE FIELD FROM STATUS
CAILE T1,NJFTLN ;A STATE WE UNDERSTAND?
SETZ T1, ;NO, CALL ILLEGAL STATE BUG.
PJRST @NJFTBL(T1) ;CALL ROUTINE APPROPRIATE TO LINK STATE
DEFINE LNKSTA(code),<
IFN .-NJFTBL-.NSS'code,<PRINTX NJFTBL is in wrong order>
IFIW NJFR'code ;;ADDRESS OF NJF ROUTINE
>
NJFTBL: IFIW NJFRIL ;ILLEGAL STATE
LNKSTA CW ;CONNECT WAIT
LNKSTA CR ;CONNECT RECEIVED
LNKSTA CS ;CONNECT SENT
LNKSTA RJ ;REMOTE REJECTED CONNECT INIT
LNKSTA RN ;LINK IS UP AND RUNNING
LNKSTA DR ;DISCONNECT RECEIVED
LNKSTA DS ;DISCONNECT SENT
LNKSTA DC ;DISCONNECT CONFIRMED
LNKSTA CF ;NO CONFIDENCE
LNKSTA LK ;NO LINK
LNKSTA CM ;NO COMMUNICATION
LNKSTA NR ;NO RESOURCES
NJFTLN==.-1-NJFTBL ;LENGTH OF TABLE
PURGE LNKSTA
NJFRCS: ;CONNECT SENT
NJFRIL: BUG. CHK,NRTILS,NRTSER,SOFT,<NRT link in unexpected state>,,<
Cause: This BUG is not documented yet.
>,NRTREL
NJFRRJ: ;REJECTED, WAITING FOR DC
NJFRDS: ;DISCONNECT SENT, WAITING FOR DC
NJFRCW: RET ;CONNECT WAIT, WAITING FOR A CONNECT
;NJFRCR - Jiffy Service Routine for a link in CONNECT RECEIVED state
;
;Call:
; W/ Pointer to Link's NRB
; RET ;ALWAYS
;
;Now we have someone interested in this link, try to get a LDB for
;it. If that succeeds, accept the link.
NJFRCR: ;CONNECT RECEIVED STATE PROCESSOR
TMNE NRCTM,(W) ;IS THIS A CTERM CONNECT?
SOSA CTHCWL ;YES, ONE LESS CTERM WAITER
SOS NRTCWL ;NO, ONE LESS NRT LINK IN CW STATE
MOVX T1,RSNRNS ;REMOTE NODE SHUT DOWN REASON CODE
MOVE T2,STATES## ;GET THE SCHEDULE BITS
TRNE T2,ST.NRT ;NO REMOTE TERMINALS?
JRST NJRCRF ;YES, GO ANNOUNCE THE FAILURE
;Get a TTY for this link
CALL NGTLDB ;GET A NRT LDB
JRST NJRCRF ;FAILED, REASON CODE IN T1
;Accept the Connect
MOVE M,NRTSAP ;POINT TO NRT'S SAB
SETZRO SAAA1,(M) ;NO USER DATA
MOVEI T1,NRTROL ;GET MAX BYTES IN OUR RECORD
STOR T1,SAAA2,(M) ;USE A MSG SEGMENT NO BIGGER THAN THAT
MOVX T1,NSF.C0 ;ELECT NO FLOW CONTROL FOR INPUT
STOR T1,SAAA3,(M) ;ARG #3
MOVX T1,.NSFAC ;ACCEPT FUNCTION CODE
MOVEI T2,5 ;NUMBER OF ARGS PASSED
CALL NRTNSF ;ACCEPT THE CONNECT
PJRST NRTREL ;ERROR, CLEAN UP
;Read link status to find out segment size
MOVE M,NRTSAP ;POINT TO NRT'S SAB
MOVX T1,.NSFRS ;READ STATUS FUNCTION CODE
MOVEI T2,3 ;NUMBER OF ARGS PASSED
CALL NRTNSF ;READ LINK STATUS
PJRST NRTREL ;ERROR, CLEAN UP
LOAD T1,SAAA1,(M) ;GET LINK'S SEGMENT SIZE
CAMLE T1,NRTMAX ;IS THAT TOO BIG FOR US?
MOVE T1,NRTMAX ;YES, LOAD UP OUR MAX
CAILE T1,NRTROL ;HAS SOMEONE POKED THAT TOO BIG?
MOVEI T1,NRTROL ;YES, LIMIT TO SIZE OF RECORD
STOR T1,NRSIZ,(W) ;STORE FOR NRTOUT
MOVE T1,NRTINA ;GET INACTIVITY TIMER
CALL SCNADT## ;START THE TIMER GOING
TMNN NRCTM,(W) ;CTERM LINK?
PJRST NRTNEP ;NO, HANG OUT A NEW NRT CONNECT WAIT LINK
LOAD T1,NRSIZ,(W) ;YES, GET SIZE AGAIN
CAIGE T1,CTHMSZ ;IS THE BUFFER SIZE ACCEPTABLE?
CALL NRTREL ;NO, PUNT THE LINK
PJRST CTHNEP ;HANG OUT A NEW CTERM LINK
;We'll send a configuration message when we get a data request.
;Here on failure in Connect Received state processing
NJRCRF: MOVE M,NRTSAP ;POINT TO NRT'S SAB
STOR T1,SAAA2,(M) ;SET DISCONNECT REASON
SETZRO SAAA1,(M) ;NO STRING BLOCK
MOVX T1,.NSFRJ ;REJECT FUNCTION CODE
MOVEI T2,4 ;NUMBER OF ARGS PASSED
CALL NRTNSF ;REJECT THE CONNECT
PJRST NRTREL ;RELEASE THE LINK
RET ;WE'LL RELEASE LINK WHEN DC COMES IN
;The configuration message sent out when we accept a connect
CFGLEN==10 ;BYTES IN CONFIG MESSAGE
CFGMSG: BYTE(8) 1,1,0,0,11,0,10,0
; Config--' ^ ^ ^ ^ ^ ^ ^
; ? ? ? | ? | ?
; System=TOPS10----' |
; Protocol=TOPS20-------'
;The Bind message sent out when CTERM accepts a connect
OSTYPE==O.T10 ;OUR O/S TYPE
PTTYPE==PT%CTM ;PROTOCOLS WE SUPPORT
BNDMSG: BYTE (8) .FMBND,2,0,0,OSTYPE,OSTYPE/B8,PTTYPE,PTTYPE/B8
;REMAINING BYTES ARE VARIABLE, AND FILLED IN BY SNDCFG
BNDLEN==23 ;TOTAL BYTES IN BIND-REQUEST MESSAGE
;BIND/CONFIG FIELDS:
; (0) MESSAGE TYPE (CONFIG/BIND-REQUEST)
; (1-3) PROTOCOL VERSION:
; (1) MAJOR
; (2) ECO (MINOR)
; (3) MOD (CUSTOMER) LEVEL
; (4-5) SYSTEM TYPE CODE (NETWORK BYTE ORDER) 11=TOPS10
; (6-7) MASK OF PROTOCOLS SUPPORTED (NETWORK BYTE ORDER)
; 10=PIM (NRT)
; 20=CTERM
; (10-17) SYSTEM REVISION STRING (ASCII)
; (20-21) LDPLNO
; (22) OPTIONS (1=HIGH-AVAILABILITY)
;NJFRRN - Jiffy Service Routine for a link in RUN state
;
;Call:
; W/ Pointer to Link's NRB
; RET ;ALWAYS
;
;The link is running, see if any traffic needs to be transferred.
NJFRRN: ;LINK IS UP AND RUNNING
LOAD U,NRLDB,(W) ;GET PTR TO LDB
;First, try some input, may free up some DECnet buffers for output
LOAD T1,NRSTS,(W) ;GET DECnet STATUS LAST TIME WE HEARD
NJFRR1: TXNN T1,NSNDA ;NORMAL DATA AVAILABLE?
JRST NJFRR2 ;NO, TRY OUTPUT
CALL NRTIN ;YES, TRY TO READ SOME
JFCL ;IGNORE ERROR HERE
;See if there is any output requested and allowed now
NJFRR2: LOAD T1,NRSTS,(W) ;GET DECnet STATUS LAST TIME WE HEARD
TXNN T1,NSNDR ;NORMAL DATA REQUESTED?
RET ;NO, ALL DONE WITH THIS LINK
CALL NRTOUT ;YES, TRY TO SEND SOME
JFCL ;BLOCKED, CAN'T DO ANY OUTPUT
RET ;RETURN
;NRTOUT - Try to do some output from SCNSER to DECnet
;
;Call, when DECnet is ready to receive from us:
; W/ Pointer to Link's NRB
; U/ Points to LDB
;Return:
; RET ;IF FATAL ERROR
; RETSKP ;SUCCESS
NRTOUT: SAVEAC <P1,P2>
NRTOT1: LOAD P1,NRSIZ,(W) ;GET MAX BYTES IN A SEGMENT ON LINK
MOVE P2,[POINT 8,NRTRCO] ;BYTE POINTER TO RECORD WE'LL SEND
MOVE R,NR.FLG(W) ;GET THE FLAGS
TXNN R,NRCFG ;HAVE WE SENT OUR CONFIG MESSAGE YET?
PJRST SNDCFG ;NO, DO SO
TXNE R,NRCTM ;YES, IS THIS A CTERM LINK?
JRST CTHOUT ;YES, USE OTHER PROTOCOL
NRTOT2: CALL XMTCHR## ;GET A CHAR IN T3
JRST NRTOT6 ;NO MORE, SEND WHAT WE COLLECTED
IDPB T3,P2 ;STORE BYTE
SOJG P1,NRTOT2 ;GET MORE WHILE THERE'S ROOM
NRTOT3: LOAD P2,NRSIZ,(W) ;GET MAX AGAIN
NRTOT4: CALL NRTOT7 ;SEND THAT MUCH
RET ;BLOCKED, TRY AGAIN LATER
LOAD T1,NRSTS,(W) ;GET DECnet STATUS AFTER LAST SEND
TXNN T1,NSNDR ;NORMAL DATA STILL REQUESTED?
RETSKP ;NO, SUCCESS RETURN NOW
JRST NRTOT1 ;SUCCESS, TRY FOR MORE
;CTERM messages come here to be sent out
NRTOT5: LOAD P2,NRSIZ,(W) ;GET MAX AGAIN
SUB P2,P1 ;FIND HOW MANY WE COPIED
JUMPG P2,NRTOT4 ;SEND & LOOP IF WE DID SOMETHING
RETSKP ;SUCCESS RETURN IF NONE
;Completed messages come here for a final send-off
NRTOT6: LOAD P2,NRSIZ,(W) ;GET MAX AGAIN
SUB P2,P1 ;CALC NUMBER WE COPIED
JUMPLE P2,NRTOT9 ;CHECK FOR END OF SESSION IF NONE
;FALL THROUGH TO NRTOT7 TO SEND
;Subroutine to send data for NRTOUT & CTHOUT
NRTOT7: MOVE M,NRTSAP ;POINT TO NRT'S SAB
STOR P2,SAAA1,(M) ;STORE LENGTH OF DATA TO SEND
MOVX T1,<<POINT 8,>!1B12> ;MAKE A 2-WORD BYTE POINTER
STOR T1,SAAA2,(M) ;STORE AS FIRST WORD OF BYTE POINTER
XMOVEI T1,NRTRCO ;GET EXTENDED ADDR OF RECORD
STOR T1,SAAA3,(M) ;STORE AS 2ND WORD OF BYTE POINTER
SETONE SAEOM,(M) ;SET THE END-OF-MESSAGE FLAG
MOVX T1,.NSFDS ;DATA SEND FUNCTION
MOVEI T2,5 ;NUMBER ARGS WE'RE PASSING
CALL NRTNSF ;SEND THE DATA TO DECnet
JRST NRTOT8 ;ERROR, GO DEAL WITH IT
LOAD T1,SAAA1,(M) ;GET COUNT OF BYTES LEFT TO SEND
JUMPE T1,CPOPJ1 ;SUCCESS RETURN NOW IF ALL SENT
;Here when the link is blocked (DECnet is out of buffers)
MOVEM W,NRTBLW ;SAVE PTR TO BLOCKED LINK
MOVEM T1,NRTBLC ;SAVE COUNT OF BYTES STILL TO SEND
LOAD T1,SAAA2,(M) ;GET BYTE POINTER
LOAD T2,SAAA3,(M) ;GET SECOND WORD OF BYTE POINTER
DMOVEM T1,NRTBLP ;SAVE BYTE PNTR FROM WHICH TO SEND
RET ;FAIL RETURN
NRTOT8: LOAD T1,SAAST,(M) ;GET NEW STATUS
LOAD T1,NSSTA,+T1 ;GET THE STATE FIELD FROM STATUS
CAIN T1,.NSSRN ;IN RUN STATE?
BUG. CHK,NRTOUD,NRTSER,SOFT,<NRT output to DECnet failed>,,<
Cause: This BUG is not documented yet.
>,NRTREL
RETSKP ;DON'T COMPLAIN NOW, ITS CLOSING
NRTOT9: TMNE NRCTM,(W) ;CTERM WILL DISCONNECT IN ITS OWN WAY
RETSKP ;SO DON'T DO IT HERE
TMNE NRRLS,(W) ;SEE IF IT WANTS TO BE RELEASED
PJRST NRTRLS ;CLOSE OFF THE LINK
RETSKP ;SUCCESS RETURN IF NOT TO BE CLOSED
;SNDCFG - Send a configuration message
;
;Call:
; W/ Pointer to Link's NRB
; U/ Pointer to LDB
;
;Return:
; RET ;ERROR
; RETSKP ;SUCCESS
;
;Send a configuration message
SNDCFG: SETONE NRCFG,(W) ;WE'RE SENDING THE CONFIG MESSAGE NOW
TMNN NRCTM,(W) ;IS THIS A CTERM LINK?
JRST SNDCFN ;NO, JUST SEND NRT MESSAGE
MOVE T2,[POINT 8,BNDMSG] ;POINT TO PROLOGUE OF BIND MESSAGE
MOVEI T3,8 ;PROLOGUE LENGTH
CALL CFOSTR ;STUFF BYTES
MOVE T2,[POINT 8,CTHREV##] ;POINT TO REVISION STRING IN COMMON
MOVEI T3,8 ;IT'S EIGHT BYTES LONG
CALL CFOSTR ;TRANSFER TO OUTPUT RECORD
LDB T1,LDPLNO## ;GET LINE NUMBER FROM LDB
CALL CFOINT ;STUFF INTO MESSAGE
MOVEI T1,CTHOPT## ;GET OPTIONS BYTE FROM COMMON
CALL CFOBYT ;INSERT INTO MESSAGE
PJRST NRTOT5 ;SEND IT OFF
;Here to send the config message for NRT links
SNDCFN: MOVEI T3,CFGLEN ;LENGTH OF MESSAGE TO SEND
MOVE T2,[POINT 8,CFGMSG] ;BYTE POINTER TO CONFIG MSG
CALL CFOSTR ;STUFF INTO OUTPUT RECORD
PJRST NRTOT5 ;SEND IT OFF AND LOOP FOR MORE
;NRTUNB - Unblock a link which is blocked trying to output
;
;Call: NRTBLW/ Pointer to NRB of blocked link
; NRTBLC/ Count of bytes still to send
; NRTBLP/ Two-word byte pointer from which to send
;
;Return:
; RET ;If link still blocked, NRTBLx updated
; RETSKP ;If link is now free, NRTBLW zeroed
;
;Uses T1-T4, M and the SAB
NRTUNB: SAVEAC W
MOVE M,NRTSAP ;POINT TO NRT'S SAB
SKIPN W,NRTBLW ;GET POINTER TO BLOCKED NRB
RETSKP ;NONE? LEAVE SUCCESSFULLY
MOVE T1,NRTBLC ;GET COUNT OF BYTES TO SEND
STOR T1,SAAA1,(M) ;STORE IN SAB
DMOVE T1,NRTBLP ;GET DOUBLE-WORD BYTE PTR
STOR T1,SAAA2,(M) ;PASS IN SAB
STOR T2,SAAA3,(M) ;PASS SECOND WORD OF BYTE PTR
SETONE SAEOM,(M) ;SET THE END-OF-MESSAGE FLAG
MOVX T1,.NSFDS ;DATA SEND FUNCTION
MOVEI T2,5 ;NUMBER ARGS WE'RE PASSING
CALL NRTNSF ;SEND THE DATA TO DECnet
JRST NRTOT8 ;ERROR, GO DEAL WITH IT
LOAD T1,SAAA1,(M) ;GET COUNT OF BYTES LEFT TO SEND
JUMPE T1,NRTUN1 ;SUCCESS RETURN NOW IF ALL SENT
;Here when the link is still blocked (DECnet is out of buffers)
MOVEM T1,NRTBLC ;SAVE NEW COUNT OF BYTES STILL TO SEND
LOAD T1,SAAA2,(M) ;GET NEW BYTE POINTER
LOAD T2,SAAA3,(M) ;GET NEW BYTE POINTER (2ND WORD)
DMOVEM T1,NRTBLP ;SAVE BYTE PNTR FROM WHICH TO SEND
RET ;FAIL RETURN
;Here when the link is unblocked
NRTUN1: SETZM NRTBLW ;NO LINK IS NOW BLOCKED
RETSKP ;SUCCESS RETURN
;NRTRLS - Release an idle link
;
;Call, when DECnet is willing to accept data:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;IF FATAL ERROR
; RETSKP ;SUCCESS
NRTRLS: MOVE R,NR.FLG(W) ;GET THE FLAGS WORD
TXNE R,NRCTM ;IS THIS A CTERM LINK?
JRST CTHRLS ;YES, GO RELEASE IT THAT WAY
TXNN R,NRTMO ;DID IT TIME OUT?
JRST NRTRS1 ;NO, JUST DISCONNECT IT
SETZRO NRTMO,(W) ;CLEAR FLAG FOR NEXT CALL
PUSHJ P,INLMES## ;SEND SOME TEXT TO THE TTY
ASCIZ "
[ Idle line disconnected by host ]
"
PJRST NRTOT1 ;SEND THE TEXT, THEN DISCONNECT THE LINK
NRTRS1: MOVE M,NRTSAP ;POINT TO NRT'S SAB
MOVX T1,.NSFSD ;SYNCHRONOUS DISCONNECT FUNCTION
MOVEI T2,2 ;NUMBER OF ARGS PASSED
CALL NRTNSF ;INITIATE THE DISCONNECT PROCESS
JFCL ;IGNORE ERROR RETURN
RET
;Here to disconnect a line for CTERM
CTHRLS: CAIGE P1,3 ;DO WE HAVE ENOUGH BYTES?
PJRST NRTRS1 ;NO, GIVE UP
MOVEI T1,.FMUNB ;YES, UNBIND IS MESSAGE TYPE TWO
CALL CFOBYT ;PUT INTO THE FOUNDATION MESSAGE
LOAD T1,CTUBR,(W) ;GET THE UNBIND REASON CODE
CALL CFOINT ;SEND IT AS A NETWORK INTEGER
SETZRO <NRTMO,NRCTM>,(W) ;SETUP TO BE RELEASED AFTER SENDING DATA
SETONE NRRLS,(W) ;MAKE SURE
PJRST NRTOT5 ;SEND THE DATA AND RETURN
;CTHOUT - Try to send some CTERM messages
;
;Call, when DECnet is willing to accept data:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;IF FATAL ERROR
; RETSKP ;SUCCESS (USUALLY VIA NRTOT5)
CTHOUT: TMNE CTRLS,(W) ;PROTOCOL ERROR SEEN?
JRST CTHRLS ;YES, GIVE UP NOW
TMNN CTRUN,(W) ;IS THE FULL PROTOCOL RUNNING YET FOR THIS LINK?
JRST CTHOT2 ;NO, SEE WHAT WE NEED TO DO TO START IT
TMNE CTCIB,(W) ;DO WE NEED TO CLEAR THE INPUT BUFFER?
JRST CTHCTA ;YES, GO SEND CLEAR-TYPEAHEAD
MOVEI T1,L1RCHP## ;SCNSER BIT FOR CHARACTERISTICS CHANGES
TDNE T1,LDBBYT##(U) ;DOES SCNSER WANT US TO CHANGE SOME?
JRST CTHONC ;YES, SET NEW CHARACTERISTICS
TMNE CTOBC,(W) ;DO WE NEED TO CHANGE OUR OUT-OF-BAND SET?
CALL CTHOOB ;YES, DO IT
CALL CTHDRQ ;SEND OFF A DRQ IF NECESSARY
PJRST CCOFIN ;DID SOMETHING, SEND IT OFF
CALL CTHXMT ;TRY TO SEND CHARACTERS
PJRST CCOFIN ;DONE
LOAD T1,CTUBR,(W) ;GET POSSIBLE UNBIND REASON
JUMPN T1,CTHRLS ;IF SET, DO THE SOFT UNBIND NOW
RETSKP ;JUST RETURN SUCCESS IF NOTHING TO DO
CTHOT2: MOVE R,CT.FLG(W) ;GET FLAGS WORD
TXNN R,CTSPI ;WE'RE BOUND, HAVE WE SENT A PROTOCOL INIT?
JRST CTHOPI ;NO, GO SEND ONE
TXNN R,CTBND ;ARE WE STILL BINDING?
RETSKP ;YES, DON'T BOTHER ME
TXNN R,CTRCS ;HAVE WE REQUESTED CHARACTERISTICS?
JRST CTHORC ;NO, MUST DO SO
TXNN R,CTRPI ;YES, HAVE WE ALSO RECEIVED ONE?
RETSKP ;NO, WE CAN DO NOTHING UNTIL THEN
TXNN R,CTCHP ;YES, HAVE WE SEEN THEM YET?
RETSKP ;NO, WE HAVE TO WAIT FOR THEM
TXNN R,CTCSD ;HAVE WE SENT OURS YET?
JRST CTHOSC ;NO, SEND THEM
SETONE CTRUN,(W) ;YES, ADMIT TO RUNNING THE PROTOCOL
SETONE CTOBC,(W) ;BUT WE HAVEN'T DONE A BREAK MASK YET
CALL TTFGRT## ;FIRE UP INITIA ON THE LINE
JRST CTHOUT ;AND TRY AGAIN THIS WAY
;CTHCTA - CTERM Clear-typeahead needs to be sent
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;ON FATAL ERROR
; RETSKP ;IF SUCCESS (VIA NRTOT5)
CTHCTA: MOVEI T1,.FMCMD ;COMMON DATA MESSAGE (DATA FOR CTERM LAYER)
CALL CFOINT ;SETUP FOR CTERM MESSAGES
MOVEI T1,2 ;A TWO-BYTE SUB-MESSAGE
CALL CFOINT ;SET THE LENGTH
MOVEI T1,.CMUNR ;UNREAD (UNCONDITIONAL)
CALL CFOINT ;STUFF THE BYTES
MOVEI T1,2 ;ANOTHER TWO-BYTE SUB-MESSAGE
CALL CFOINT ;SET THE LENGTH
MOVEI T1,.CMCTA ;CLEAR TYPEAHEAD
CALL CFOINT ;STUFF THE BYTES
SETZRO CTCIB,(W) ;WE ARE CLEARING THE INPUT BUFFER NOW
TMNN CTDRQ,(W) ;DOES OUR UNREAD MEAN ANYTHING?
PJRST NRTOT5 ;NO, JUST SEND THE MESSAGE AND DISMISS
SETONE CTDRI,(W) ;YES, NOTE IT FOR THE READ-DATA HANDLER
SETONE CTURA,(W) ;AND THAT AN UNREAD IS ACTIVE
PJRST NRTOT5 ;NOW SEND & DISMISS
;CTHOOB - CTERM Out-of-band characteristics need to be sent
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;ALWAYS
;THESE BITS DEFINE WHAT WE CONSIDER TO BE A BREAK CHARACTER
CCBRK==<CHBRK##!CHUAE##!CHALT##!CHRIA##!CHINVL##!CHCRE##!CHNDFR##>
CTHOOB: SETZRO CTOBC,(W) ;WE'RE DOING OUR CHANGES NOW
MOVE CX,[POINT 8,CH.BKM(W)] ;POINT TO NETWORK BREAK MASK
MOVSI T3,-400 ;LOOP OVER ALL CHARACTERS
CTHOB1: MOVEI T2,1 ;NEW BYTE, START WITH LSB
SETZ T4, ;AND AN EMPTY BYTE
CTHOB2: CALL SPCHEK## ;SEE IF THIS CHARACTER IS SPECIAL
TRN ;MAYBE NOT
TLNN T1,CHBRK##!CHOOB## ;IS IT A BREAK (TO US)?
CALL CHRMAP ;OR IS IT MAPPED?
IOR T4,T2 ;YES OR YES, CONSIDER IT A BREAK
LSH T2,1 ;MOVE THE BIT OVER
TRNE T2,BYTMSK ;IF STILL IN THIS BYTE
AOBJN T3,CTHOB2 ;LOOP OVER IT
ILDB T2,CX ;GET MATCHING BYTE OF PREVIOUS STRING
CAMN T2,T4 ;DO THEY MATCH?
JRST CTHOB3 ;YES, DON'T UPDATE
TRO T3,400000 ;NO, MARK THAT SOMETHING CHANGED
DPB T4,CX ;AND STORE THE NEW BYTE
CTHOB3: AOBJN T3,CTHOB1 ;LOOP OVER ALL CHARACTERS
TRNN T3,400000 ;DID WE CHANGE ANYTHING?
RET ;NO, JUST RETURN
SETONE CTBMC,(W) ;YES, NOTE THE NEW BREAK MASK
RET ;NOW RETURN
CHRMAP: TRNN T3,CK.CHR ;IF TESTING NUL,
RET ;IT'S SPECIAL
PUSH P,T1 ;SAVE SOME ACS
PUSH P,T2 ;WE NEED THEM
MOVE T1,T3 ;COPY CURRENT CHARACTER
ANDI T1,CK.CHR ;MASK OFF FUNNY STUFF
LDB T2,LDPUNP## ;GET UNPAUSE CHARACTER
CAMN T2,T1 ;IS THIS IT?
JRST TTPOPJ## ;YES, GIVE MAPPED RETURN
LDB T2,LDPESC## ;NO, GET ESCAPE CHARACTER
CAMN T2,T1 ;DOES THIS MATCH?
JRST TTPOPJ## ;YES, IT'S MAPPED
LDB T2,LDPSW1## ;NO, GET SWITCH-1
CAMN T2,T1 ;MATCH?
JRST TTPOPJ## ;YES, MAPPED
LDB T2,LDPSW2## ;NO, GET SWITCH-2
CAME T2,T1 ;UNLESS MATCH,
AOS -2(P) ;IT'S NOT MAPPED
JRST TTPOPJ## ;RESTORE ACS AND RETURN
;CTHONC - CTERM Characteristics message needs to be sent
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ L1RCHP
;Return:
; RET ;IF FATAL ERROR
; RETSKP ;SUCCESS (USUALLY VIA NRTOT5)
DEFINE HAK(CHRS),<
IRP CHRS,<
LDB T1,LDP'CHRS'## ;;GET CHARACTERISTIC TO HACK
TRC T1,1 ;;CHANGE IT
STOR T1,CH'CHRS,(W) ;;CLOBBER OUR VALUE (SO WE SEND IT)
>>
CTHONC: ANDCAM T1,LDBBYT##(U) ;WE'RE GOING TO SEND THE CHARACTERSTICS MSG
MOVEI T1,.CMCHR ;MESSAGE TYPE FOR CTERM CHARACTERISTICS
CALL CCOST2 ;SETUP FOR COMMON DATA/CTERM MESSAGE
LDB T1,LDPPIM## ;GET PIM BIT
LOAD T2,CHPIM,(W) ;AND OUR COPY
CAMN T1,T2 ;DO THEY MATCH?
JRST CTHON4 ;YES, DON'T CHANGE IT
STOR T1,CHPIM,(W) ;YES, UPDATE OUR COPY
CALL CHOPIM ;CHANGE IT
CTHON4: LDB T1,LDPIMI## ;GET IMAGE-MODE BIT
LOAD T2,CHIMI,(W) ;AND OUR COPY
CAMN T1,T2 ;DO THEY MATCH?
JRST CTHON3 ;YES, DON'T CHANGE IT
STOR T1,CHIMI,(W) ;YES, UPDATE OUR COPY
CALL CHOIMI ;CHANGE IT
CTHON3: MOVE R,CH.FLG(W) ;GET MODE BITS
TXNE R,CHPIM!CHIMI ;ARE WE IN IMAGE MODE?
PJRST CCOFIN ;YES, DON'T CLOBBER OUR IMAGE-MODE VALUES
PUSH P,P3 ;WE NEED AN AC FOR AOBJN'ING
MOVSI P3,-CHRTBL ;FORM AOBJN INDEX TO TABLES
; TMNE CTBAD,(W) ;IS THIS THE SUB-STANDARD PROTOCOL?
; MOVSI P3,1-CHRTBL ;YES, DON'T MAKE RTPAD ACCVIO
CTHON1: LDB T2,@CHRSCN(P3) ;GET VALUE FROM SCNSER
LDB T1,CHRTAB(P3) ;AND FROM OURSELVES
CAMN T2,T1 ;DO THEY MATCH?
JRST CTHON2 ;YES, NOTHING TO CHANGE
MOVE T1,CHRPID(P3) ;NO, GET THE PROTOCOL ID OF THE VALUE
CALL CCOINT ;SAY WHAT VALUE WE'RE CHANGING
MOVE T1,T2 ;MOVE THE NEW CHARACTERISTIC
DPB T1,CHRTAB(P3) ;UPDATE IN OUR RECORDS
CALL @CHRPUT(P3) ;SEND THE NEW VALUE
CTHON2: AOBJN P3,CTHON1 ;LOOP OVER ALL OF TABLE
POP P,P3 ;RESTORE AC
PJRST CCOFIN ;SEND THE MSG AND RETURN
;Build the characteristic tables for CTHONC
DEFINE CHRS,<
C TTT,TTN,TTT
C WID,WID,INT
C LNB,LEN,INT
C LCT,RAI,BYT
C ECH,ECH,IVB
C DIS,TAM,DIS
C XNF,OFC,BYT
C 8BT,CSZ,8BT ;;MUST BE LAST!!! (FOR *$&$&$& VMS)
>
CHRTAB: DEFINE C(NAM,PID,FMT),<POINTR CH.'NAM(W),CH'NAM>
CHRS
CHRTBL==.-CHRTAB ;LENGTH OF THE TABLE
CHRSCN: DEFINE C(NAM,PID,FMT),<IFIW LDP'NAM'##>
CHRS
CHRPID: DEFINE C(NAM,PID,FMT),<EXP .CC'PID>
CHRS
CHRPUT: DEFINE C(NAM,PID,FMT),<IFIW CCO'FMT>
CHRS
;CHOPIM & CHOIMI - Send appropriate characteristics for image modes
CHOPIM: JUMPE T1,CHOPM2 ;GO ELSEWHERE IF CLEARING IT
MOVE T2,[POINT 8,PIMMSG] ;POINT TO PIM MESSAGE STRING
MOVEI T3,PIMLEN ;GET ITS LENGTH
; TMNE CTBAD,(W) ;IS THIS FOR VMS?
; SUBI T3,FT.8BC+2 ;YES, DON'T TWEAK 8-BIT STUFF
CALL CCOSTR ;SEND THE BYTES
RET ;BACK TO CTHONC
CHOPM2: HAK <LCT,8BT,ECH> ;SEND THE VALUES OF THESE
RET ;BACK TO CTHONC
PIM RAI,0
PIM ECH,0
PIM CSZ,8 ;MUST BE LAST FOR **&&* VMS!!
PIMMSG: BYTSTR (PIM)
PIMLEN==PIMLEN ;PUBLISH THE LENGTH
CHOIMI: JUMPE T1,CHOIM2 ;GO ELSEWHERE IF CLEARING IT
MOVE T2,[POINT 8,IMIMSG] ;POINT TO IMAGE MESSAGE STRING
MOVEI T3,IMILEN ;GET ITS LENGTH
; TMNE CTBAD,(W) ;IS THIS FOR VMS?
; SUBI T3,FT.8BC+2 ;YES, DON'T TWEAK 8-BIT STUFF
CALL CCOSTR ;SEND THE BYTES
RET ;BACK TO CTHONC
CHOIM2: HAK <LCT,8BT,ECH,XNF> ;BE SURE TO SEND THESE
RET ;BACK TO CTHONC
IMI RAI,0
IMI ECH,0
IMI OFC,0
IMI CSZ,8 ;MUST BE LAST FOR **&&* VMS!!
IMIMSG: BYTSTR (IMI)
IMILEN==IMILEN ;PUBLISH THE LENGTH
;CTHXMT - CTERM Write message initiator
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;IF TIME TO STOP (WE SEND SOMETHING)
; RETSKP ;KEEP LOOKING FOR SOMETHING TO DO
;Define our default Write message flags
WRTMSK==WR.EOM!WR.BOM!WR.CDS!FLD(.WRLTU,WR.LOK)
CTHXMT: MOVX R,CTCTG ;CHARACTER-TO-GO BIT
TDNE R,CT.CTG(W) ;IS IT LIT?
JRST CTHXM1 ;YES, GO USE IT
CALL XMTCHR## ;NO, GET ONE
RETSKP ;NOTHING TO DO IF NONE TO SEND
JRST CTHXM2 ;YES, WE HAVE A CHARACTER
CTHXM1: ANDCAM R,CT.CTG(W) ;WE'RE ABOUT TO USE THE CHARACTER
LOAD T3,CTCHO,(W) ;FETCH IT
CTHXM2: SAVEAC P3 ;CHARACTER BIT-TEST AC
MOVEI T1,.CMWRT ;START-WRITE MESSAGE TYPE
CALL CCOSET ;BEGIN CTERM MESSAGE
MOVEI T1,WRTMSK ;GET BITS TO SEND
TRNE T3,CK.IMG ;IF CHARACTER IS IMAGE,
TRO T1,WR.BIN ;THEN SO IS THIS WRITE
;IF WE EVER IMPLEMENT THE DOBE FUNCTION, TEST FOR IT HERE AND LIGHT WR.VFY
CALL CCOINT ;SEND THE FLAG BITS
SETZ T1, ;POSTFIX & PREFIX BYTES
CALL CCOINT ;WE HAVE NONE
CTHXM3: MOVE T1,T3 ;MOVE CHARACTER FOR OUTPUT
CALL CCOBYT ;STUFF INTO MESSAGE
JUMPLE P1,CPOPJ## ;END OF MESSAGE IF FULL
MOVE P3,T3 ;SAVE MESSAGE FOR CK.IMG COMPARISON
CALL XMTCHR## ;GET THE NEXT CHARACTER FOR OUTPUT
RET ;DONE IF NO MORE
XOR P3,T3 ;GET CHANGE MASK
TRNN P3,CK.IMG ;DID IMAGE-MODE STATUS CHANGE?
JRST CTHXM3 ;NO, SEND THE CHARACTER
SETONE CTCTG,(W) ;YES, NOTE THAT WE HAVE A CHARACTER TO SEND
STOR T3,CTCHO,(W) ;SAVE IT AWAY
RET ;AND FINISH OFF THIS WRITE MESSAGE
;CTHDRQ - CTERM Send a start-read if appropriate
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;IF A DRQ HAS BEEN PACKAGED TO SEND
; RETSKP ;IF NOTHING TO DO (CONTINUE SCANNING)
;Define our default masks for Start-Read flags
SRDMSK==SR.TMR!SR.NEC!SR.CON!SR.VPT!FLD(.SRTRM,SR.UND)!FLD(.SRALL,SR.CCD)
;BYTES 0 & 1
SR2MSK==0 ;BYTE 2
CTHDRQ: MOVE T4,CT.FLG(W) ;GET THE FLAG BITS
TXNE T4,CTBMC ;HAS THE BREAK MASK CHANGED?
TXNN T4,CTDRQ ;YES, DID IT CHANGE DURING A READ?
JRST CTHDR1 ;NO OR NO, KEEP GOING
TXNE T4,CTURA ;YES AND YES, DID I ALREADY SEND THE UNREAD?
RETSKP ;YES, WE'RE DONE HERE (UNTIL READ DATA COMES)
SETONE CTURA,(W) ;NO, LIGHT UNREAD-ACTIVE FLAG
MOVEI T1,.CMUNR ;UNREAD REQUEST
CALL CCOSET ;SET IT UP
SETZ T1, ;NO FLAGS
PJRST CCOBYT ;STUFF FLAGS BYTE & RETURN TO CTHOUT
CTHDR1: TXNE T4,CTDRQ!CTXOF ;DO WE NEED TO SEND A DATA REQUEST?
RETSKP ;NO, JUST GIVE CONTINUE RETURN
MOVEI T1,.CMSRD ;YES, GET START-READ MESSAGE TYPE
CALL CCOSET ;PREPARE TO SEND IT
MOVEI T1,SRDMSK ;GET BITS TO SEND
TXNE T4,CTBMC ;DID THE BREAK MASK CHANGE?
TRO T1,FLD(.SRUNT,SR.TRM) ;YES, WE'RE ALSO SENDING A NEW MASK
TXNE T4,CTDRZ ;WAS THE LAST READ-DATA NULL?
TXZ T1,SR.TMR ;YES, DON'T TIME THIS ONE
REPEAT 0,< ;DON'T DO THIS UNTIL TOPS-20'S SERVER WORKS
TXNE T4,CTCTG ;ONLY IF NOT WAITING
JRST CTHDR2 ;CAN'T IF WE ARE
MOVE T2,LDBBY2##(U) ;NO, GET MISC. TERMINAL BITS
TLNE T2,L2LDEL## ;NO, ARE WE IN RUBOUT SEQUENCE?
JRST CTHDR2 ;YES, CAN'T ECHO
SKIPGE T2,LDBDCH##(U) ;GET STATUS BITS, SKIP IF OUTPUT ACTIVE
TLNE T2,LDLNEC##!LDLLCP##!LDLCNE##!LDLBKA##!LDLIMI## ;PROGRAM CONTROL?
JRST CTHDR2 ;YES
TMNE CHPIM,(W) ;PIM IS ALSO EXCESSIVE PROGRAM CONTROL
JRST CTHDR2 ;SO CAN'T DO IT THEN, EITHER
SKIPN LDBIST##(U) ;IF DOING FANCY TWO-CHARACTER INPUT,
SKIPGE LDBCHM##(U) ;OR FANCY MAPPING
JRST CTHDR2 ;CAN'T DO IT
EXTERN LMLNDS ;FLAG BIT REFERENCED
MOVE T2,LDBBYT##(U) ;GET THE DEFERED ECHO BITS
TLNN T2,L1LUNR## ;IF NOT IN UNREAD,
TRNN T2,L1RDEL## ;AND IF WAITING FOR A LINE
JRST CTHDR2 ;NO, CAN'T ECHO
TXZ T1,SR.NEC ;YES, OK TO ECHO AFTER ALL
> ;END OF UNTIL TOPS-20 ETC.
CTHDR2: CALL CCOINT ;STUFF THE FLAG BITS
MOVX R,CTDRQ ;READ ACTIVE BIT
TRNN T1,SR.NEC ;ARE WE ALLOWING ECHO?
TXO R,CTECH ;YES, ADD IN THAT BIT
IORM R,CT.FLG(W) ;SET DRQ & ECH FLAGS APPROPRIATELY
MOVEI T1,SR2MSK ;GET THIRD BYTE OF FLAGS TO SEND
CALL CCOBYT ;SHIP IT
LOAD T1,CTIBS,(W) ;GET MAXIMUM BUFFER SIZE
MOVSI T2,LDLBKA## ;BREAK-ON-ALL CHARACTERS BIT
TDNN T2,LDBDCH##(U) ;IF SET,
TXNE T4,CTDRZ ;OR WE'RE BLOCKING THIS READ,
MOVEI T1,1 ;THEN BREAK ON ALL
CALL CCOINT ;SEND AS THIS DRQ'S SIZE
SETZ T1, ;PRE-FILL LENGTH
CALL CCOINT ;END OF DATA IS AT START
LDB T1,LDPTIM## ;SEE IF WE'RE DOING IMAGE MODE
SOSG T1 ;IF WE'RE NOT,
MOVEI T1,1 ;WE STILL WANT TO SEE INPUT EVENTUALLY
TXNE T4,CTDRZ ;UNLESS WE'RE BLOCKING THIS READ,
SETZ T1, ;THEN DON'T UPSET VMS
CALL CCOINT ;SEND TIMEOUT DURATION
SETZRO CTDRZ,(W) ;NO LONGER NEED THIS BIT
SETZ T1, ;OTHER CHARACTER POSITIONS
CALL CCOINT ;WE'RE SENDING NO PROMPT
CALL CCOINT ;NO REDISPLAY POINT
CALL CCOINT ;NO LOW-WATER MARK
TXNE T4,CTBMC ;DID WE WANT TO SEND A BREAK MASK?
MOVEI T1,400/8 ;YES, WE'LL SEND THIS MANY BYTES OF BKM
CALL CCOBYT ;SEND SIZE OF BKM LIST
JUMPE T1,CPOPJ ;DONE IF SENDING NONE
MOVE T3,T1 ;COPY THE LENGTH TO SEND
MOVE T2,[POINT 8,CH.BKM(W)] ;POINT TO BREAK MASK BYTES
SETZRO CTBMC,(W) ;WE'RE SENDING THE MESSAGE NOW
PJRST CCOSTR ;SEND THEM VIA RETURN TO CTHOUT
;CTHOPI - CTERM Send a protocol initiate message
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;ON ERROR
; RETSKP ;SUCCESS (USUALLY VIA NRTOT5)
CTHOPI: MOVEI T1,.CMPIN ;PROTOCOL INIT MESSAGE
CALL CCOST2 ;ENTER INTO A 'COMMON DATA' CARRIER
MOVEI T1,1 ;MAJOR VERSION OF PROTOCOL IS ONE
CALL CFOBYT ;STORE IT
SETZ T1, ;ECO & MOD FIELDS ARE ZERO
CALL CFOINT ;STORE ECO LEVEL & MOD LEVEL
MOVE T2,[POINT 8,CTHREV##] ;POINT TO REVISION STRING IN COMMON
MOVEI T3,8 ;IT'S 8 CHARACTERS LONG
CALL CFOSTR ;STORE THE REVISION STRING
MOVE T2,[POINT 8,CPIMSG] ;POINT TO THE PARAMETERS WE NEED TO SET
MOVEI T3,CPILEN ;WE'RE SENDING THIS MANY MORE BYTES
CALL CFOSTR ;COPY THE BYTES INTO THE MESSAGE
SETONE CTSPI,(W) ;WE'RE SENDING THE PROTOCOL INIT NOW
PJRST CCOFIN ;BIND OFF & SEND THE MESSAGE
;Build our Protocol Initiate parameters
CPI MMS,NRTRIL ;OUR MAXIMUM INPUT MESSAGE SIZE
CPI SUP,MT.SUP ;WE SUPPORT ONLY THE REQUIRED MESSAGES
CPIMSG: BYTSTR (CPI) ;DUMP THE STRING
CPILEN==CPILEN ;PUBLISH THE LENGTH
;CTHORC - CTERM Send a read characteristics messge
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;ON ERROR
; RETSKP ;SUCCESS (USUALLY VIA NRTOT5)
CTHORC: MOVEI T1,.CMRCH ;MESSAGE TYPE TO READ CHARACTERISTICS
CALL CCOST2 ;EMBED IN A 'COMMON DATA' MESSAGE
MOVE T2,[POINT 8,RSCMSG] ;POINT TO THE ACTUAL SELECTOR SEQUENCE
MOVEI T3,RSCLEN ;WE'RE SENDING THIS MANY MORE BYTES
TMNE CTBAD,(W) ;TALKING TO AN ERRANT RTPAD?
SUBI T3,.FTCCA ;YES, DON'T ASK ABOUT TTY QUOTE
CALL CCOSTR ;STORE INTO THE MESSAGE BUFFER
SETONE CTRCS,(W) ;WE'RE SENDING THE READ CHARACTERSTICS NOW
PJRST CCOFIN ;BIND OFF AND SEND MESSAGE
;Build our selectors for Read Characteristics
RSC TTN, ;TTY NAME TYPE
RSC TAM, ;DISPLAY BIT
RSC RAI, ;TTY LC
RSC ECH, ;TTY ECHO
RSC RSP, ;RECEIVE SPEED
RSC TSP, ;TRANSMIT SPEED
RSC CSZ, ;TTY EIGHTBIT
RSC OFC, ;TTY XONOFF
RSC OPS, ;TTY STOP
RSC WID, ;TTY WIDTH
RSC LEN, ;TTY LENGTH
RSC SSZ, ;TTY STOP N
RSC WRP, ;TTY CRLF
RSC HTM, ;TTY TAB
RSC FFM, ;TTY FORM
RSC CAT,"V"-100 ;TTY QUOTE (** MUST BE LAST **)
RSCMSG: BYTSTR (RSC) ;DUMP THE STRING
RSCLEN==RSCLEN ;PUBLISH THE LENGTH
;CTHOSC - CTERM Send the first set characteristics messge
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
;Return:
; RET ;ON ERROR
; RETSKP ;SUCCESS (USUALLY VIA NRTOT5)
CTHOSC: MOVEI T1,.CMCHR ;MESSAGE TYPE TO SET CHARACTERISTICS
CALL CCOST2 ;START UP A 'COMMON DATA' MESSAGE
TMNE CTCTG,(W) ;ARE WE PART-WAY THROUGH HERE?
JRST CTHOS1 ;YES, RESUME WITH STORED CHARACTER
MOVE T2,[POINT 8,CSCMSG] ;POINT TO THE SET CHARACTERISTICS MESSAGE
MOVEI T3,CSCLEN ;WE'RE SENDING THIS MANY MORE BYTES
CALL CFOSTR ;COPY THEM TO THE BUFFER
SETONE CTCTG,(W) ;WE'RE NOW PARTLY DONE
TDZA T3,T3 ;FIRST TIME, START OFF WITH 0 (NUL)
CTHOS1: LOAD T3,CTCHO,(W) ;GET THE CHARACTER WE BROKE OFF WITH
CTHOS2: CAIGE P1,5 ;DO WE HAVE ENOUGH ROOM TO STORE THE STATUS?
JRST CTHOS3 ;NO, MUST BREAK OFF FOR NOW
MOVEI T1,.CCCAT ;YES, GET CHARACTERISTIC PID FOR CHARACTER BITS
CALL CCOINT ;INTRODUCE CHARACTER ATTRIBUTES
MOVE T1,T3 ;COPY THE CHARACTER
CALL CCOBYT ;SETTING STATUS FOR THIS CHARACTER
MOVEI T1,CA.MSK ;SETTING ALL DEFINED BITS TO ZERO
CAIE T3,"Q"-100 ;UNLESS THIS IS XON
CAIN T3,"S"-100 ;OR XOFF,
TRO T1,CA.ENB_8 ;THEN WE ENABLE ITS SPECIAL ACTION
CALL CCOINT ;SEND MASK & BITS
AOS T3 ;BUMP THE CHARACTER
TRNN T3,140 ;IS IT STILL A CONTROL CHARACTER?
JRST CTHOS2 ;YES, SEND ITS STATUS TOO
TMNN CTBAD,(W) ;STOP AFTER 0-37 IF VMS
TRNE T3,CK.PAR ;NO, IS IT A TOP-HALF CHARACTER?
JRST CTHOS4 ;YES, WE'RE DONE
MOVEI T3,177 ;NO, DO RUBOUT AND TOP HALF CONTROLS
JRST CTHOS2 ;LOOP OVER ALL WE CARE ABOUT
CTHOS3: STOR T3,CTCHO,(W) ;SAVE THE CHARACTER WHERE WE LEFT OFF
PJRST CCOFIN ;SEND MESSAGE AND RETURN
CTHOS4: MOVX R,CTCSD!CTCTG ;GET BITS TO CHANGE
XORM R,CT.FLG(W) ;NO MORE CTG, BUT CSD IS ON (WE'RE DONE HERE)
PJRST CCOFIN ;SEND MESSAGE AND RETURN
;Build our initial Characteristics message values
CSC FCP,1 ;GIVE US XON/XOFF
CSC WRP,WP.PHY ;TRACK PRESUMED HARDWARE WRAPPING
CSC HTM,HT.PHY ;TABS ARE LITERAL IF WE SEND THEM
CSC FFM,FF.PHY ;FF IS LITERAL IF WE SEND IT
CSC VTM,VT.PHY ;VT IS ALSO LITERAL
CSC IGN,0 ;ALLOW INPUT
CSC APE,0 ;LEAVE OUT THE STUPID CONTROL-A
CSC CNT,CN.ALL ;ALWAYS SEND US INPUT-STATE MESSAGES
CSC IER,0 ;NO ESCAPE RECOGNITION
CSC OER,0 ;IN EITHER DIRECTION
CSC COP,1 ;SEND US CONTROL-O AS DATA
CSC CPE,0 ;DISABLE PARITY
CSCMSG: BYTSTR (CSC) ;DUMP THE STRING
CSCLEN==CSCLEN ;PUBLISH THE LENGTH
;CCOTTT - CTERM Layer output routine to send a terminal type
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ LDPTTT index to translate and send
;Return:
; RET ;ON SUCCESS
CCOTTT: PUSHJ P,TORTCN## ;GET THE CLASS NAME
CALL CCOSIX ;SEND IT IN ASCIC FORMAT
HAK <DIS,WID,LNB,LCT,8BT,ECH,XNF> ;BE SURE WE SEND THESE
RET ;RETURN TO CTHONC
;CCOSIX - CTERM Layer output routine to send a SIXBIT string in ASCIC
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ The SIXBIT word to be sent
;Return:
; RET ;ON SUCCESS
;
;Uses:
; T1-T4
;ASCIC format is the following:
; First byte: N (the length of the actual string)
; Next N bytes: ascii character (the string, from left to right)
; Total is N+1 bytes.
CCOSIX: JUMPE T1,CCOBYT ;ZERO BYTES IF BLANK NAME
MOVE T4,T1 ;NOT SO SIMPLE. SAVE THE NAME
MOVNS T1 ;GET ITS NEGATIVE
AND T1,T4 ;GET THE RIGHTMOST BIT
JFFO T1,.+1 ;GET ITS BIT NUMBER
IDIVI T2,6 ;GET WHICH BYTE IT OCCURS IN (0-5)
MOVEI T1,1(T2) ;GET TOTAL NUMBER OF BYTES TO SEND
CALL CCOBYT ;SEND LENGTH BYTE OF ASCIC
MOVE T2,T4 ;COPY NAME TO FRIENDLIER AC
CCOSX1: SETZ T1, ;CLEAR OLD CRUFT
LSHC T1,6 ;GET NEXT BYTE TO SEND
ADDI T1,"A"-'A' ;CONVERT TO ASCII FROM SIXBIT
CALL CCOBYT ;SEND THE NEXT CHARACTER
JUMPN T2,CCOSX1 ;LOOP OVER ALL CHARACTERS IN WORD
RET ;RETURN WHEN DONE
;CCODIS - CTERM Layer output routine to send the display characteristic
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ The value of LDPDIS to be sent
;Return:
; RET ;ON SUCCESS
CCODIS: LSH T1,1 ;THE BIT IS OFFSET BY ONE
.CREF TA%DIS ;NOTE WHAT WE'RE SETTING
LDB T2,LDPTTT## ;GET THE TTY TYPE
SKIPE T2 ;IF WE KNOW THIS TTY TYPE,
TRO T1,TA%KNO ;THEN ADMIT IT
PJRST CCOINT ;TERMINAL ATTRIBUTES IS TWO BYTES
.CREF FT.TAM ;PROVE THAT WE KNOW IT
;CFOBYT - Foundation output routine to send a byte
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ Data byte to send
;Return:
; RET ;ON SUCCESS
;
; It is the caller's responsibility to ensure that there is enough room
; in the output record. We will stopcode if there is not.
CCOIVB: TRC T1,1 ;SEND INVERTED BYTE
CCOBYT:!
CFOBYT: SOSGE P1 ;IS THERE ENOUGH ROOM?
STOPCD .,STOP,CTHOCE, ;++OUTPUT COUNT EXCEEDED
IDPB T1,P2 ;YES, STORE IT AWAY
RET ;DONE
;CFOSTR - Foundation output routine to send a string of N bytes
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T2/ Byte pointer to string to send
; T3/ Count of bytes in message
;Return:
; RET ;ON SUCCESS
;
; It is the caller's responsibility to ensure that there is enough room
; in the output record. We will stopcode if there is not.
CCOSTR:!
CFOSTR: SOSGE T3 ;MORE BYTES TO SEND?
RET ;NO, WE'RE DONE
ILDB T1,T2 ;YES, FETCH THE NEXT
CALL CFOBYT ;SEND IT OUT
JRST CFOSTR ;LOOP OVER THE STRING
;CFOINT - Foundation output routine to send a network integer
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ Data word to send
;Return:
; RET ;ON SUCCESS
;
; It is the caller's responsibility to ensure that there is enough room
; in the output record. We will stopcode if there is not.
CCO8BT: ADDI T1,7 ;CONVERT TO CHARACTER FRAME SIZE
CCOINT:!
CFOINT: CALL CFOBYT ;SEND THE LOW-ORDER PART FIRST
ROT T1,-8 ;THE HIGH-ORDER PART COMES NEXT
CALL CFOBYT ;SEND THAT
ROT T1,8 ;PUT THE WORD BACK THE WAY WE GOT IT
RET ;DONE
;CCOSET - CTERM layer output setup (common data Foundation message)
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Maximum byte count for storing via P2
; P2/ Byte pointer (8-bit) to NRTRCO
; T1/ CTERM message type
;Return:
; RET ;ALWAYS
CCOST2: SKIPA T2,[CCOINT] ;USE INT IF GUARANTEED ZERO-FILL
CCOSET: MOVEI T2,CCOBYT ;BYTE MODE IF THERE COULD BE FLAGS
PUSH P,T1 ;SAVE CTERM TYPE
MOVEI T1,.FMCMD ;COMMON DATA FOUNDATION TYPE
CALL CFOINT ;STORE TYPE & ZERO FILL
MOVEM P2,CTHCDP ;SAVE THE POINTER FOR LATER LENGTH STORAGE
SETZ T1, ;CURRENT LENGTH IS ZERO
CALL CFOINT ;MAKE ROOM FOR ACTUAL LENGTH TO BE STORED LATER
MOVEM P1,CTHCDL ;SAVE THE REMAINING BYTE COUNT FOR CCOFIN
POP P,T1 ;RETRIEVE THE CTERM MESSAGE TYPE
CALL (T2) ;SET THE TYPE
MOVEM P2,CTHBUL ;BACK-UP LIMIT FOR CCOFIN NOT TO SEND AFTER ALL
RET ;RETURN WITH MESSAGE ALL SET UP
;CCOFIN - CTERM layer output sender (end of CCOSET)
;
;Call:
; W/ Pointer to Link's CTB
; U/ Points to LDB
; P1/ Remaining byte count for storing via P2
; P2/ Byte pointer (8-bit) into NRTRCO
;Return:
; via NRTOT5
;
;This routine inserts the actual length into the sub-message block
; of the Foundation's common data message, and then sends the message out.
CCOFIN: CAMN P2,CTHBUL ;SHOULD WE BOTHER SENDING IT?
PJRST NRTOT1 ;NO, JUST CLAIM SUCCESS
CCOFN2: MOVE P2,CTHCDP ;RETRIEVE POINTER TO LENGTH FIELD
MOVE T1,CTHCDL ;AND STARTING FREE BYTE COUNT
SUB T1,P1 ;FIND ACTUAL SUB-MESSAGE LENGTH
ADDI P1,2 ;WE REALLY ALREADY STORED THESE TWO BYTES
CALL CFOINT ;UPDATE THE LENGTH
PJRST NRTOT5 ;SEND THE MESSAGE AND RETURN
;NRTIN - Try to do some input from DECnet to SCNSER
;
;Call, when DECnet has something for us to read:
; W/ Pointer to Link's NRB
; U/ Points to LDB
;Return:
; RET ;IF FATAL ERROR
; RETSKP ;SUCCESS
NRTIN: TMNN NRCFG,(W) ;HAVE WE SENT A CONFIG MSG YET?
RET ;NO, DON'T ACCEPT INPUT YET
SAVEAC <P1,P2> ;YES, PRESERVE OUR BYTE POINTER & COUNT ACS
NRTIN1: MOVE R,NR.FLG(W) ;GET FLAGS
TXNN R,NRCTM ;IF A NRT LINK,
TXNN R,NRXOF ;MAKE SURE SCNSER WANTS SOME CHARACTERS
TRNA ;CTERM OR NOT XOFF'ED, GO AHEAD
RETSKP ;NRT AND XOFF'ED, QUIT WHILE WE'RE AHEAD
MOVE M,NRTSAP ;POINT TO NRT'S SAB
MOVEI T1,NRTRIL ;GET MAX CHARS WE'LL ALLOW AT ONCE
STOR T1,SAAA1,(M) ;STORE LENGTH OF DATA TO SEND
MOVX T1,<<POINT 8,>!1B12> ;MAKE A 2-WORD BYTE POINTER
STOR T1,SAAA2,(M) ;STORE AS FIRST WORD OF BYTE POINTER
XMOVEI T1,NRTRCI ;GET EXTENDED ADDR OF INPUT RECORD
STOR T1,SAAA3,(M) ;STORE AS 2ND WORD OF BYTE POINTER
SETZRO SAEOM,(M) ;DON'T INSIST ON A WHOLE RECORD
MOVX T1,.NSFDR ;DATA RECEIVE FUNCTION
MOVEI T2,5 ;NUMBER ARGS WE'RE PASSING
CALL NRTNSF ;GET DATA FROM DECnet
JRST NRTINE ;ERROR, GO DEAL WITH IT
;Now we have some data, give it to SCNSER
MOVE P1,[POINT 8,NRTRCI] ;GET BYTE POINTER TO NRT'S RECORD
MOVEI P2,NRTRIL ;GET MAX WE SAID WE'D READ
OPSTR <SUB P2,>,SAAA1,(M) ;CALC # OF CHARS WE GOT
JUMPE P2,NRTIN3 ;NONE?
TMNE NRCTM,(W) ;IS THIS A CTERM LINK?
JRST CTHIN ;YES, USE OTHER PROTOCOL
NRTIN2: ILDB T3,P1 ;GET NEXT CHARACTER FROM DECnet
CALL RECPTY## ;GIVE THE CHAR TO SCNSER
SOJG P2,NRTIN2 ;LOOP UNTIL ALL PASSED TO SCNSER
;CTERM protocol will merge here for more data
NRTIN3: LOAD U,NRLDB,(W) ;RESTORE LDB POINTER TO U
LOAD T1,NRSTS,(W) ;GET DECnet STATUS AFTER LAST SEND
TXNE T1,NSNDA ;NORMAL DATA STILL AVAILABLE?
JRST NRTIN1 ;YES, GO GET IT
RETSKP ;NO, SUCCESS RETURN NOW
;Here on DECnet error
NRTINE: LOAD T1,SAAST,(M) ;GET NEW STATUS
LOAD T1,NSSTA,+T1 ;GET THE STATE FIELD FROM STATUS
CAIN T1,.NSSRN ;IN RUN STATE?
BUG. CHK,NRTINP,NRTSER,SOFT,<NRT Input to DECnet failed>,,<
Cause: This BUG is not documented yet.
>,NRTREL
RET ;DON'T COMPLAIN NOW, ITS CLOSING
;CTHIN - Try to read some CTERM messages from DECnet
;
;Call, when DECnet has something for us to read:
; W/ Pointer to Link's NRB
; U/ Points to LDB
; P1/ Byte pointer to input record
; P2/ Byte count for reading from P1
;Return:
; RET ;IF FATAL ERROR
; RETSKP ;SUCCESS
CTHIN: TMNE CTRLS,(W) ;PROTOCOL ERROR SEEN?
JRST NRTIN3 ;YES, JUST FLUSH THE BUFFER
OPSTR <SKIPE T1,>,CTIFL,(W) ;DO WE HAVE ANY BUFFERED BYTES?
MOVE T1,[POINT 8,CT.IFM(W)] ;YES, GET BYTE POINTER
MOVEM T1,CTHIFP ;STORE POINTER OR ZERO AS APPROPRIATE
CTHIN1: LOAD T1,CTIFT,(W) ;GET PAST INPUT FOUNDATION TYPE
JUMPN T1,CTHIN2 ;ONE IN PROGRESS, RE-DISPATCH IT
CALL CFIBYT ;GET THE MESSAGE-TYPE BYTE
JRST NRTIN3 ;DONE HERE IF NONE
CAILE T1,0 ;IS IT IN THE RANGE
CAILE T1,.FMMDD ;OF VALID FOUNDATION MESSAGE TYPES?
JRST CTHINE ;NO, DEAL WITH PROTOCOL ERROR
STOR T1,CTIFT,(W) ;YES, STORE IT
CTHIN2: CALL @CTHIFM(T1) ;YES, CALL ITS HANDLER
JRST CTHINE ;NON-SKIP MEANS PROTOCOL ERROR SEEN
JRST NRTIN3 ;MESSAGE OK, TRY FOR NEXT
CTHINE: STOPCD .,INFO,CTHPED,DIEBCM ;++PROTOCOL ERROR DETECTED
SETONE CTRLS,(W) ;LIGHT BIT TELLING CTHOUT TO UNBIND
MOVEI T1,.UBPED ;PROTOCOL ERROR UNBIND REASON
STOR T1,CTUBR,(W) ;STORE FOR CTHOUT'S UNBIND MESSAGE
JRST NRTIN3 ;FLUSH THE BUFFER ON PROTOCOL ERRORS
;CTERM foundation layer input messages dispatch table
CTHIFM: IFIW CPOPJ## ;(0) ILLEGAL MESSAGE TYPE
IFIW CPOPJ## ;(1) BIND-REQUEST (ILLEGAL)
IFIW CTIFUB ;(2) UNBIND REQUEST
IFIW CPOPJ## ;(3) REBIND REQUEST (ILLEGAL)
IFIW CTIFBA ;(4) BIND-ACCEPT MESSAGE
IFIW CPOPJ## ;(5) ENTER MODE (ILLEGAL)
IFIW CPOPJ## ;(6) EXIT MODE (ILLEGAL)
IFIW CPOPJ## ;(7) CONFIRM MODE (ILLEGAL)
IFIW CPOPJ## ;(10) NO MODE (ILLEGAL)
IFIW CTIFCD ;(11) COMMON DATA
IFIW CPOPJ## ;(12) MODE DATA (ILLEGAL)
;Note that the 'mode' messages are illegal because we never send an
;enter-mode message.
;CTIFUB - CTERM Foundation input routine for Unbind requests
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;ALWAYS
CTIFUB: MOVEI T1,2 ;WE NEED TWO ADDITIONAL BYTES
CALL CFICHK ;CALL THE INPUT BUFFER CHECKER
JRST CFIRET ;FAILED, RETURN DEPENDS ON EOM FLAG
CALL CFIINT ;GET A NETWORK (2-BYTE) INTEGER
RET ;COULD STOPCODE HERE, SINCE JUST CHECKED
CAIN T1,.UBPED ;REMOTE COMPLAIN THAT WE SCREWED UP?
STOPCD .,INFO,CTHPER,DIEBCM ;++PROTOCOL ERROR REPORTED
SETONE CTREL,(W) ;NOTE THAT WE WANT TO RELEASE THIS CHANNEL
PJRST CFIFIN ;SUCCESSFUL END OF FUNCTION
;CTIFBA - CTERM Foundation input routine for Bind Accept
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;ALWAYS
CTIFBA: TMNE CTBND,(W) ;BETTER GET THIS ONLY ONCE
RET ;PROTOCOL ERROR IF TWICE
MOVEI T1,^D16 ;WE NEED SEVERAL ADDITIONAL BYTES
CALL CFICHK ;SEE IF WE CAN GET THE MESSAGE
JRST CFIRET ;RETURN DEPENDING ON EOM
MOVEI T1,3 ;THREE BYTES OF VERSION
CALL CFISKP ;SKIP OVER THEM
RET ;COULD STOPCODE, SINCE CHECKED
CALL CFIINT ;GET THE O/S TYPE
RET ;MAYBE STOPCODE?
STOR T1,CTROS,(W) ;SAVE FOR DEBUGGERS
MOVX R,CTBAD ;GET THE BAD-BOYS BIT
CAIN T1,O.VMS ;IF VMS,
IORM R,CT.BAD(W) ;REMEMBER THE SUB-STANDARD ALTERNATE PROTOCOL
MOVEI T1,^D8 ;BYTES UNTIL LINE NUMBER
CALL CFISKP ;SKIP OVER THAT MANY BYTES (WE DON'T CARE)
RET ;COULD STOPCODE, SINCE JUST CHECKED
CALL CFIINT ;GET THE REMOTE'S LINE NUMBER
TRNA ;MAYBE STOPCODE?
TRNE T1,SGNBIT ;NEGATIVE?
SETO T1, ;YES, FLAG AS UNKNOWN
STOR T1,CTRLN,(W) ;SAVE FOR NETOP. UUO
CALL CFIBYT ;SKIP OPTIONS TYPE (RESERVED)
RET ;MAYBE STOPCODE?
SETONE CTBND,(W) ;FLAG THAT FOUNDATION IS RUNNING
CALL TOPOKE## ;WAKE UP OUR OUTPUT PROCESS
PJRST CFIFIN ;SUCCESSFUL END OF FUNCTION
;CTIFCD - CTERM Foundation input routine for Common Data (actual CTERM layer)
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;ALWAYS
CTIFCD: CALL CCIJNK ;SKIP ANY JUNK BYTES THERE MAY BE
RET ;SOMEBODY BLEW IT
RETSKP ;DEFER
LOAD T1,CTIMT,(W) ;GET DATA TYPE IN PROGRESS
JUMPN T1,CTIFC3 ;RE-START SUB-MESSAGE IF APPLICABLE
TMNE CTIML,(W) ;DO WE HAVE A SUB-MESSAGE LENGTH?
JRST CTIFC2 ;YES, TRY AGAIN FOR ITS TYPE
TMNE CTMI0,(W) ;IS THIS REALLY THE START OF THE DATA MESSAGE?
JRST CTIFC1 ;NO, GET NEXT SUB-MESSAGE
MOVEI T1,1 ;WE NEED A FILL BYTE
CALL CFICHK ;SEE IF WE CAN GET THE MESSAGE
JRST CFIRET ;RETURN DEPENDING ON EOM
CALL CFIBYT ;GET ONE BYTE
RET ;BUT I JUST CHECKED...
SETONE CTMI0,(W) ;REMEMBER THAT WE'VE SKIPPED THE FILL BYTE
CTIFC1: CALL CFICK0 ;SEE IF AT END OF MESSAGE
JRST CTIFC4 ;YES, FINISH UP
MOVEI T1,2 ;NO, I NEED TWO BYTES FOR THIS MESSAGE TYPE
CALL CFICHK ;CAN I GET THEM?
JRST CFIRET ;NO.
CALL CFIINT ;GET A NETWORK INTEGER (16-BIT)
RET ;SHOULDN'T FAIL
JUMPE T1,CTIFC1 ;TRY AGAIN IF THIS SUB-MESSAGE IS NULL
STOR T1,CTIML,(W) ;SETUP LENGTH FOR CCI INPUT ROUTINES
CTIFC2: CALL CCIBYT ;GET THE MESSAGE TYPE (COUNTING THE BYTE)
RET ;THE BYTE WENT AWAY?!?
RETSKP ;DEFER IF WE MUST
CAILE T1,0 ;IS IT IN RANGE
CAILE T1,.CMIST ;FOR THE CTERM MESSAGES WE SUPPORT?
RET ;NO, RETURN A PROTOCOL ERROR
STOR T1,CTIMT,(W) ;NOTE THE FUNCTION IN PROGRESS
CTIFC3: CALL @CTIFCT(T1) ;CALL THE APPROPRIATE MESSAGE HANDLER
RET ;PROPAGATE PROTOCOL ERRORS
RETSKP ;AND DELAYS
SETZRO CTIMT,(W) ;CLEAR SUB-TYPE IN PROGRESS
JRST CTIFC1 ;LOOP FOR NEXT MESSAGE
CTIFC4: SETZRO CTMI0,(W) ;NEXT TIME WE MUST SKIP THE FILL BYTE
PJRST CFIFIN ;SUCCESSFUL END OF FUNCTION
;The dispatch table for the supported CTERM layer functions
CTIFCT: IFIW CPOPJ## ;(0) TYPE ZERO IS ILLEGAL
IFIW CTICIM ;(1) INITIALIZE CTERM MODE
IFIW CPOPJ## ;(2) START READ (SEND ONLY)
IFIW CTICRD ;(3) READ DATA
IFIW CTICOB ;(4) OUT-OF-BAND CHARACTER
IFIW CPOPJ## ;(5) UNREAD (SEND ONLY)
IFIW CPOPJ## ;(6) CLEAR TYPEAHEAD (SEND ONLY)
IFIW CPOPJ## ;(7) WRITE DATA (SEND ONLY)
IFIW CTICWC ;(10) WRITE COMPLETE
IFIW CTICDS ;(11) DISCARD STATE (^O)
IFIW CPOPJ## ;(12) READ CHARACTERISTICS (SEND ONLY)
IFIW CTICCM ;(13) CHARACTERISTICS MESSAGE
IFIW CPOPJ## ;(14) READ COUNT CHECK (SEND ONLY)
IFIW CTICIC ;(15) INPUT COUNT
IFIW CTICIS ;(16) INPUT STATE TRANSITION
;CTICIM - CTERM layer input message to initialize the CTERM layer
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICIM: TMNE CTRPI,(W) ;IS THIS THE FIRST ONE?
RET ;PROTOCOL ERROR IF TWICE
TMNE CTMI1,(W) ;HAVE WE SKIPPED OUR CRUFT YET?
JRST CTICI1 ;YES, DON'T SKIP IT AGAIN
MOVEI T1,^D12 ;NO. WE NEED 12 BYTES OF VERSION STRING & FILL
CALL CCISKP ;TRY TO GET PAST IT
RET ;ERROR
RETSKP ;MUST DEFER
SETONE CTMI1,(W) ;NOTE THAT WE SKIPPED IT
MOVEI T1,NRTRIL-12 ;GET OUR MAXIMUM INPUT BUFFER SIZE
STOR T1,CTIBS,(W) ;SAVE IN CASE REMOTE DOESN'T SET IT
CTICI1: CALL CCIJNK ;SKIP OVER JUNK BYTES (IF ANY)
RET ;ERROR
RETSKP ;MUST DEFER
CTICI2: TMNN CTIML,(W) ;ANYTHING MORE TO READ?
JRST CTICIF ;NO, EXIT THE SUB-MESSAGE
MOVEI T1,2 ;TO BE LEGAL, ANY PARAMETER MUST HAVE TWO BYTES
CALL CCICHK ;SEE IF I CAN READ THEM
RET ;ERROR
RETSKP ;DEFER
MOVEI T1,4 ;I'D PREFER TO SEE 4, HOWEVER
CALL CCICHK ;CAN I GET THEM?
TRNA ;OK IF TOO SHORT
RETSKP ;WAIT IF THEY'RE POSSIBLE
CALL CCIBYT ;YES, GET THE PARAMETER TYPE INDEX
RET ;ERROR
RET ;STILL AN ERROR
JUMPE T1,CPOPJ## ;TYPE ZERO IS ILLEGAL
MOVE T4,T1 ;COPY THE PARAMETER BYTE
CALL CCIBYT ;GET THE VALUE LENGTH BYTE
RET ;ERROR
RET ;STILL AN ERROR
MOVE T3,T1 ;COPY THAT, TOO
CALL CCICHK ;CAN WE GET THAT MANY?
RET ;NO
JFCL ;DON'T DEFER (YET)
CAILE T4,3 ;DO WE KNOW ABOUT THIS PARAMETER?
JRST CCIIM0 ;NO, JUST SKIP IT
JRST @.(T4) ;YES, DISPATCH
IFIW CCIIM1 ;(1) MAXIMUM MESSAGE SIZE ALLOWABLE
IFIW CCIIM2 ;(2) MAXIMUM INPUT BUFFER SIZE ALLOWABLE
IFIW CCIIM3 ;(3) MESSAGE TYPES SUPPORTED
CCIIM0: STOR T3,CTMIJ,(W) ;CLAIM THAT THE MESSAGE IS JUNK
JRST CTICI1 ;AND SKIP OVER IT
CCIIM1: CAILE T3,2 ;DOES IT LOOK LIKE THE SIZE MEANS ANYTHING?
JRST CCIIM0 ;NO, DON'T BOTHER WITH IT
XMOVEI T1,CCIBYT ;ASSUME THE SIZE IS A BYTE
CAIL T3,2 ;IS IT?
XMOVEI T1,CCIINT ;NO, GRAB AN INTEGER
CALL (T1) ;READ THE VALUE IN QUESTION
RET ;CAN'T DO IT
RET ;I ALREADY CHECKED FOR FOUR
CAIGE T1,SRVMMS ;WITHIN MINIMUM (FROM THE SPEC)?
RET ;NO, GIVE UP
LOAD T2,CTSIZ,(W) ;YES, GET OUR MAXIMUM TO SEND
CAMGE T1,T2 ;DOES IT FIT?
STOR T1,CTSIZ,(W) ;NO, LIMIT OURSELVES
JRST CTICI2 ;CHECK FOR NEXT PARAMETER
CCIIM2: CAILE T3,2 ;DOES IT LOOK LIKE THE SIZE WILL MATTER TO US?
JRST CCIIM0 ;NO, SO SKIP IT
XMOVEI T1,CCIBYT ;ASSUME A 1-BYTE SIZE
CAIL T3,2 ;VALID ASSUMPTION?
XMOVEI T1,CCIINT ;NO, IT'S 2 BYTES
CALL (T1) ;GET THE VALUE
RET ;ERROR
RET ;STILL AN ERROR
CAIGE T1,MINIBS ;WITHIN REQUIREMENTS OF THE SPEC?
RET ;ERROR IF NOT
CAIGE T1,NRTRIL-12 ;WITHIN OUR MAXIMUM?
STOR T1,CTIBS,(W) ;YES, REMEMBER IT
JRST CTICI2 ;CHECK FOR NEXT PARAMETER
CCIIM3: CAIGE T3,2 ;DO WE HAVE ENOUGH BYTES?
RET ;DOESN'T SUPPORT ENOUGH, IT'S AN ERROR
SUBI T3,2 ;YES, OFFSET BY HOW MANY WE'LL READ
STOR T3,CTMIJ,(W) ;ANY OTHERS ARE JUNK
CALL CCIINT ;READ THE BYTES WE CARE ABOUT
RET ;ERROR IF CAN'T
RET ;I ALREADY CHECKED FOR FOUR
ANDI T1,MT.SUP ;MASK DOWN TO THE MESSAGE TYPES WE CARE ABOUT
CAIE T1,MT.SUP ;ARE THEY ALL SUPPORTED?
STOPCD .,EVENT,CTHBCM,DIEBCM ;++BAD CONFIGURATION MESSAGE
JRST CTICI1 ;YES, SKIP ANY POSSIBLE JUNK BYTES
CTICIF: SETONE CTRPI,(W) ;WE HAVE RECEIVED A VALID PROTOCOL INIT
CALL SETCHP## ;WAKE UP OUTPUT PROCESS
PJRST CCIFIN ;SUCCESSFUL END OF FUNCTION
DIEBCM: PUSHJ P,INLMES## ;TYPE SOME INFO
ASCIZ \ Node \
MOVE T1,W ;COPY CTB POINTER
PUSHJ P,NRTNFC ;GET NODE FROM CTB/NRB
PJRST PRNODE ;TYPE THE NODE SPEC
;CTICRD - CTERM layer input message to accept read data
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICRD: TMNE CTMI1,(W) ;HAVE WE READ OUR OVERHEAD BYTES YET?
JRST CTICR1 ;YES, DON'T OVERWRITE OUR HEADER INFO
MOVEI T1,7 ;NO, I NEED 7 BYTES OF ONE-TIME DATA
CALL CCICHK ;CAN I GET THEM?
RET ;PROTOCOL ERROR
RETSKP ;MUST WAIT
CALL CCIBYT ;GET FLAGS BYTE
RET ;ERROR
RET ;STILL AN ERROR
ANDI T1,RD.IIP!RD.TRM ;KEEP ONLY RELEVANT BITS
MOVE T4,T1 ;SAVE FOR LATER CHECK
MOVEI T1,4 ;FOUR ARE JUST JUNK TO ME
CALL CCISKP ;SO TRY NOT TO READ THEM
RET ;ERROR
RET ;STILL AN ERROR
CALL CCIINT ;NOW GET THE NUMBER OF PRE-TERMINATOR CHARACTERS
RET ;ERROR
RET ;STILL AN ERROR
OPSTR <CAMLE T1,>,CTIML,(W) ;DO WE HAVE THAT MANY TO READ?
RET ;PROTOCOL ERROR IF NOT
MOVX R,CTECH ;DRQ-IS-ECHOING BIT
TDNN R,CT.ECH(W) ;IS IT?
TDZA T1,T1 ;NO, FORGET ABOUT PRE-TERMINATOR COUNT
ANDCAM R,CT.ECH(W) ;YES, BUT NOT ANY MORE
STOR T1,CTMW1,(W) ;SAVE THE COUNT FOR CK.FDE FLAGGING
SETONE CTMI1,(W) ;WE HAVE READ OUR HEADER
CAIN T4,.RDTMO ;IF READ TIMED OUT,
SKIPE CT.IML(W) ;AND THERE ARE NO CHARACTERS AT ALL,
JRST CTICR1 ;NO OR NO, FORGET THIS
SETONE CTDRZ,(W) ;YES, REMEMBER THE NULL DRQ
CTICR1: CALL CCIBYT ;TRY TO GET A CHARACTER TO STORE
JRST CTICR2 ;DONE IF NO MORE CHARACTERS
RETSKP ;DEFER IF WE MUST
MOVE T3,T1 ;PUT CHARACTER WHERE SCNSER WANTS IT
OPSTRM <SOSL>,CTMW1,(W) ;TERMINATORS DON'T ECHO
TRO T3,CK.FDE ;FRONT-END DID THE ECHO
MOVX R,CTCIB!CTDRI ;GET BITS SAYING NOT TO STORE
TDNN R,CT.FLM(W) ;DON'T STORE IF THIS IS AN INVALID DRQ
CALL RECPTY## ;STUFF IT INTO THE INPUT CHUNKS
JRST CTICR1 ;LOOP FOR AS MANY CHARACTERS AS WE CAN
CTICR2: SETZRO CTDRI,(W) ;OK, THE NEXT DRQ WILL BE VALID
MOVX R,CTDRQ!CTURA ;AND WE DON'T HAVE ONE OUTSTANDING
ANDCAM R,CT.FLG(W) ;AND ANY PENDING UNREAD IS COMPLETE
PJRST CCIFIN ;SUCCESSFUL END OF COMMON-DATA
;CTICOB - CTERM layer input message to accept an out-of-band character
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICOB: MOVEI T1,2 ;TWO DATA BYTES FOR THIS MESSAGE
CALL CCICHK ;DO I HAVE THEM?
RET ;PROTOCOL ERROR
RETSKP ;MUST WAIT FOR THEM
CALL CCIBYT ;GET FLAGS BYTE
RET ;ERROR
RET ;STILL AN ERROR
TRNE T1,OB.DIS ;SHOULD WE BE SUPPRESSING?
CALL STCTRO## ;YES, NOTIFY SCNSER
CALL CCIBYT ;GET THE CHARACTER IN QUESTION
RET ;ERROR
RET ;STILL ERROR
MOVE T3,T1 ;MOVE IT TO CHARACTER AC
CALL RECPTY## ;FEED IT TO SCNSER
JRST CCIFIN ;DONE
;CTICWC - CTERM layer input message to accept a write completion notice
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICWC: MOVEI T1,5 ;FIVE DATA BYTES FOR THIS MESSAGE
CALL CCISKP ;CAN I EAT THEM?
RET ;PROTOCOL ERROR
RETSKP ;MUST WAIT FOR THEM
;Add code here to notify SCNSER as soon as we implement the DOBE function
JRST CCIFIN ;DONE
;CTICDS - CTERM layer input message to accept a new discard state
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICDS: CALL CCIBYT ;READ THE SINGLE DATA BYTE
RET ;PROTOCOL ERROR
RETSKP ;WAIT FOR IT
XMOVEI T2,NOCTRO## ;ASSUME ENABLING OUTPUT
TRNN T1,DS.CDS ;BIT IS BACKWARDS
XMOVEI T2,STCTRO## ;NO, DISABLING
CALL (T2) ;INFORM SCNSER
JRST CCIFIN ;DONE
;CTICCM - CTERM layer input message to accept a characteristics message
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICCM: TMNE CTMI1,(W) ;DID WE EAT THE HEADER YET?
JRST CTICC1 ;YES, DON'T DO IT AGAIN
CALL CCIBYT ;TRY TO EAT IT
RET ;PROTOCOL ERROR
RETSKP ;WAIT FOR IT
SETONE CTMI1,(W) ;OK, WE ATE IT
MOVEI T1,1 ;DEFAULT TTY QUOTE ON FOR RTPAD
DPB T1,LDPQOT## ;JUST IN CASE
CTICC1: LOAD T1,CTMW1,(W) ;DO WE HAVE A CHARACTERISTIC IN PROGRESS?
JUMPN T1,CTICC2 ;IF SO, TRY IT AGAIN
CTICC4: MOVEI T1,2 ;NO, NEED TWO BYTES
CALL CCICHK ;CAN WE HAVE THEM?
JRST CTICC5 ;WE'RE DONE
RETSKP ;MUST WAIT FOR THEM
CALL CCIINT ;GET THE IDENTIFIER
RET ;ERROR
RET ;STILL AN ERROR
STOR T1,CTMW1,(W) ;STORE THE WORD FOR LATER
CTICC2: LSHC T1,-8 ;SPLIT INTO MAJOR & MINOR TYPES
LSH T2,-^D<36-8> ;POSITION BOTTOM TO WHERE IT BELONGS
CAILE T1,.CTCMH ;IS THE MAJOR TYPE ONE WE UNDERSTAND?
RET ;NO, SO WE DIDN'T ASK
JRST @.+1(T1) ;YES, DISPATCH ON IT
IFIW CCICMP ;(0) PHYSICAL FOUNDATION VALUES
IFIW CCICML ;(1) LOGICAL FOUNDATION VALUES
IFIW CCICMC ;(2) CTERM HANDLER VALUES
CTICC3: SETZRO CTMW1,(W) ;DONE WITH CURRENT CHARACTERISTIC
JRST CTICC4 ;TRY FOR ANOTHER
CTICC5: CALL SETCHP## ;START UP OUR OUTPUT SIDE
SETONE CTCHP,(W) ;WE HAVE RECEIVED A CHARACTERISTICS MESSAGE
TMNE CTBAD,(W) ;IS THIS VMS?
CALL CCIBYT ;YES, ALLOW RTPAD ITS TRASH
JRST CCIFIN ;NO, FINISH UP AND RETURN
RETSKP ;YES, BUT WE HAVE TO WAIT FOR THE GARBAGE
JRST CCIFIN ;YES, AND WE GOT ITS JUNK BYTE, GO FINISH UP
CCICMP: CAILE T2,0 ;IS THE SUB-TYPE
CAILE T2,.CMXFP&BYTMSK ;IN RANGE OF 'PHYSICAL' VALUES WE KNOW?
RET ;NO, SO WE DIDN'T ASK
JRST @.(T2) ;YES, SO DISPATCH ON IT
IFIW CCMPRS ;(1) RECEIVE SPEED
IFIW CCMPXS ;(2) TRANSMIT SPEED
IFIW CCMPCS ;(3) CHARACTER SIZE
IFIW CCMPPE ;(4) PARITY ENABLE
IFIW CCMPPT ;(5) PARITY TYPE
IFIW CCMPMP ;(6) MODEM PRESENT (DATASET)
IFIW CCMPAB ;(7) AUTO-BAUD
IFIW CCMPMG ;(10) MANAGEMENT GUARANTEED
IFIW CCMPS1 ;(11) SWITCH-CHARACTER ONE
IFIW CCMPS2 ;(12) SWITCH-CHARACTER TWO
IFIW CCMP8C ;(13) EIGHT-BIT
IFIW CCMPME ;(14) MANAGEMENT-ENABLED
CCMPMP==CPOPJ## ;I DIDN'T ASK
CCMPAB==CPOPJ## ;I DIDN'T ASK
CCMPMG==CPOPJ## ;I DIDN'T ASK
CCMPS1==CPOPJ## ;I DIDN'T ASK
CCMPS2==CPOPJ## ;I DIDN'T ASK
CCMPME==CPOPJ## ;I DIDN'T ASK
CCMPPE==CPOPJ## ;I DIDN'T ASK
CCMPPT==CPOPJ## ;I DIDN'T ASK
CCMP8C==CPOPJ## ;I DIDN'T ASK
CCMPRS: CALL CCIINT ;GET THE BAUD RATE
RET ;NEVER MIND
RETSKP ;WAIT FOR IT
CALL CCMPSX ;CONVERT TO A -10 SPEED INDEX
DPB T2,LDPRSP## ;YES, STORE IN SCNSER
JRST CTICC3 ;LOOP FOR NEXT PARAMETER
CCMPXS: CALL CCIINT ;GET THE BAUD RATE
RET ;NEVER MIND
RETSKP ;WAIT FOR IT
CALL CCMPSX ;CONVERT TO A -10 SPEED INDEX
DPB T2,LDPTSP## ;YES, STORE IN SCNSER
JRST CTICC3 ;LOOP FOR NEXT PARAMETER
CCMPSX: MOVSI T2,-CCMPSL ;GET AOBJN POINTER TO SPEED TABLE
CAME T1,CCMPST(T2) ;DOES THE SPEED MATCH?
AOBJN T2,.-1 ;NO, LOOK AGAIN
HRRZS T2 ;ISOLATE SPEED INDEX
RET ;PASS BACK THIS VALUE
CCMPST: DEC 0,50,75,110,135,150,200,300,600,1200,1800,2400
DEC 4800,9600,19200
CCMPSL==.-CCMPST
CCMPCS: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;WAIT FOR IT
CAIE T1,8 ;REMOTE HANDLING 8-BIT MODE?
TDZA T1,T1 ;NO, ASSUME 7-BIT
MOVEI T1,1 ;YES, LIGHT THE FLAG
DPB T1,LDP8BT## ;SET IT
STOR T1,CH8BT,(W) ;KEEP OUR OWN COPY
JRST CTICC3 ;LOOP FOR NEXT PARAMETER
CCICML: CAILE T2,0 ;IS IT IN RANGE OF THE LOGICAL
CAILE T2,.CMXFL&BYTMSK ;PARAMETERS WE KNOW ABOUT?
RET ;NO, SO WE DIDN'T ASK
JRST @.(T2) ;YES, SO DISPATCH ON IT
IFIW CCMLMW ;(1) MODE WRITING ALLOWED
IFIW CCMLTA ;(2) TERMINAL ATTRIBUTES
IFIW CCMLTT ;(3) TERMINAL TYPE
IFIW CCMLOF ;(4) OUTPUT FLOW CONTROL
IFIW CCMLPS ;(5) PAGE STOP
IFIW CCMLFP ;(6) FLOW CHARACTER PASSTHROUGH
IFIW CCMLIF ;(7) INPUT FLOW CONTROL
IFIW CCMLLN ;(10) LOSS NOTIFICATION
IFIW CCMLLW ;(11) LINE WIDTH
IFIW CCMLFL ;(12) FORMS LENGTH
IFIW CCMLSL ;(13) STOP LENGTH
IFIW CCMLCR ;(14) CR-FILL
IFIW CCMLLF ;(15) LF-FILL
IFIW CCMLWR ;(16) WRAP HANDLING
IFIW CCMLHT ;(17) HT HANDLING
IFIW CCMLVT ;(20) VT HANDLING
IFIW CCMLFF ;(21) FF HANDLING
CCMLMW==CPOPJ## ;I DIDN'T ASK
CCMLFP==CPOPJ## ;I DIDN'T ASK
CCMLIF==CPOPJ## ;I DIDN'T ASK
CCMLLN==CPOPJ## ;I DIDN'T ASK
CCMLCR==CPOPJ## ;I DIDN'T ASK
CCMLLF==CPOPJ## ;I DIDN'T ASK
CCMLVT==CPOPJ## ;I DIDN'T ASK
CCMLTA: CALL CCIINT ;GET THE 2-BYTE BIT MASK
RET ;ERROR
RETSKP ;WAIT
ANDI T1,TA%DIS ;ONLY CARE IF IT'S VIDEO
LSH T1,-1 ;POSITION WHERE IT BELONGS
DPB T1,LDPDIS## ;STORE IT AWAY
STOR T1,CHDIS,(W) ;KEEP OUR OWN COPY
JRST CTICC3 ;LOOP OVER ALL PARAMETERS
CCMLTT: LOAD T1,CTIML,(W) ;GET NUMBER OF REMAINING BYTES
CAILE T1,7 ;IF BEYOND RANGE THAT WE CARE ABOUT,
MOVEI T1,7 ;MINIMIZE
CALL CCICHK ;SEE IF WE CAN HAVE THAT MANY
RET ;BUT IT'S IN RANGE!
RETSKP ;BE PATIENT
CALL CCIBYT ;GET THE STRING'S LENGTH
RET ;ERROR IF CAN'T
RET ;I JUST CHECKED FOR IN RANGE
CAILE T1,17 ;CAN WE HANDLE THAT LONG A NAME?
RET ;NO, BUT THAT MEANS IT'S TOO LONG
JUMPE T1,CTICC3 ;DONE WITH IT IF IT'S NULL
MOVE T4,T1 ;COPY THE LENGTH FOR LATER COMPARISON
CALL CCISIX ;READ SIXBIT
RET ;ERROR IF RAN OUT
RET ;I ALREADY CHECKED AVAILABILITY (6 BYTES MAX)
STOR T4,CTMIJ,(W) ;STORE NUMBER OF JUNK BYTES
MOVE T2,T1 ;GET TTY NAME WHERE COMCON WANTS IT
PUSHJ P,TTUTYP## ;TRY TO SET TTY NAME
JRST CCMLT1 ;DON'T STORE JUKN
LDB T1,LDPTTT## ;GOT IT,
STOR T1,CHTTT,(W) ;SAVE IN OUR COPY AS WELL
CCMLT1: SETZ T1, ;ZERO FILL CLASS
DPB T1,LDPFLC## ;REMOTE DOES ITS OWN FILL
SETZRO CTMW1,(W) ;NO LONGER DOING A CHARACTERISTIC
CALL CCIJNK ;SKIP ANY TRASH IN THE NAME
RET ;ERROR IF RAN OUT
RETSKP ;OK TO BE PATIENT NOW
JRST CTICC3 ;LOOP OVER ALL PARAMETERS
CCMLOF: CALL CCIBYT ;GET THE VALUE
RET ;ERROR
RETSKP ;AWAIT IT
DPB T1,LDPXNF## ;STORE IT AWAY
STOR T1,CHXNF,(W) ;KEEP OUR OWN COPY
JRST CTICC3 ;LOOP OVER ALL PARAMETERS
CCMLPS: CALL CCIBYT ;GET THE VALUE
RET ;ERROR
RETSKP ;AWAIT IT
DPB T1,LDPSPE## ;STORE IT AWAY
SKIPE T1 ;IF ON,
DPB T1,LDPSST## ;IT IMPLIES SSTOP AS WELL
JRST CTICC3 ;LOOP OVER ALL PARAMETERS
CCMLLW: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;AWAIT IT
JUMPE T1,CTICC3 ;IGNORE IT IF TOPS-20 NOWRAP
CAILE T1,^D255 ;IS IT IN RANGE?
MOVEI T1,^D255 ;NO, TAKE OUR MAXIMUM
CAIGE T1,^D16 ;HOW ABOUT LOWER BOUND?
MOVEI T1,^D16 ;HARUMPH
DPB T1,LDPWID## ;SAVE THE CARRIAGE WIDTH
STOR T1,CHWID,(W) ;KEEP OUR OWN COPY
JRST CTICC3 ;LOOP OVER ALL PARAMETERS
CCMLFL: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;WAIT
CAILE T1,^D255 ;IN OUR RANGE LIMIT?
SETZ T1, ;NO, SAY NO MAXIMUM
DPB T1,LDPLNB## ;SET OUR LENGTH
STOR T1,CHLNB,(W) ;KEEP OUR COPY
JRST CTICC3 ;LOOP FOR NEXT PARAMETER
CCMLSL: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;WAIT
CAILE T1,^D255 ;IN RANGE?
SETZ T1, ;NO, DON'T BOTHER
DPB T1,LDPSTB## ;SET OUR STOP SIZE
JRST CTICC3 ;TRY FOR NEXT PARAMETER
CCMLWR: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;WAIT
CAIN T1,WP.SFT ;IS IT REALLY DOING AUTO-WRAP?
TDZA T1,T1 ;YES,
MOVEI T1,1 ;OR NO
DPB T1,LDPNFC## ;SET NO-FREE-CRLF CORRESPONDINGLY
JRST CTICC3 ;LOOP FOR NEXT CHARACTERISTIC
CCMLHT: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;WAIT
DPB T1,LDPTAB## ;PROPAGATE INTO TTY TAB
.CREF HT.PHY ;NOTE VALUE PROPAGATED
JRST CTICC3 ;LOOP FOR NEXT VALUE
CCMLFF: CALL CCIINT ;GET THE VALUE
RET ;ERROR
RETSKP ;WAIT
DPB T1,LDPFRM## ;PROPAGATE INTO TTY FORM
.CREF FF.PHY ;NOTE VALUE PROPAGATED
JRST CTICC3 ;LOOP FOR NEXT VALUE
CCICMC: CAILE T2,0 ;IS IT IN RANGE FOR CTERM CHARACTERISTICS
CAILE T2,.CMXMH&BYTMSK ;THAT WE KNOW ABOUT?
RET ;NO, SO WE DIDN'T ASK
JRST @.(T2) ;YES, SO DISPATCH ON IT
IFIW CCMCII ;(1) IGNORE INPUT
IFIW CCMCCA ;(2) CHARACTER ATTRIBUTES
IFIW CCMCOP ;(3) CONTROL-O PASSTHROUGH
IFIW CCMCRI ;(4) RAISE INPUT
IFIW CCMCNE ;(5) NORMAL ECHO
IFIW CCMCIE ;(6) INPUT ESCAPE SEQUENCE RECOGNITION
IFIW CCMCOE ;(7) OUTPUT ESCAPE SEQUENCE RECOGNITION
IFIW CCMCCS ;(10) INPUT COUNT STATE
IFIW CCMCAP ;(11) AUTO-PROMPT
IFIW CCMCEP ;(12) ERROR PROCESSING
CCMCII==CPOPJ## ;I DIDN'T ASK
CCMCOP==CPOPJ## ;I DIDN'T ASK
CCMCIE==CPOPJ## ;I DIDN'T ASK
CCMCOE==CPOPJ## ;I DIDN'T ASK
CCMCCS==CPOPJ## ;I DIDN'T ASK
CCMCAP==CPOPJ## ;I DIDN'T ASK
CCMCEP==CPOPJ## ;I DIDN'T ASK
CCMCCA: MOVEI T1,3 ;WE NEED THIS MANY MORE BYTES
CALL CCICHK ;SEE IF WE CAN HAVE THEM
RET ;CAN'T
RETSKP ;BE PATIENT
CALL CCIBYT ;YES, SEE WHAT CHARACTER THIS IF ABOUT
RET ;I ALREADY CHECKED FOR THIS
RET ;THIS, TOO
CAIE T1,"V"-100 ;IS IT FOR ^V (SYN)?
RET ;NO, THEN I DIDN'T ASK
CALL CCIINT ;YES, GET ITS BITS
RET ;I CHECKED FOR THIS ALREADY
RET ;AND FOR THIS
TRNN T1,CA.ENB_8 ;IS ITS SPECIAL ACTION ENABLED?
TDZA T1,T1 ;NO, LOAD A ZERO
MOVEI T1,1 ;OR A ONE IF YES
DPB T1,LDPQOT## ;SET TTY QUOTE VALUE
JRST CTICC3 ;LOOP OVER ALL VALUES
CCMCRI: CALL CCIBYT ;GET THE FLAG
RET ;CAN'T
RETSKP ;HAVE TO WAIT
DPB T1,LDPLCT## ;TTY [NO] LC
STOR T1,CHLCT,(W) ;KEEP OUR OWN COPY
JRST CTICC3 ;LOOP FOR NEXT VALUE
CCMCNE: CALL CCIBYT ;GET THE FLAG
RET ;CAN'T
RETSKP ;WAIT
TRC T1,1 ;OURS IS INVERTED
DPB T1,LDPECH## ;SET ECHO STATUS
DPB T1,LDPCNE## ;ALSO SET COMMMAND-LEVEL NO ECHO FROM IT
STOR T1,CHECH,(W) ;KEEP OUR OWN COPY
JRST CTICC3 ;LOOP OVER ALL VALUES
;CTICIC - CTERM layer input message to accept a queued input count
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICIC: MOVEI T1,4 ;NUMBER OF BYTES REQUIRED
CALL CCICHK ;CAN I GET THEM?
TRNA ;OK IF NOT THERE
RETSKP ;HAVE TO WAIT FOR THEM
MOVEI T1,3 ;NUMBER REALLY IN THE SPEC
CALL CCICHK ;CAN I GET THEM?
RET ;PROTOCOL ERROR IF CAN'T
RET ;ALREADY WAITED FOR FOUR
CALL CCIBYT ;EAT ONE
RET ;ERROR
RET ;STILL ERROR
CALL CCIINT ;GET THE COUNT
RET ;ERROR
RET ;STILL ERROR
;Add code here to deliver it to SCNSER once we can
CALL CCIBYT ;EAT THE VMS LOOK-AHEAD CHARACTER
TRNA ;WONDERFUL IF NOT THERE
RET ;I ALREADY CHECKED & WAITED HERE
JRST CCIFIN ;DONE
;CTICIS - CTERM layer input message to accept an input state message
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; CTIML(W)/ Count of bytes in this sub-message
; RET ;PROTOCOL ERROR
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T4
CTICIS: CALL CCIBYT ;GET THE ONLY DATA BYTE
RET ;ERROR
RETSKP ;WAIT FOR IT
TRNN T1,IS.IIP ;DO WE CARE?
JRST CCIFIN ;NO, WE'RE DONE
HRRZ F,LDBDDB##(U) ;SEE IF THERE'S A DDB TO ANNOY
JUMPE F,CCIFIN ;NO, WE'RE STILL DONE
SKIPE DEVPSI(F) ;DON'T BOTHER IF NOT ENABLED
CALL PSIAVL## ;YES, NOTIFY THAT INPUT IS AVAILABLE
JRST CCIFIN ;DONE
;CFICHK - CTERM Foundation input routine to check remaining bytes
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; T1/ Number of bytes needed
; RET ;NOT AVAILABLE, CHECK FOR EOM/MORE DATA
; RETSKP ;AVAILABLE
;
; Uses: T2, and T1 is clobbered on the non-skip return
;If the data is not available, any bytes which can be had are copied into
; the CTB for the foundation input routines, so more input can be had from
; DECnet even while blocking this link.
CFICHK: JUMPE T1,CFICK0 ;SPECIAL-CASE ZERO BYTES
CAMG T1,P2 ;ARE THERE ENOUGH IN THE CURRENT MESSAGE?
RETSKP ;YES, NO PROBLEM
SKIPE T2,CTHIFP ;NO, IF USING STORED BYTES,
LOAD T2,CTIFL,(W) ;GET NUMBER OF BYTES CURRENTLY BUFFERED
CAMG T1,T2 ;ENOUGH HERE?
RETSKP ;YES, GIVE OK RETURN
ADD T2,P2 ;FIND OUT HOW MANY THERE ARE TOTAL
CAMG T1,T2 ;IS THIS ENOUGH?
RETSKP ;YES, THIS IS OK
CAILE T2,^D16 ;NO, WILL IT FIT?
STOPCD .,STOP,CTHIBO, ;++CTERM HOST INPUT BUFFER OVERFLOW
JUMPE T2,CPOPJ## ;SKIP OVERHEAD IF NO BYTES AVAILABLE AT ALL
CALL CFICMP ;COMPRESS OUT ANY USED-UP BYTES
LOAD T1,CTIFL,(W) ;GET BUFFER COUNT AGAIN
MOVE T2,T1 ;COPY IT
ADD T2,P2 ;GET THE TOTAL TO BE STORED (AGAIN)
ADJBP T1,[POINT 8,CT.IFM(W)] ;FORM STORAGE POINTER TO REST OF BUFFER
STOR T2,CTIFL,(W) ;STORE NEW BUFFER COUNT
MOVE T2,[POINT 8,CT.IFM(W)] ;GET COMPRESSED POINTER
MOVEM T2,CTHIFP ;SET IT IN CASE WASN'T IN USE BEFORE
CFICK2: SOSGE P2 ;IS THERE ANOTHER BYTE TO COPY?
RET ;NO, RETURN
ILDB T2,P1 ;YES, FETCH IT
IDPB T2,T1 ;AND BUFFER IT
JRST CFICK2 ;LOOP OVER THE CURRENT MESSAGE
CFICK0: LOAD T2,CTIFL,(W) ;GET THE BUFFER COUNT
CAMN T2,P2 ;DOES THE BUFFER COUNT EQUAL THE MESSAGE COUNT?
SKIPE T2 ;AND ARE BOTH ZERO?
RETSKP ;NO, MORE IS AVAILABLE
PJRST CFIRET ;YES, SEE IF AT END OF MESSAGE
;CFICMP - CTERM Foundation input buffer compressor
;
;Call:
; W/ Pointer to Link's CTB
; RET ;ALWAYS
;
; Uses: T1-T4
CFICMP: SKIPN T3,CTHIFP ;ARE WE DOING INPUT THROUGH THE BUFFER?
RET ;NO, NOTHING TO DO
LOAD T2,CTIFL,(W) ;YES, GET THE NUMBER OF BYTES TO TRANSFER
MOVE T1,[POINT 8,CT.IFM(W)] ;GET POINTER TO BEGINNING OF BUFFER
CAMN T3,T1 ;ARE THEY THE SAME?
RET ;YES, NOTHING TO DO
MOVEM T1,CTHIFP ;NO, UPDATE POINTER FOR READ ROUTINES
CFICM1: SOSGE T2 ;IS THERE ANOTHER?
RET ;NO, ALL DONE
ILDB T4,T3 ;YES, FETCH IT
IDPB T4,T1 ;STORE IN THE BEGINNING
JRST CFICM1 ;LOOP OVER ENTIRE BUFFER
;CFIRET - CTERM Foundation input routine to check for EOM
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; RET ;EOM
; RETSKP ;NOT EOM
CFIRET: SAVEAC M ;PRESERVE THE AC WE USE
MOVE M,NRTSAP ;NEED TO EXAMINE THE SAB
TMNN SAEOM,(M) ;EOM FLAG ON?
AOS (P) ;NO, SKIP RETURN
RET ;YES, RETURN
;CFIBYT - CTERM Foundation input routine to read one byte
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;NOT AVAILABLE
; RETSKP ;BYTE IN T1
CFIBYT: SKIPN CTHIFP ;ARE WE STILL READING FROM BUFFERED DATA?
JRST CFIBY1 ;NO, GO READ FROM THE MESSAGE
OPSTRM <SOS>,CTIFL,(W) ;YES, DECREMENT THE COUNT OF REMAINING BYTES
ILDB T1,CTHIFP ;GET THE NEXT
TMNN CTIFL,(W) ;WAS THIS THE LAST?
SETZM CTHIFP ;YES, FLAG FOR NEXT TIME
RETSKP ;RETURN WITH DATUM
CFIBY1: SOSGE P2 ;ANOTHER BYTE IN MESSAGE?
RET ;NO, RETURN FAILURE
ILDB T1,P1 ;YES, FETCH IT
RETSKP ;RETURN THE DATUM
;CFISKP - CTERM Foundation input routine to skip N bytes
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; T1/ Number of bytes to skip over
; RET ;NOT ALL WERE AVAILABLE
; RETSKP ;DONE
; Uses: T1 & T2
CFISKP: MOVE T2,T1 ;COPY THE COUNT OF BYTES TO SKIP
CFISK1: SOSGE T2 ;ANY MORE TO SKIP?
RETSKP ;NO, WE'RE DONE
CALL CFIBYT ;YES, GET ONE
RET ;CAN'T DO IT
JRST CFISK1 ;LOOP UNTIL REQUEST IS COMPLETED
;CFIINT - CTERM Foundation input routine to read a network integer
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;NOT AVAILABLE
; RETSKP ;16-BIT INTEGER IN T1
CFIINT: CALL CFIBYT ;GET LOW-ORDER BYTE
RET ;PROPAGATE FAILURE
SAVEAC T2 ;NEED ANOTHER AC
MOVE T2,T1 ;SAVE LOW BYTE
CALL CFIBYT ;GET HIGH-ORDER BYTE
RET ;FAILED AGAIN
LSH T1,8 ;POSITION HIGH BYTE WHERE IT BELONGS
IOR T1,T2 ;MERGE IN LOW BYTE
RETSKP ;RETURN THE DATUM
;CFIFIN - CTERM Foundation input routine message exit routine
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;PROTOCOL ERROR
; RETSKP ;WE'RE DONE SUCCESSFULLY
CFIFIN: SETZRO CTIFT,(W) ;NO LONGER HAVE A FUNCTION IN PROGRESS
CALL CFICK0 ;CHECK FOR EOM
AOS (P) ;ON, WE'RE GOLDEN
RET ;OFF IS PROTOCOL ERROR
;EOM is required at this point because some Foundation messages are of
; otherwise indeterminate length.
;CCICHK - CTERM layer input routine to check on available bytes
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; T1/ Number of bytes needed
; RET ;NOT AVAILABLE
; RETSKP ;IN RANGE, BUT MUST DELAY
; DOUBLE-SKIP ;AVAILABLE NOW
;
; Uses: T1 & T2
;If the data is not available, any bytes which can be had are copied into
; the CTB for the foundation input routines, so more input can be had from
; DECnet even while blocking this link.
CCICHK: OPSTR <CAMLE T1,>,CTIML,(W) ;IN RANGE OF CTERM BLOCK?
RET ;NO, GIVE UP
CALL CFICHK ;YES, CHECK IF IN CURRENT BUFFER
JRST CFIRET ;NO, RETURN DEPENDS ON EOM
JRST CPOPJ2## ;YES, IT'S AVAILABLE
;CCIBYT - CTERM layer input routine to read one byte
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;NOT AVAILABLE
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;BYTE IN T1
;
; Uses: T1 & T2
CCIBYT: MOVEI T1,1 ;WANT TO READ ONE BYTE
CALL CCICHK ;IS IT THERE?
RET ;NOT AT ALL
RETSKP ;MAYBE LATER
OPSTRM <SOS>,CTIML,(W) ;DECREMENT THE COUNT BY AMOUNT TO BE USED
CALL CFIBYT ;IN RANGE, GO FETCH
RET ;ERROR?!?
JRST CPOPJ2## ;GOT IT
;CCISKP - CTERM layer input routine to skip N bytes
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; T1/ Number of bytes to skip over
; RET ;NOT AVAILABLE
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1 & T2
CCISKP: CALL CFICHK ;DO WE HAVE THEM AROUND?
JRST CFIRET ;NO, RETURN BASED ON EOM
LOAD T2,CTIML,(W) ;YES, GET OUR REMAINING MESSAGE BYTE COUNT
SUB T2,T1 ;ACCOUNT FOR BYTES ABOUT TO BE READ
JUMPL T2,CPOPJ## ;NOT ENOUGH BYTES
STOR T2,CTIML,(W) ;UPDATE BYTE COUNT
CALL CFISKP ;SKIP OVER THE BYTES
RET ;DIDN'T WORK
JRST CPOPJ2## ;BINGO
;CCIJNK - CTERM layer input routine to skip junk bytes
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;NOT AVAILABLE
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;DONE
;
; Uses: T1-T2
CCIJNK: LOAD T1,CTMIJ,(W) ;GET THE REMAINING NUMBER OF JUNK BYTES
JUMPE T1,CPOPJ2## ;NO JUNK, GET NEXT VALUE BYTE
LOAD T2,CTIFL,(W) ;GET FOUNDATION BUFFER LENGTH
ADD T2,P2 ;PLUS INPUT LENGTH
JUMPE T2,CFIRET ;CAN'T SKIP IF NO BYTES, RETURN DEPENDS ON EOM
CAMG T1,T2 ;WILL WE NEED TO DEFER AGAIN?
TDZA T2,T2 ;NO, NEW COUNT IS ZERO
SUBM T1,T2 ;YES, NEW COUNT TO T2
STOR T2,CTMIJ,(W) ;UPDATE JUNK COUNT
SUB T1,T2 ;CALCULATE HOW MANY TO SKIP NOW
CALL CCISKP ;EAT THE BYTES
RET ;ERROR
RET ;STILL AN ERROR
JRST CCIJNK ;CHECK AGAIN, JUST IN CASE
;CCIINT - CTERM layer input routine to read a network integer
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;NOT AVAILABLE
; RETSKP ;MUST WAIT FOR FURTHER FOUNDATION BYTES
; DOUBLE-SKIP ;16-BIT INTEGER IN T1
;
; Uses: T1 & T2
CCIINT: MOVEI T1,2 ;WANT TO READ TWO BYTES
CALL CCICHK ;IS IT THERE?
RET ;NOT AT ALL
RETSKP ;MAYBE ANOTHER TIME
MOVNI T1,2 ;GET AMOUNT FOR ADJUSTING BYTE COUNT
OPSTRM <ADDM T1,>,CTIML,(W) ;UPDATE REMAINING LENGTH
CALL CFIINT ;IN RANGE, GO FETCH
RET ;ERROR?!?
JRST CPOPJ2## ;GOT IT
;CCISIX - CTERM layer input routine to read sixbit from a string
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; T4/ Maximum number of characters available in the string
; RET ;ON ERROR
; RETSKP ;NEED MORE FOUNDATION BYTES
; DOUBLE-SKIP ;ON SUCCESS, T1/ VALUE
;
; Uses: T1-T3, returns T4 decremented only by amount read
CCISIX: SETZM CTH6BW ;CLEAR OUR STORAGE WORD
MOVE T3,[POINT 6,CTH6BW] ;INITIALIZE OUR BYTE POINTER
CCISX1: JUMPLE T4,CCISX4 ;EXIT IF NO MORE TO READ
SUBI T4,1 ;ACCOUNT FOR THE NEXT READ
CALL CCIBYT ;FETCH A CHARACTER
RET ;ERROR
RET ;CAN'T WAIT HERE
TRNN T1,140 ;IS IT A CONTROL CHARACTER?
JRST CCISX4 ;YES, THIS ENDS THE STRING
TRNE T1,200 ;IS IT AN EIGHT-BIT CHARACTER?
RET ;THE SPEC CLAIMS ONLY 7-BIT IS LEGAL HERE...
CAILE T1,"a" ;IS IT A LOWERCASE CHARACTER?
CAILE T1,"z" ; (TEST)
SUBI T1,40 ;NO, NEEDS CONVERSION TO SIXBIT
IDPB T1,T3 ;STORE THE CHARACTER
TLNE T3,770000 ;IS THERE ROOM FOR ANOTHER?
JRST CCISX1 ;YES, READ IT
CCISX4: MOVE T1,CTH6BW ;GET OUR STORAGE WORD
JRST CPOPJ2## ;RETURN THE FANCY WORD
;CCIFIN - CTERM layer input routine to exit the sub-message
;
;Call:
; W/ Pointer to Link's CTB
; U/ Address of corresponding LDB
; P1/ Byte pointer to read bytes from the current message
; P2/ Number of bytes remaining in the current message
; RET ;ON ERROR
; DOUBLE-SKIP ;ON SUCCESS
;
; Uses: T1 & T2
CCIFIN: TMNE CTIML,(W) ;ARE WE DONE WITH THE MESSAGE?
RET ;NO, SOMEBODY SCREWED UP
SETZRO CTMIJ,(W) ;NO MORE JUNK BYTES
SETZRO CTMI1,(W) ;NEXT MESSAGE MUST SKIP ITS OWN FILL
JRST CPOPJ2## ;GIVE SUCCESS RETURN TO FOUNDATION
;NJFRDR - Jiffy Service Routine for a link in DISCONNECT RECEIVED state
;
;Call:
; W/ Pointer to Link's NRB
; RET ;ALWAYS
;
;The link is in one of the "gone sour" states. Close the link
;and free the TTY LDB.
NJFRDC: ;DISCONNECT CONFIRMED
NJFRDR: ;DISCONNECT RECEIVED
NJFRCF: ;NO CONFIDENCE
NJFRLK: ;NO LINK
NJFRCM: ;NO COMMUNICATION
NJFRNR: ;NO RESOURCES
PJRST NRTREL ;RELEASE THE LINK ALTOGETHER
;NRTNEP - Do an Enter Passive to hang out a new DECnet link
;
;Call:
; NRTSAP/ Pointer to NRT's SAB
; NRTSJP/ Pointer to NRT's SJB
;
;Return:
; RET ;ALWAYS
NRTNEP: SKIPE NRTCWL ;ANY LINKS ALREADY WAITING?
RET ;YES, DON'T HANG OUT ANY MORE
SAVEAC <M,W,P1> ;SAVE FOR SAB,NRB,CBLK POINTERS
MOVEI T1,NR.LEN ;LENGTH OF A NRB (AS DISTINGUISHED FROM CTB)
MOVE T2,[NRTOBJ,,NRTOBJ];REMOTE,,LOCAL OBJECTS
CALL CMNNEP ;DO COMMON ENTER PASSIVE STUFF
RET ;PASS ALONG FAILURE
AOS NRTCWL ;REMEMBER OUR NEW WAITER
RET ;AND RETURN
CTHNEP: SKIPE CTHCWL ;ANY LINKS ALREADY WAITING?
RET ;YES, DON'T HANG OUT ANY MORE
SAVEAC <M,W,P1> ;SAVE FOR SAB,NRB,CBLK POINTERS
MOVEI T1,CT.LEN ;LENGTH OF A CTERM BLOCK
MOVE T2,[CTSOBJ,,CTHOBJ];REMOTE,,LOCAL OBJECTS
CALL CMNNEP ;DO COMMON ENTER PASSIVE STUFF
RET ;FAILED
AOS CTHCWL ;REMEMBER THE NEW WAITER
SETONE NRCTM,(W) ;NOTE THAT THIS IS A CTERM LINK
RET ;AND RETURN
CMNNEP: MOVE P1,T2 ;SAVE OBJECT TYPES
MOVE M,NRTSAP ;POINT TO NRT'S SAB
CALL NRTGWD ;GET A NEW NRB OR CTB
RET ;COULDN'T
MOVE W,T1 ;POINTER TO NRB
;Get and set up a connect block
MOVEI T1,CB.LEN ;GET PLACE TO PUT CONNECT BLK
CALL NRTGWD
JRST [MOVE T1,W ;CAN'T, DEALLOCATE NRB AS WELL
PJRST NRTFWD] ;FREE NRB
HLRZ T2,P1 ;GET REMOTE'S OBJECT NUMBER
STOR T2,PBOBJ,+CB.SRC(T1) ;SAVE IN CB
HRRZ T2,P1 ;GET OUR OBJECT NUMBER
STOR T2,PBOBJ,+CB.DST(T1) ;SAVE FOR CONNECT
MOVE P1,T1 ;P1 POINTS TO CONNECT BLOCK
MOVEI T1,PB.LEN ;LENGTH OF PDB
STOR T1,PBSIZ,+CB.SRC(P1) ;STORE SIZE OF SOURCE PDB
STOR T1,PBSIZ,+CB.DST(P1) ;STORE SIZE OF DEST PDB
MOVEI T1,0 ;GET FORMAT TYPE 0
STOR T1,PBFOR,+CB.SRC(P1) ;STORE FORMAT OF SOURCE PDB
STOR T1,PBFOR,+CB.DST(P1) ;STORE FORMAT OF DEST PDB
;Now set up the SAB for an Enter Passive
STOR P1,SAAA1,(M) ;CONNECT BLK IS FIRST ARG
STOR P1,SACBP,(M) ;STORE POINTER TO CONNECT BLOCK HERE TOO
MOVX T1,.NSFEP ;ENTER PASSIVE FUNCTION CODE
MOVEI T2,3 ;NUMBER OF ARGS
CALL NRTNSF ;ENTER PASSIVE
JRST NRTNEE ;CAN'T, RETURN MEMORY & LEAVE
CAMLE T1,NRTCHL ;CAN WE HANDLE THIS CHANNEL NUMBER?
JRST [MOVX T1,.NSFRL ;NO, RELEASE THE CHANNEL & TRY
MOVEI T2,2 ; FOR ANOTHER LATER, WHEN DECnet
CALL NRTNSF ; HAS FREED UP SOME LOWER NUMBERS
JFCL ;IGNORE ERROR RETURN
JRST NRTNEE] ;RETURN MEMORY & LEAVE
;Now collect returned info not already stored by NRTNSF
LOAD T1,SAACH,(M) ;GET NEW CHANNEL NUMBER
STOR T1,NRCHN,(W) ;STORE CHANNEL NUMBER IN NRB
ADD T1,NRTCHP ;CALC PTR TO CHANNEL TABLE ENTRY
MOVEM W,(T1) ;STORE NEW NRB PTR IN CHANNEL TABLE
AOS (P) ;PROPAGATE SUCCESS
NRTNEX: MOVE T1,P1 ;GET POINTER TO CONNECT BLOCK
PJRST NRTFWD ;FREE IT
;Here on error when we have to deallocate an NRB
NRTNEE: MOVE T1,W ;DEALLOCATE NRB AS WELL
CALL NRTFWD ;FREE NRB
JRST NRTNEX ;FREE CONNECT BLOCK AS WELL
SUBTTL Subroutines -- NRTNSF - Call SCLINK's SCTNSF
;NRTNSF - Call SCLINK's SCTNSF and handle the return
;
; Call:
; T1/ Function code
; T2/ Number of Args not defaulted in SAB
; M/ Extended pointer to filled-in SAB
; W/ Pointer to NRB
;
; Return:
; RET ;FAILED, CODE IN T1
; RETSKP ;SUCCESS
NRTNSF: STOR T1,SAAFN,(M) ;FUNCTION CODE
STOR T2,SANAG,(M) ;STORE NUMBER OF ARGS
SETONE SAEVA,(M) ;BUFFERS WE PASS WILL BE IN EVA
MOVE T1,NRTSJP ;GET POINTER TO OUR SJB
STOR T1,SASJB,(M) ;STORE THE ADDRESS OF THE SJB
XMOVEI T1,NRTHBR ;POINT TO THE HIBER ROUTINE (BUG.)
STOR T1,SAHBA,(M) ;STORE IN THE HIBER ADDRESS ARGUMENT
XMOVEI T1,NRTWAK ;GET ADDRESS OF WAKE HANDLER
STOR T1,SAWKA,(M) ; AND TELL SCLINK ABOUT IT
LOAD T1,NRCHN,(W) ;GET CHANNEL NUMBER
STOR T1,SAACH,(M) ;STORE IN SAB
MOVE T1,M ;PASS SAB TO SCLINK
SNCALL (SCTNSF,MS.HGH) ;DO THE DECnet FUNCTION
LOAD T1,SAERR,(M) ;GET THE ERROR CODE
JUMPN T1,CPOPJ ;ERROR RETURN IF NON-ZERO
LOAD T1,SAAST,(M) ;GET NEW LINK STATUS
STOR T1,NRSTS,(W) ;STORE IN NRB
RETSKP ;SUCCESS RETURN
SUBTTL Subroutines -- NRTREL - Release a Link
;NRTREL - Release a link and all that goes with it.
;
; Call: W/ Pointer to the NRB to release
;
; Return:
; RET ;ALWAYS, NRB IS DEALLOCATED
;
; Uses: W
NRTREL: SAVEAC <U,M>
SETONE NRREL,(W) ;TELL NRTLKS THIS NRB IS DOOMED
OPSTR <SKIPN U,>,NRLDB,(W) ;ANY LDB HERE?
JRST NRTRL1 ;NO
;Here when there is an LDB to be freed
CALL NGVLDB ;FREE UP THE DDB/LDB
;Here to free the associated DECnet link
NRTRL1: MOVE M,NRTSAP ;POINT TO NRT'S SAB
MOVX T1,.NSFRL ;RELEASE FUNCTION CODE
MOVEI T2,2 ;NUMBER OF ARGS PASSED
CALL NRTNSF ;RELEASE THE CONNECT
JFCL ;IGNORE ERROR RETURN
LOAD T1,NRCHN,(W) ;GET DECnet CHANNEL NUMBER
ADD T1,NRTCHP ;INDEX INTO CHANNEL TABLE
SETZM (T1) ;WE NO LONGER HAVE THIS CHANNEL OPEN
MOVE T1,W ;ADDRESS OF NRB
CALL NRTFWD ;FREE IT
SETZ W, ;DON'T LET CALLERS USE W
RET ;LINK IS RELEASED NOW
SUBTTL Subroutines -- NGTLDB - Get an LDB for NRTSER
;NGTLDB - Get a remote LDB and make it mine
;
; Call: W/ Pointer to NRB
;
; Return:
; RET ;FAILED, REASON CODE IN T1
; RETSKP ;SUCCESS, POINTER IN U
;
; Uses: W
NGTLDB: SAVEAC <P1,W> ;P1 WILL POINT TO NRB
MOVE P1,W ;PTR TO NRB
;Allocate an LDB
MOVSI T1,LTLNRT## ;FLAG A NEW NRT/CTERM TERMINAL
MOVEI T3,NRTDSP ;NRT'S ISR DISPATCH TABLE
CALL GETLDB## ;GET A REMOTE TTY LDB, POINTER IN U
JRST [MOVX T1,RSNOTB ; OBJECT TOO BUSY REASON CODE
RET] ; GO ANNOUNCE THE FAILURE
;Finish making this a NRT LDB
MOVEI T1,NRTRTQ ;GET POINTER TO OUTPUT Q HEADER
HRLZM T1,LDBQUH##(U) ;STORE FOR SCNSER (TOPOKE/TOTAKE)
STOR U,NRLDB,(P1) ;REMEMBER OUR LDB
MOVEM P1,LDBNRT##(U) ;STORE NRB PTR IN LDB TOO
MOVEI T1,1 ;MAKE CONTROL-A THE
DPB T1,LDPUNP## ;TTY UNPAUSE CHARACTER
TMNE NRCTM,(P1) ;IS THIS A NRT LINK?
JRST NGTLDC ;NO, CTERM, GO ELSEWHERE
MOVEI T1,APCNRT## ;GET NRTSER CODE
DPB T1,LDPAPC## ;SET ASYNC PORT CHARACTERISTIC
;Initialize the TTY with .HELLO force command
CALL TTFGRT## ;GO FORCE .HELLO
RETSKP ;SUCCESS RETURN
;Here to finish up allocating a CTERM link's LDB
NGTLDC: MOVEI T1,APCCTM## ;GET CTERM CODE
DPB T1,LDPAPC## ;SET ASYNC PORT CHARACTERISTIC
RETSKP ;RETURN GOODNESS NOW (DEFER TTFGRT UNTIL BOUND)
SUBTTL Subroutines -- NGVLDB - Give an LDB back to SCNSER
;NGVLDB - Give an LDB back to SCNSER
;
; Call: U/ Pointer to LDB
;
; Return:
; RET ;ALWAYS
NGVLDB: SETZM LDBNRT##(U) ;DISENGAGE LDB FROM NRB
MOVEI T1,IONND% ;"NODE DOWN" (PATH LOST/ETC) ERROR
CALL DETLDB## ;DETACH THE LDB/DDB
PJRST FRELDB## ;RETURN LDB TO SCNSER FREE POOL
SUBTTL Subroutines -- NRTWAK - Subroutine to do the WAKEs.
;NRTWAK - Called when SCLINK thinks we might want to wake the user
;
; Call: T1/ Old Status,,PSI Mask
; T2/ New Status,,Channel Number
; T3/ Pointer to Session Control Job Block
; T4/ Link identifier to pass to SCTWKQ
;
; Return:
; RET ;Tells SCLINK not to queue SLB
; RETSKP ;Tells SCLINK to queue SLB for SCTPSQ
;
; Uses: T1,T2,T3,T4
;
;SCLINK calls this routine (via SAWKA) when either the link
;state has changed or one of the status bits has changed from a
;zero to a one.
;
;This routine is called from extended section (on extended machine)
;so be careful not to change that.
NRTWAK: ;NRTNSF PASSES THIS ADDR TO SCLINK
MOVE T1,T4 ;PASS LINK IDENTIFIER TO SCTWKQ
SNCALL (SCTWKQ,MS.HGH) ;ASK SCLINK TO QUEUE THIS LINK FOR SCTPSQ
SETOM NRTPSQ ;TELL NRTSTO DECnet IS INTERESTING NOW
RET ;ONLY RETURN
SUBTTL Subroutines -- NRTHBR - Subroutine to do the HIBERs.
;NRTHBR - Called by SCLINK to hibernate
;
; Call:
; T1/ Pointer to SJB
;
; Return:
; RET ;ONLY RETURN
;
; Uses: T1
NRTHBR: BUG. CHK,NRTHBC,NRTSER,SOFT,<NRTHBR should never be called>,,<
Cause: This BUG is not documented yet.
>,CPOPJ
SUBTTL Subroutine -- NRTLFC - Get a NRT Line number from channel
;NRTLFC - Gets a Line number given a NRT channel.
;
; Call:
; U/ Channel number
;
; Return: U/ Line number or 0 if none found
; RET ;Always return
; It is expected when this subroutine is called, that the calling
; routine has checked to be sure that the channel is in range of the
; channels that NRTSER has open.
;
; Used: T1,U
NRTLFC::MOVE T1,NRTCHP ;GET THE POINTER TO THE NRB
ADD T1,U ;ADD IN THE CHANNEL NUMBER
SKIPN T1,(T1) ;ANYTHING THERE?
JRST NRTRZR ;NONE, THEN RETURN ZERO
LOAD U,NRLDB,(T1) ;AND THEN THE POINTER TO THE LDB
SKIPN U ;ANYTHING THERE?
NRTRZR: TDZA U,U ;CLEAR OUT U
LDB U,LDPLNO## ;GET THE LINE NUMBER
POPJ P, ;AND RETURN
SUBTTL Subroutine -- CWHNRT - Type a node spec for WHERE command
;CWHNRT - Types a node spec given a NRTSER-owned LDB.
;
; Call:
; U/ Target LDB address
; 0(P)/ Command LDB address
;
; Return:
; RET ;If success
; via CWHNCN ;If line is not owned by NRTSER
;
; Used: T1-T4
CWHNRT::PUSHJ P,NRTNFL ;GET NODE FROM LINE
PJRST CWHNCN## ;NOT CONNECTED ANY MORE?
PUSH P,DEVNAM(F) ;SAVE DEVICE NAME
PUSH P,T1 ;SAVE NODE ADDRESS
PUSH P,T2 ;AND NODE NAME
PUSHJ P,TTYKLQ## ;ZAP USELESS TTY DDB
EXCH U,-3(P) ;RESTORE COMMAND LDB FOR TYPEOUT
PUSHJ P,INLMES## ;TYPE OUT
ASCIZ /DECnet / ;INTRODUCER
DMOVE T1,-1(P) ;RESTORE NODE SPEC
PUSHJ P,PRNODE ;FORMAT IT
MOVE T1,-3(P) ;GET TARGET LDB
MOVE T1,LDBNRT##(T1) ;GET CTB/NRT ADDRESS
MOVX T2,NRCTM ;CTERM-MODE BIT
TDNN T2,NR.CTM(T1) ;IS THIS A CTERM CONNECT?
JRST WHNRT1 ;NO, CAN'T GIVE A LINE NUMBER
LOADE T1,CTRLN,(T1) ;YES, GET THE REMOTE'S LINE NUMBER
JUMPL T1,WHNRT1 ;SKIP THIS IF UNKNOWN
PUSH P,T1 ;SAVE IT
PUSHJ P,INLMES## ;TYPE SOME INTRO
ASCIZ / line # /
POP P,T1 ;RESTORE IT
PUSHJ P,PRTDI8## ;LINE NUMBERS ARE OCTAL
WHNRT1: MOVEI T3," " ;SPACE TO SEPARATE
PUSHJ P,COMTYO## ;DO IT
MOVE T2,-2(P) ;DEVICE NAME
PUSHJ P,PRNAME## ;TYPE THAT
PUSHJ P,INLMES## ;MORE FORMATTING
ASCIZ / (/
MOVE T1,-3(P) ;GET TARGET LDB ADDRESS
MOVE T1,LDBNRT##(T1) ;GET CTB/NRB ADDRESS
LOAD T1,NRCTM,(T1) ;FIND OUT WHICH IT IS
SKIPE T1 ;IF CTERM,
SKIPA T2,['CTERM '] ;LOAD THAT
MOVSI T2,'NRT' ;ELSE TYPE NRT
PUSHJ P,PRNAME## ;TYPE CONNECTION MODE
MOVEI T3,")" ;CLOSING TEXT
PUSHJ P,COMTYO## ;TYPE IT
ADJSP P,-4 ;TRIM JUNK OFF THE STACK
PJRST PCRLF## ;END LINE AND RETURN
SUBTTL Subroutine -- NRTNFL - Get a NRT Node spec from line
;NRTNFL - Gets a Node spec given a NRTSER-owned LDB.
;
; Call:
; U/ LDB address
;
; Return: T1/ Node address
; T2/ Node name
; RETSKP ;If success
; RET ;If line is not owned by NRTSER
;
; Used: T1-T4
NRTNFL::SE1ENT ;GET TO REASONABLE SECTION
SETZ T2, ;ASSUME NO NAME
SKIPN T1,LDBNRT##(U) ;GET NRB/CTB FROM LDB
RET ;NO CAN DO
IFE FTXMON,<
DNCALL (NRTNFC) ;GET INFO FROM CTB/NRB
RETSKP ;AND RETURN GOODNESS
>
IFN FTXMON,<
AOS (P) ;GIVE SKIP RETURN & FALL INTO NRTNFC
>
NRTNFC: LOAD T2,CTCHN,(T1) ;GET OUR CHANNEL NUMBER
MOVE T1,NRTSJP ;GET OUR SJB ADDRESS
LOAD T1,SJCHT,(T1) ;GET BASE OF OUR CHANNEL TABLE
ADDI T1,-1(T2) ;OFFSET BY CHANNEL INDEX (1 VS. 0 ORIGIN)
MOVE T1,(T1) ;PICK UP SLB FOR CHANNEL
LOAD T1,SLDNA,(T1) ;THEN GET DESTINATION NODE ADDRESS
PUSH P,T1 ;SAVE ADDRESS
SNCALL (SCTA2N##,MS.HGH) ;GET NODE NAME FROM ADDRESS
TDZA T2,T2 ;NULL NAME IF CAN'T FIND IT
MOVE T2,T1 ;COPY FOR PRNAME
JRST TPOPJ## ;RETURN ADDRESS & NAME
PRNODE: PUSH P,T1 ;SAVE NODE ADDRESS
CALL PRNAME## ;TYPE NAME OUT IN SIXBIT
MOVEI T3,"(" ;START FOR TYPING NODE ADDRESS
CALL COMTYO## ;TYPE ONE
LOAD T1,RN%ARE,(P) ;GET THE AREA NUMBER
JUMPE T1,PRNOD1 ;DON'T TYPE IT IF ZERO
CALL RADX10## ;DUMP IN DECIMAL
MOVEI T3,"." ;SEPARATOR
CALL COMTYO## ;TYPE IT
PRNOD1: LOAD T1,RN%NOD,(P) ;GET THE IN-AREA NODE NUMBER
CALL RADX10## ;TYPE IT IN DECIMAL
MOVEI T3,")" ;END OF NODE ADDRESS
CALL COMTYO## ;TYPE IT
JRST TPOPJ## ;BALANCE STACK AND RETURN
SUBTTL NETDID - NETOP. function to give node ID for a TTY
;NETDID - NETOP. functin to return node ID for a NRT TTY
;
;Call: (in section 1 already)
;
; U/ LDB of NRT terminal
; M/ Address of user's NETOP. arg list
;Return:
; ECDX? depending on error
; RETSKP node name stored in string block pointed to by user's arg list
;
;Uses P1,P2 (already saved by higher routine), T1-T4, M
NETDID::MOVE P1,M ;Get pointer to user's arg list
EXCTUX <SKIPN M,5(P1)>;Does he want node name?
JRST NTDID2 ;No
PUSHJ P,NRTNFL ;Yes, get node number and name
JRST NOPDNC## ;Not connected
JUMPE T2,NTDID1 ;Handle differently if name is unknown
MOVE T1,T2 ;Get node name
PUSHJ P,PU6STB## ;And put it into string block
JRST NOPADC## ;Address check doing that
JRST NTDID2 ;Skip code to store a node address
NTDID1: MOVE P2,T1 ;Preserve the node address
PUSHJ P,CHKSTB## ;Address check the string block
JRST NOPADC## ;Failed
ADJSP P,3 ;Make some room
MOVEM P2,(P) ;Save node address
SETZB T1,T2 ;Make some zeros
DMOVEM T1,-2(P) ;Clear storage words
MOVEI T3,-2(P) ;Start of storage
TLO T3,(POINT 8,,7) ;Byte pointer for storing (leading 0 for flag)
MOVEI P2,1 ;Count one byte into the string
LOAD T1,RN%ARE,(P) ;Get area number
PUSHJ P,NTDNMO ;Stuff a decimal number
MOVEI T1,"." ;Separator
IDPB T1,T3 ;Store
AOS P2 ;Count the byte
LOAD T1,RN%NOD,(P) ;Get the in-area node number
PUSHJ P,NTDNMO ;Stuff a decimal number
DMOVE T1,-2(P) ;Get the string (eight bytes max)
ADJSP P,-3 ;Balance stack
PUSHJ P,NTDSTO ;Store into the string block
JRST NOPADC## ;Couldn't do it
NTDID2: EXCTUX <SKIPN M,6(P1)>;Does he want port name?
RETSKP ;No. We're done, then.
PUSHJ P,CHKSTB## ;Check out the string block
JRST NOPADC## ;Address check
MOVE T1,LDBNRT##(U) ;Get NRB
MOVX T2,NRCTM ;Type flag
TDNN T2,NR.CTM(T1) ;Is this a CTERM connect?
RETSKP ;No, we're done here
LOADE T1,CTRLN,(T1) ;Yes, get remote's line number
JUMPL T1,CPOPJ1 ;Forget about storing a string if unknown
SETZ T2, ;Clean accumulation word
NTDID3: LSHC T1,-3 ;Get next octal digit
LSH T2,-3 ;Make room for full SIXBIT digit
TLO T2,'0 ' ;Digitize it
JUMPN T1,NTDID3 ;Loop until done with number
MOVE T1,T2 ;Put into correct AC
PUSHJ P,PU6STB## ;Store into user's string block
JRST NOPADC## ;Didn't work
RETSKP ;That's all, folks!
NTDNMO: IDIVI T1,^D10 ;Hardwired for positive decimal
JUMPE T1,NTDNM1 ;Skip recursion if done
PUSH P,T2 ;Save remainder for unwind
PUSHJ P,NTDNMO ;Typical recursive printer (in section 1)
POP P,T2 ;Restore next remainder
NTDNM1: ADDI T2,"0" ;Make ASCII
IDPB T2,T3 ;Salt it away
AOJA P2,CPOPJ ;Count byte and return
NTDSTO: MOVE T3,T1 ;Save T1
IFN FTXMON,<PUSHJ P,SSPCS##> ;Preserve PCS
MOVE T1,M ;Copy address
PUSHJ P,SXPCS## ;Validate pointer
POPJ P, ;Shouldn't happen since called CHKSTB
PUSHJ P,GETEWD## ;Fetch length word
POPJ P, ;Shouldn't fail
HRL T1,P2 ;Tell number of bytes we're storing
PUSHJ P,PUTEWD## ;Update count for user
POPJ P, ;Should never happen
CAILE P2,(T4) ;Will the string fit?
POPJ P, ;No room
MOVE T1,T3 ;Yes, recover first word
PUSHJ P,PUTEW1## ;Store first word for user
POPJ P, ;Address check
CAIG P2,4 ;Is there really a second word?
RETSKP ;No, don't store it
MOVE T1,T2 ;Yes, get it
PJRST PUTEW1## ;And store that, too
SUBTTL NRTGWD - Get Some Words
;NRTGWD - Get some zeroed words
;
; Call:
; T1/ Count of words we want
;
; Return:
; RET ;ON ALLOCATION FAILURE
; RETSKP ;WITH T1 POINTING TO WORDS
;
; Uses: T1-T4
;
;Note: The count of words allocated is stored in the word before the
;returned pointer.
NRTGWD: SAVEAC <P1,W,M> ;W & M ARE DECnet'S T5 & T6
MOVE P1,T1 ;SAVE THE COUNT
MOVEI T2,1(T1) ;T2 GETS NUMBER OF WORDS.
CALL GETWDS## ;GO GET SOME FREE CORE
RET ;TELL CALLER WE LOST
XMOVEI T1,(T1) ;MAKE EXTENDED ADDR IN SECTION 1
HRLI P1,'NRT' ;MAKE A TEST THINGY
MOVEM P1,(T1) ;STORE COUNT IN RH OF OVERHEAD WORD
AOJ T1, ;RETURN POINTER TO USER PART OF BLOCK
;Zero the words.
PUSH P,T1 ;SAVE USER ADDRESS OF NEW BLOCK
HRRZ T2,P1 ;GET THE LENGTH OF THE BLOCK
ADD T2,T1 ;AND POINT TO THE LAST WORD IN THE BLOCK
SOJ T2, ;POINT TO LAST WORD
MOVEI T3,0 ;VALUE TO SMEAR INTO BLOCK
SNCALL (DNSWDS,MS.HGH) ;SMEAR ZEROES INTO BLOCK
JRST TPOPJ1## ;RESTORE ADDRESS AND GIVE GOOD RETURN
SUBTTL NRTFWD - Free Some Words
;NRTFWD - Free what NRTGWD took away
;
; Call:
; T1/ Pointer to some words
;
; Return:
; RET ;ALWAYS
;
; Uses: T1,T2
NRTFWD: SOJLE T1,[BUG.(CHK,NRTFW0,NRTSER,SOFT,<Tried to free words at zero>,,<
Cause: This BUG is not documented yet.
>,CPOPJ)]
;POINT TO HEADER WORD
HLRZ T3,(T1) ;GET THINGY TO CHECK AGAINST.
CAIE T3,'NRT' ;IS IT WHAT WE PUT THERE?
BUG. CHK,NRTBPM,NRTSER,SOFT,<Bad pointer passed to memory manager>,,<
Cause: This BUG is not documented yet.
>,CPOPJ
HRRZ T2,(T1) ;GET THE WORD COUNT FOR GIVWDS
AOJ T2, ;ADD IN WORD OF OVERHEAD
EXCH T1,T2 ;CORE1 WANTS THESE IN OTHER ORDER
HRRZS T2 ;RESTORE ADDRESS TO SECTION 0
PJRST GIVWDS## ;LET GO OF OUR CORE AND RETURN
SUBTTL End of Program
.XCMSY ;XCREF MACSYM TEMPS
;PUT A LABEL ON THE LITERAL POOL
NRTLIT: XLIST ;DON'T LIST THE LITERALS
LIT
LIST
END