mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-01 17:26:38 +00:00
5600 lines
185 KiB
Plaintext
5600 lines
185 KiB
Plaintext
TITLE .NET SWIL network operations
|
||
SUBTTL Robert Houk/RDH
|
||
|
||
SEARCH SWIDEF, SWIL ;SWIL PACKAGE DEFINITIONS
|
||
SEARCH JOBDAT, MACTEN, UUOSYM ;STANDARD DEFINITIONS
|
||
|
||
SALL ;PRETTY LISTINGS
|
||
.DIREC FLBLST ;PRETTIER LISTINGS
|
||
|
||
TWOSEG 400000
|
||
|
||
|
||
COMMENT \
|
||
|
||
COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1987,1988. ALL RIGHTS RESERVED.
|
||
|
||
|
||
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
|
||
ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
|
||
INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
|
||
COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
|
||
OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
|
||
TRANSFERRED.
|
||
|
||
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
|
||
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
|
||
CORPORATION.
|
||
|
||
DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
|
||
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
|
||
|
||
\
|
||
SUBTTL Version and Revision History
|
||
|
||
MAJVER==13 ;MAJOR VERSION LEVEL
|
||
MINVER==0 ;MINOR (MAINTENANCE RELEASE) LEVEL
|
||
CSTVER==0 ;CUSTOMER VERSION (WHO LAST . . .)
|
||
EDTVER==1050 ;EDIT LEVEL
|
||
|
||
%%NET==:<BYTE (3)CSTVER(9)MAJVER(6)MINVER(18)EDTVER>
|
||
%%SWIL==:%%SWIL ;SHOW (AND SYNCHRONIZE) SWIL VERSION
|
||
|
||
IF2,< PURGE CSTVER,MAJVER,MINVER,EDTVER>
|
||
|
||
|
||
|
||
;INITIAL CREATION
|
||
|
||
;1000 RDH 01-Jan-84
|
||
; Incorporate into SWIL %12(1000), sync edit level at 1000.
|
||
|
||
;1012 DRB 25-Jan-85
|
||
; Add scheduler calls to ANF-10 non-blocking I/O. Allow non-blocking
|
||
; NSP. enter passive.
|
||
|
||
;1013 DRB 25-Jan-85
|
||
; XDBUF3 is clearing IO.ENM, before we're sure that the message is
|
||
; going to make it out. If we retry, due to non-blocking I/O, EOM
|
||
; isn't getting set. Rearrange code so that it works.
|
||
|
||
;1020 RDH 12-Aug-85
|
||
; "Managed Memory" is lost when doing ANF network I/O.
|
||
|
||
;1022 LEO 09-Sep-85
|
||
; Do Copyrights.
|
||
|
||
;1043 BSC 24-Apr-86
|
||
; Add a DAP message trace feature which is useful for debugging.
|
||
; Refer to edit [1043] in SWIL.MAC for full details.
|
||
|
||
;1045 BSC 18-Jun-86
|
||
; Add code to support transmission of CONTINUE interrupt messages.
|
||
|
||
;1050 BAH 21-Jan-87
|
||
; Change TRC macro to $TRACE.
|
||
SUBTTL DAP Message Service Routines
|
||
|
||
;RDSTS -- READ AND TRY TO MAKE SENSE OF RECEIVED DAP STATUS
|
||
;CALL IS:
|
||
;
|
||
; PUSHJ P,RDSTS
|
||
; error return
|
||
; normal return
|
||
;
|
||
;RDSTS will read in the status message from the network stream via
|
||
;RDDAP, so call RDSTS upon receipt of the $DHSTS code.
|
||
;
|
||
;The error return is taken if the network dies or the status message
|
||
;makes no sense (uses a reserved code, etc.)
|
||
;
|
||
;On normal return M0 will contain the translated 18-bit status code.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
ENTRY .RDSTS
|
||
INTERN RDSTS0, RDSTS1
|
||
|
||
.RDSTS: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RDSTS0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
RDSTS1: SKIPLE T2,.IODIM(IO) ;GET INPUT MESSAGE TYPE FROM RDMSG
|
||
CAIE T2,$DHSTS ;IT HAD BETTER BE STATUS!
|
||
STOPCD <RDSTS called without a status message>
|
||
SETZB T3,T4 ;INITIALIZE SOME 0 VALUES
|
||
MOVDM T3,STC ;CLEAR OUT STATUS CODE FIELD
|
||
MOVDM T3,SRA ;CLEAR OUT RECORD ADDRESS FIELD
|
||
MOVDM T3,SRN ;CLEAR OUT RECORD NUMBER FIELD
|
||
MOVDM T3,STV ;CLEAR OUT SECONDARY STATUS FIELD
|
||
|
||
;READ IN THE STATUS MESSAGE
|
||
|
||
PUSHJ P,RDDAP1 ;SLURP UP THE STATUS MESSAGE
|
||
POPJ P, ;SIGH
|
||
PJRST RDSTC1 ;AND CONVERT IT TO ERROR/EXCEPTION CODE
|
||
;RDSTC -- TRANSLATE DAP STATUS CODE INTO INTERNAL ERROR/EXCEPTION CODE
|
||
;CALL IS:
|
||
;
|
||
; PUSHJ P,RDSTC
|
||
; error return
|
||
; normal return
|
||
;
|
||
;RDSTC takes the DAP error status from the I/O CDB (as read in by RDSTS)
|
||
;and translates it into NIP/NFT internal error/exception code. The new
|
||
;code is always returned in register M0.
|
||
;
|
||
;The error return is taken if the DAP status code is illegal or otherwise
|
||
;unintelligible.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
ENTRY .RDSTC
|
||
INTERN RDSTC0, RDSTC1
|
||
|
||
.RDSTC: PUSHJ P,.SACIO## ;CONVERT TO I/O CONTEXT
|
||
RDSTC0: ;WE DON'T STOMP ON THE P'S HERE
|
||
RDSTC1: LDB T1,PDPEMA ;DAP "MACCODE" FIELD
|
||
LDB T2,PDPEMI ;DAP "MICCODE" FIELD
|
||
LDB T3,PDPEMT ;MESSAGE TYPE WITHIN MICCODE
|
||
LDB T4,PDPEMF ;MESSAGE FIELD WITHIN MESSAGE TYPE
|
||
PJRST @RDSTCX(T1) ;DISPATCH ON STATUS CLASS
|
||
|
||
|
||
;STATUS CODE FIELD POINTERS
|
||
|
||
PDPEMA::POINT 04,.IDSTC(IO),23;DAP "MACCODE" FIELD
|
||
PDPEMI::POINT 12,.IDSTC(IO),35;DAP "MICCODE" FIELD
|
||
PDPEMT::POINT 06,.IDSTC(IO),29;MESSAGE TYPE WITHIN MICCODE
|
||
PDPEMF::POINT 06,.IDSTC(IO),35;MESSAGE FIELD WITHIN MESSAGE TYPE
|
||
|
||
|
||
;STATUS MACRO-CODE DISPATCH
|
||
|
||
RDSTCX: IFIW RD00S ;OPERATION IN PROGRESS
|
||
IFIW RD01S ;OPERATION SUCCESSFUL
|
||
IFIW RD02S ;UNSUPPORTED FUNCTION
|
||
IFIW RD03S ;RESERVED
|
||
IFIW RD04S ;FILE ACCESS
|
||
IFIW RD05S ;I/O TRANSMISSION ERROR
|
||
IFIW RD06S ;I/O OPERATION WARNING
|
||
IFIW RD07S ;ERROR CLOSING FILE
|
||
IFIW RD10S ;DAP MESSAGE SYNTAX ERROR
|
||
IFIW RD11S ;DAP MESSAGE FIELD ERROR
|
||
IFIW RD12S ;DAP MESSAGE OUT OF SYNC
|
||
IFIW RD13S ;RESERVED
|
||
IFIW RD14S ;RESERVED
|
||
IFIW RD15S ;RESERVED
|
||
IFIW RD16S ;CUSTOMER-DEFINED
|
||
IFIW RD17S ;CUSTOMER-DEFINED
|
||
;00 - OPERATION PENDING
|
||
|
||
RD00S: MOVEI M0,$EGOIP ;"OPERATION IN PROGRESS" (AS A WILD GUESS)
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;01 - OPERATION SUCCESSFUL
|
||
|
||
RD01S: MOVEI M0,$EGAOK ;"A-OK" (AS A WILD GUESS)
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;02 - UNSUPPORTED DAP FUNCTION
|
||
|
||
RD02S: MOVEI M0,$EERDE ;REMOTE DAP ERROR
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;03 - XXX - RESERVED
|
||
|
||
RD03S: MOVEI M0,$EEUDS ;UNKNOWN DAP STATUS
|
||
POPJ P, ;RETURN ERROR
|
||
|
||
|
||
|
||
;04 - FILE ACCESS ERROR
|
||
|
||
RD04S: MOVEI T4,DS2EF ;CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO FILE ACCESS ERROR
|
||
MOVEI T1,$EFDAP ;BIZARRE DAP STATUS ERROR
|
||
MOVE M0,T1 ;RETURN STATUS IN M0
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;05 - I/O DATA TRANSMISSION ERROR
|
||
|
||
RD05S: MOVEI T4,DS2EI ;CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO I/O ERROR
|
||
JRST RD05S2 ;NOT I/O CODE - MAYBE FILE CODE?
|
||
MOVE M0,T1 ;POSITION IN M0
|
||
JRST .POPJ1## ;AND RETURN STATUS
|
||
|
||
RD05S2: MOVEI T4,DS2EF ;FILE-LEVEL CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO FILE ERROR
|
||
MOVEI T1,$EIDAP ;BIZARRE DAP I/O STATUS ERROR
|
||
MOVE M0,T1 ;POSITION IN M0
|
||
JRST .POPJ1## ;AND RETURN STATUS
|
||
|
||
|
||
|
||
;06 - I/O DATA TRANSMISSION WARNING
|
||
|
||
RD06S: MOVEI T4,DS2EI ;CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO I/O ERROR
|
||
JRST RD06S2 ;TRY FOR FILE ERROR
|
||
MOVE M0,T1 ;POSITION IN M0
|
||
JRST .POPJ1## ;AND RETURN STATUS
|
||
|
||
RD06S2: MOVEI T4,DS2EF ;FILE-LEVEL CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO FILE ERROR
|
||
MOVEI T1,$EIDAP ;BIZARRE DAP I/O STATUS ERROR
|
||
MOVE M0,T1 ;POSITION IN M0
|
||
JRST .POPJ1## ;AND RETURN STATUS
|
||
|
||
|
||
|
||
;07 - FILE/I/O CLOSE ERROR
|
||
|
||
RD07S: MOVEI T4,DS2EI ;CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO I/O ERROR
|
||
JRST RD07S2 ;TRY FOR FILE ERROR
|
||
MOVE M0,T1 ;POSITION IN M0
|
||
JRST .POPJ1## ;AND RETURN STATUS
|
||
|
||
RD07S2: MOVEI T4,DS2EF ;FILE-LEVEL CONVERSION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO CONVERT TO FILE ERROR
|
||
MOVEI T1,$EFDAP ;BIZARRE DAP FILE STATUS ERROR
|
||
MOVE M0,T1 ;POSITION IN M0
|
||
JRST .POPJ1## ;AND RETURN STATUS
|
||
|
||
|
||
|
||
;10 - DAP SYNTAX ERROR
|
||
|
||
RD10S: MOVEI M0,$EERDE ;REMOTE DAP ERROR
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;11 - DAP FIELD ERROR
|
||
|
||
RD11S: MOVEI M0,$EERDE ;REMOTE DAP ERROR
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;12 - DAP MESSAGE OUT OF SYNC
|
||
|
||
RD12S: MOVEI M0,$EERDE ;REMOTE DAP ERROR
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;13 - XXX - RESERVED
|
||
|
||
RD13S: MOVEI M0,$EEUDS ;UNKNOWN DAP STATUS
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;14 - XXX - RESERVED
|
||
|
||
RD14S: MOVEI M0,$EEUDS ;UNKNOWN DAP STATUS
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;15 - XXX - RESERVED
|
||
|
||
RD15S: MOVEI M0,$EEUDS ;UNKNOWN DAP STATUS
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;16 - XXX - CUSTOMER DEFINED
|
||
|
||
RD16S: MOVEI M0,$EEUDS ;UNKNOWN DAP STATUS
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
|
||
|
||
|
||
;17 - XXX - CUSTOMER DEFINED
|
||
|
||
RD17S: MOVEI M0,$EEUDS ;UNKNOWN DAP STATUS
|
||
JRST .POPJ1## ;RETURN STATUS
|
||
;CONVERSION TABLE: DAP STATUS TO FILE ACCESS ERROR
|
||
|
||
DS2EF:: $EFRAE,,$DSACC ;"GENERIC" REMOTE FILE ACCESS ERROR
|
||
$EFNSD,,$DSDEV ;BAD DEVICE; NO SUCH DEVICE
|
||
$EFTBL,,$DSDME ;SYSTEM DYNAMIC MEMORY EXHAUSTED
|
||
$EFDNF,,$DSDNF ;DIRECTORY NOT FOUND
|
||
$EFAEF,,$DSFEX ;(DUPL) ALREADY EXISTING FILE
|
||
$EFFLK,,$DSFLK ;FILE LOCKED BY ANOTHER USER
|
||
$EFFNF,,$DSFNF ;FILE NOT FOUND
|
||
$EFNRM,,$DSFUL ;NO ROOM - DEVICE/FILE IS FULL
|
||
$EFFUL,,$DSFUL ;DEVICE/FILE IS FULL
|
||
$EFPRT,,$DSPRV ;PRIVILEGE VIOLATION
|
||
$EFILU,,$DSSYS ;SYSTEM DIRECTIVE ERROR
|
||
$EFWLK,,$DSWLK ;DEVICE IS WRITE-LOCKED
|
||
$EFRIB,,$DSIFA ;ILL FILE ATTR; CORRUPT FILE HEADER
|
||
$EFQTA,,$DSQTA ;QUOTA EXCEEDED
|
||
$EFFBM,,$DSFBM ;FILE BEING MODIFIED (ANOTHER WRITER)
|
||
$EFDNA,,$DSDNA ;DEVICE NOT AVAILABLE
|
||
$EFNSD,,$DSDNF ;DEVICE NOT FOUND (NO SUCH DEVICE)
|
||
$EFPOA,,$DSPOA ;PARTIAL ALLOCATION ONLY
|
||
$EFBNF,,$DSBNF ;SPECIFIED BLOCK NOT FREE
|
||
$EFCSD,,$DSCSD ;CAN'T SUPERSEDE DIRECTORY FILE
|
||
$EFDNE,,$DSDNE ;CAN'T DELETE NON-EMPTY DIRECTORY FILE
|
||
$EFSNF,,$DSSNF ;SUB-FILE-DIRECTORY NOT FOUND
|
||
$EFSLE,,$DSSLE ;SEARCH LIST EMPTY
|
||
$EFLVL,,$DSLVL ;SUB-FILE-DIRECTORIES NESTED TOO DEEPLY
|
||
$EFNCE,,$DSNCE ;NO-CREATE FOR ENTIRE SEARCH LIST
|
||
$EFFCU,,$DSFCU ;CAN'T UPDATE FILE
|
||
$EFENC,,$DSENC ;EXCEEDED NETWORK CAPACITY
|
||
$EFTNA,,$DSTNA ;TSK DEVICE NOT AVAILABLE
|
||
$EFNSN,,$DSNSN ;NO SUCH NODE
|
||
$EFSIU,,$DSSIU ;SUB-FILE-DIRECTORY IN USE ON RENAME
|
||
$EFNDR,,$DSNDR ;CAN'T DELETE FILE - NDR LOCK SET
|
||
$EFJCH,,$DSJCH ;TOO MANY SIMULTANEOUS FILE ACCESSES
|
||
$EFSSL,,$DSSSL ;CAN'T RENAME SUB-FILE-DIRECTORY TO LOWER LVL
|
||
$EFDDU,,$DSDDU ;DEVICE "DOWN" AND UNUSEABLE
|
||
$EFDRS,,$DSDRS ;DEVICE IS RESTRICTED
|
||
$EFDCM,,$DSDCM ;DEVICE CONTROLLED BY MDA, NOT ASSIGNABLE
|
||
$EFDAJ,,$DSDAJ ;DEVICE ASSIGNED TO ANOTHER JOB
|
||
$EFIDM,,$DSIDM ;ILLEGAL I/O DATA MODE
|
||
|
||
;"DUPLICATES", SEPARATED TO PRIORITIZE ERRORS FOR FAL
|
||
|
||
$EFAEF,,$DSCFS ;CREATED FILE SUPERSEDED EXTANT FILE
|
||
$EFAEF,,$DSRFE ;RENAME TO EXTANT FILE
|
||
0
|
||
|
||
|
||
|
||
;CONVERSION TABLE: DAP STATUS TO I/O TRANSMISSION ERROR
|
||
|
||
DS2EI:: $EIEOF,,$DSEOF ;END OF FILE
|
||
$EIFUL,,$DSFUL ;DEVICE FULL
|
||
$EIBKT,,$DSRTB ;RECORD/BLOCK TOO LARGE
|
||
$EIHWL,,$DSWLK ;DEVICE IS (HARDWARE) WRITE-LOCKED
|
||
$EIDEV,,$DSHDE ;HARD DEVICE ERROR
|
||
$EIDAT,,$DSPAR ;DEVICE PARITY ERROR
|
||
$EIEOV,,$DSEOV ;END OF VOLUME
|
||
$EICKE,,$DSCKE ;NETWORK FILE DATA CRC (CHECKSUM) ERROR
|
||
$EIQTA,,$DSQTA ;USER QUOTA EXCEEDED
|
||
$EILLE,,$DSLLE ;LINEPRINTER PAGE LIMIT EXCEEDED
|
||
$EIVFE,,$DSVFE ;LINEPRINTER VFU FORMAT ERROR
|
||
$EILUC,,$DSLUC ;LINEPRINTER "UNDEFINED CHARACTER" ERROR
|
||
$EIVRP,,$DSVRP ;LINEPRINTER VFU RAM PARITY ERROR
|
||
|
||
$EIRIE,,$DSRER ;GENERIC/UNSPECIFIED READ ERROR
|
||
$EIRIE,,$DSWER ;GENERIC/UNSPECIFIED WRITE ERROR
|
||
|
||
;"DUPLICATES", SEPARATED TO PRIORITIZE ERRORS FOR FAL
|
||
|
||
$EISWL,,$DSWLK ;DEVICE IS (SOFTWARE) WRITE-LOCKED
|
||
0
|
||
;RDDAT -- START READING A DAP DATA MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T2,<CDB>
|
||
; PUSHJ P,RDDAT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return M0 contains an error code (network died, etc.).
|
||
;
|
||
;On normal return the DAP input routines (i.e., RDBYT) are ready to
|
||
;read and return data bytes. The DAP DATA RCN (record number) field
|
||
;returned in T2/T3.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
ENTRY .RDDAT
|
||
INTERN RDDAT0, RDDAT1
|
||
|
||
.RDDAT: PUSHJ P,.SACIO## ;SETUP I/O CDB ADDRESS
|
||
RDDAT0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
RDDAT1: SKIPLE T2,.IODIM(IO) ;GET CURRENT INPUT MESSAGE TYPE
|
||
CAIE T2,$DHDAT ;IS IT DATA?
|
||
STOPCD <Not a DAP DATA message in RDDAT>
|
||
PUSHJ P,RDDAP2 ;HANDLE TEMPLATED PORTION OF DATA MESSAGE
|
||
POPJ P, ;SOMETHING BAD HAPPENED
|
||
MOVD T2,RCN ;GET RECORD NUMBER (IF ANY)
|
||
RCV < PUSHJ P,TRCRCV > ;TRACE RECEIVED DATA
|
||
JRST .POPJ1## ;READY TO EXTRACT THE DATA BYTES
|
||
;RDDAP -- READ AND STORE A GENERIC DAP MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<code>
|
||
; PUSHJ P,RDDAP
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB, and <code> is the
|
||
;DAP message code of the incoming DAP message. Data messages
|
||
;(<code> = $DHDAT) are illegal.
|
||
;
|
||
;On error return, M0 contains an error code (network died or some sort
|
||
;of DAP error such as message too short). If the error was DAPpish in
|
||
;origin, a status message will have been sent to the other side telling
|
||
;of the error.
|
||
;
|
||
;On normal return the DAP message has been read into the .IODAP area in
|
||
;the I/O CDB, ready to be translated into the usual CDB stuff.
|
||
;
|
||
;Uses acs T1, T2, T3, T4
|
||
|
||
ENTRY .RDDAP
|
||
INTERN RDDAP0, RDDAP1
|
||
|
||
.RDDAP: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RDDAP0: PUSHJ P,.SAVE4## ;SAVE LOTS OF ACS
|
||
RDDAP1: CAIN T2,$DHDAT ;BETTER NOT BE A DATA MESSAGE
|
||
STOPCD <RDDAP called for DATA message>
|
||
RDDAP2: MOVEI T4,DAPIDX ;DAP INDEX TABLE
|
||
PUSHJ P,.CFIND## ;FIND THE INDEX ENTRY FOR THIS MESSAGE TYPE
|
||
PJRST RDEUM ;ERROR - UNKNOWN MESSAGE TYPE
|
||
HRRZM T1,.IODRX(IO) ;SET CURRENT RDDAP EXECUTION INDEX
|
||
HRRZM T2,.IODIM(IO) ;SET CURRENT INPUT MESSAGE TYPE
|
||
|
||
;LOOP READING FIELDS FROM THE DAP INPUT MESSAGE
|
||
|
||
RDDAP3: PUSHJ P,RDBYT0 ;GET NEXT DAP BYTE
|
||
JRST RDDAP7 ;END OF MESSAGE ACCEPTABLE HERE
|
||
PUSHJ P,RDBYR0 ;SAVE BYTE TO BE RE-READ
|
||
STOPCD ;CAN'T HAPPEN
|
||
AOS P1,.IODRX(IO) ;ADVANCE TO NEXT FIELD
|
||
MOVE T1,DAPXCT(P1) ;EXECUTION TABLE ENTRY FOR THIS FIELD
|
||
LDB T2,[POINTR T1,DX$COD] ;FIELD "NUMBER"
|
||
LDB T3,[POINTR T1,DX$TYP] ;FIELD "TYPE"
|
||
CAILE T3,$DXTMX ;RANGE CHECK AGAINST KNOWN FIELDS
|
||
STOPCD <RDDAP DX$TYP field entry too big>
|
||
JUMPE T3,RDDAP5 ;END OF MESSAGE TEMPLATE?
|
||
.XCREF $DXTMS ;CREF REFERENCE TO SYMBOLIC NAME
|
||
MOVEM T2,.IODRF(IO) ;SAVE IN CASE OF ERROR
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;CALL FIELD PROCESSOR WITH P1/DAPXCT INDEX AND T1/DAPXCT TABLE ENTRY
|
||
|
||
RCV < PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX(P1) ;ADDR OF FIELD DESCRIPTIVE TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
MOVE T1,DAPXCT(P1) > ;WE USED T1 SO RETRIEVE EXECUTION TABLE ENTRY
|
||
PUSHJ P,@RDDAPX(T3) ;DISPATCH ON FIELD TYPE
|
||
POPJ P, ;ERROR SOMEWHERE
|
||
JRST RDDAP3 ;LOOP BACK FOR REST OF THE MESSAGE
|
||
|
||
;HERE WHEN THE INPUT DAP MESSAGE SHOULD BE EXHAUSTED (SINCE OUR TEMPLATE
|
||
;USED UP ALL ITS FIELD DEFINITIONS).
|
||
|
||
RDDAP5: MOVE T2,.IODIM(IO) ;GET INPUT MESSAGE TYPE
|
||
CAIN T2,$DHDAT ;DATA MESSAGE?
|
||
JRST .POPJ1## ;YES, SOMEONE ELSE READS THE REST
|
||
PUSHJ P,RDBYT1 ;SEE IF ANY MORE DATA
|
||
JRST RDDAP7 ;PROBABLY NOT
|
||
HRRZ T1,.IODIM(IO) ;TOO MUCH DATA PRESENT
|
||
CAIE T1,$DHCFG ;IN CONFIGURATION MESSAGE?
|
||
PJRST RDEUF ;NO, ERROR - UNKNOWN FIELD IN MESSAGE
|
||
PJRST RDEAT1 ;YES, OK, JUST EAT EXCESS CONFIGURATION
|
||
|
||
RDDAP7: JUMPE M0,.POPJ1## ;IF OUT OF DAP DATA THEN WE'RE HAPPY
|
||
POPJ P, ;OTHERWISE NETWORK DIED, ERROR
|
||
|
||
|
||
;DAP MESSAGE FIELD PROCESSOR DISPATCH TABLE
|
||
|
||
;EACH FIELD PROCESSING ROUTINE IS ENTERED WITH:
|
||
; T1/DAPXCT TABLE ENTRY FOR THE FIELD
|
||
; P1/DAPXCT TABLE INDEX FOR THE FIELD
|
||
;ACS T1 - T4, AND P1 - P4 ARE AVAILABLE FOR USAGE WITHIN THE VARIOUS
|
||
;FIELD PROCESSING ROUTINES
|
||
|
||
RDDAPX: RD00T ;00 - START OF DAP MESSAGE TEMPLATE
|
||
RD01T ;01 - ASCII TEXT
|
||
RD02T ;02 - BINARY DATA
|
||
RD03T ;03 - COMPRESSED (1 WORD/5 BYTES) BINARY
|
||
RD04T ;04 - FLAGS (OR BIT MAP)
|
||
RD05T ;05 - IMAGE 8-BIT BYTES
|
||
RD06T ;06 - MENU FIELD FOR REST OF MESSAGE
|
||
RD07T ;07 - DATE/TIME IN ASCII
|
||
;RD00T - START OF MESSAGE TEMPLATE IN EXECUTION TABLE
|
||
|
||
RD00T: STOPCD <RD00T dispatch in RDDAP>
|
||
;RD01T - ASCII TEXT FIELD
|
||
|
||
RD01T: PUSHJ P,TSAV11## ;NEED A SCRATCH LOCATION
|
||
LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
LDB T4,[POINTR T1,DX$IOX] ;FIELD OFFSET INTO .IODAP
|
||
ADD T4,[POINT 7,.IODAP(IO)] ;MAKE INTO BYTE POINTER
|
||
SETZM -T1(P) ;NO TRAILING SPACE YET
|
||
TXNE T1,DX$XTN ;EXTENSIBLE ASCII?
|
||
JRST RD01T5 ;YES
|
||
TXNN T1,DX$VAR ;VARIABLE LENGTH ASCII STRING?
|
||
NORCV < JRST RD01T4 > ;NO, FIXED LENGTH
|
||
RCV < JRST RD01T2 > ;NO, FIXED LENGTH
|
||
PUSHJ P,RDBYT1 ;YES, READ STRING LENGTH
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
CAMLE T2,T3 ;FIELD LENGTH WITHIN SPECS?
|
||
PJRST RDEIE ;NO, TOO BIG, ERROR IN FIELD
|
||
EXCH T3,T2 ;YES, OK, SET REAL FIELD LENGTH
|
||
SUB T2,T3 ;T2:=SPACE LEFT OVER
|
||
MOVEM T2,-T1(P) ;SET TRAILING SPACE NEEDING CLEARING
|
||
RCV < MOVEI T1,[ASCIZ \ [var len ASCII, len= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS VAR LENGTH ASCII
|
||
PUSHJ P,VARLEN > ;TYPE OUT THE VARIABLE LENGTH FROM T3
|
||
JRST RD01T4 ;ENTER LOOP
|
||
|
||
RCV <
|
||
RD01T2: MOVEI T1,[ASCIZ \ [fix len ASCII, len from DAP spec= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS FIXED LENGTH ASCII
|
||
PUSHJ P,FIXLEN ;TYPE OUT THE FIXED LENGTH
|
||
JRST RD01T4 > ;ENTER LOOP
|
||
|
||
;LOOP READING FIXED/VARIABLE ASCII INPUT
|
||
|
||
RD01T3: PUSHJ P,RDBYT1 ;READ NEXT ASCII BYTE
|
||
PJRST RDEIE ;SOMETHING'S WRONG
|
||
RCV < PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
PUSHJ P,.THEXB > ;TYPE-OUT BYTE FROM T2
|
||
IDPB T2,T4 ;STASH AWAY THIS CHARACTER
|
||
RD01T4: SOJGE T3,RD01T3 ;LOOP FOR REST OF FIELD
|
||
MOVE T3,-T1(P) ;AMOUNT OF SPACE STILL NEEDING CLEARING
|
||
JRST RD01T7 ;GO CLEAR THAT SPACE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;LOOP READING EXTENSIBLE ASCII INPUT
|
||
|
||
RD01T5:
|
||
RCV < MOVEI T1,[ASCIZ \ [extensible ASCII]\]
|
||
PUSHJ P,.TSTRG## > ;TELL USER IT IS EXTENSIBLE ASCII
|
||
|
||
RD01T6: PUSHJ P,RDBYT1 ;READ NEXT INPUT BYTE
|
||
PJRST RDEIE ;ERROR SOMEWHERE
|
||
RCV < PUSHJ P,EXTENS > ;TYPE EXTENSIBLE BYTE FROM T2
|
||
IDPB T2,T4 ;STASH AWAY THIS CHARACTER
|
||
TRNE T2,200 ;EXTENDED BYTE?
|
||
SOJG T3,RD01T6 ;YES, READ MORE
|
||
TRNE T2,200 ;TRULY END OF INPUT?
|
||
PJRST RDEIF ;NO, TOO MUCH, ERROR IN FIELD
|
||
RD01T7: SETZ T2, ;YES, A TERMINATING NULL
|
||
IDPB T2,T4 ;TO TERMINATE THE STRING
|
||
SOJGE T3,.-1 ;CLEAR REST OF STRING
|
||
RCV < PUSHJ P,ASCSTR ;TYPE ASCII STRING FROM .IODAP(IO)
|
||
PUSHJ P,.TCRLF## > ;FINISH THE LINE NEATLY
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;RD02T - BINARY INPUT FIELD
|
||
;RD03T - COMPRESSED BINARY INPUT FIELD
|
||
|
||
RD02T: ;THEY'RE THE SAME, ALMOST
|
||
RD03T: LDB P3,[POINTR T1,DX$LNB] ;FIELD LENGTH (MAX IN DAP BYTES)
|
||
CAILE P3,^D9 ;WILL IT FIT THE ALGORITHM BELOW?
|
||
STOPCD <Binary DAP field larger than 9 bytes in RD03T>
|
||
SETZB T3,T4 ;INITIALIZE BINARY VALUE
|
||
TXNE T1,DX$XTN ;EXTENSIBLE BINARY FORMAT?
|
||
JRST RD03T5 ;YES
|
||
MOVEI P4,^D9 ;MAXIMUM POSSIBLE LENGTH
|
||
SUB P4,P3 ;P4:=BYTES NOT USED IN 72-BIT DOUBLE-WORD
|
||
TXNN T1,DX$VAR ;VARIABLE LENGTH BINARY FORMAT?
|
||
NORCV < JRST RD03T3 > ;NO, FIXED LENGTH
|
||
RCV < JRST RD03T1 > ;NO, FIXED LENGTH
|
||
PUSHJ P,RDBYT1 ;READ FIELD LENGTH
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
MOVE P3,T2 ;SET ACTUAL FIELD LENGTH
|
||
RCV < MOVEI T1,[ASCIZ \ [var len bin, len= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS VAR LENGTH BINARY
|
||
MOVE T3,P3 ;GET LENGTH IN T3 FOR TYPING BY VARLEN
|
||
PUSHJ P,VARLEN > ;TYPE THE VARIABLE LENGTH
|
||
MOVEI P4,^D9 ;MAX FIELD LENGTH (FOR TWO WORDS)
|
||
SUB P4,P3 ;BYTES NOT USED
|
||
SETZB T3,T4 ;INITIALIZE BINARY VALUE
|
||
JRST RD03T3 ;ENTER LOOP
|
||
|
||
|
||
RCV <
|
||
RD03T1: MOVEI T1,[ASCIZ \ [fix len bin, len from DAP spec= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS FIXED LENGTH BINARY
|
||
PUSHJ P,FIXLEN ;TYPE THE FIXED LENGTH
|
||
SETZB T3,T4 ;INITIALIZE BINARY VALUE
|
||
JRST RD03T3 > ;ENTER LOOP
|
||
|
||
;LOOP READING FIXED/VARIABLE BINARY INPUT BYTES
|
||
|
||
RD03T2: PUSHJ P,RDBYT1 ;READ NEXT BYTE
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
RCV < PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
PUSHJ P,.THEXB > ;TYPE-OUT BYTE FROM T2
|
||
LSHC T3,-^D8 ;MAKE ROOM FOR NEXT HIGHER-ORDER BYTE
|
||
LSH T3,^D8 ;SLIP BACK AND
|
||
LSHC T2,-^D8 ;PICK UP THE BYTE
|
||
RD03T3: SOJGE P3,RD03T2 ;LOOP FOR REST OF FIELD
|
||
IMULI P4,^D8 ;COUNT OF BITS NOT USED IN DOUBLE-WORD VALUE
|
||
MOVNS P4 ;NEGATIVE BIT COUNT
|
||
LSHC T3,0(P4) ;RIGHT-JUSTIFY FIELD
|
||
TLNE T3,(1B0!1B1) ;MORE THAN 70 BITS?
|
||
STOPCD <Binary DAP value greater than 70 bits in RD03T>
|
||
RCV < PUSHJ P,BINFLD ;TYPE OUT BINARY FIELD FROM T3 & T4
|
||
PUSHJ P,.TCRLF## > ;FINISH OFF THE LINE
|
||
LSHC T3,1 ;PUT 35-BITS PER WORD
|
||
LSH T4,-1 ;-10 FORMAT DOUBLE PRECISION INTEGER
|
||
LDB T1,[POINTR DAPXCT(P1),DX$LNB] ;SIZE OF FIELD IN 8-BIT BYTES
|
||
CAIG T1,4 ;MORE THAN ONE -10 WORDS' WORTH?
|
||
MOVEI T1,1 ;NO, ONE WORD IS SUFFICIENT
|
||
CAILE T1,4 ;LESS THAN TWO -10 WORDS' WORTH?
|
||
MOVEI T1,2 ;NO, TWO WORDS NEEDED
|
||
LDB T2,[POINTR DAPXCT(P1),DX$TYP] ;FIELD TYPE
|
||
CAIN T2,$DXTCN ;COMPRESSED 1 WORD VALUE?
|
||
MOVEI T1,1 ;YES, SIZE IS ONE WORD THEN
|
||
LDB T2,[POINTR DAPXCT(P1),DX$IOX] ;OFFSET INTO .IODAP AREA
|
||
ADDI T2,.IODAP(IO) ;RELOCATE INTO I/O CDB
|
||
CAIN T1,1 ;ONE-WORD VALUE?
|
||
MOVEM T4,(T2) ;YES
|
||
CAIN T1,2 ;TWO-WORD VALUE?
|
||
DMOVEM T3,(T2) ;YES
|
||
LDB T1,[POINTR DAPXCT(P1),DX$TYP] ;FIELD TYPE AGAIN
|
||
CAIN T1,$DXTCN ;COMPRESSED BINARY?
|
||
CAIN T3,0 ;YES, DID DAP INPUT FIT?
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
STOPCD <Compressed DAP binary field exceeded 36 bits in RD03T>
|
||
|
||
;LOOP READING EXTENSIBLE BINARY FIELD
|
||
|
||
RD03T5: STOPCD <Extensible DAP binary field encountered in RD03T>
|
||
;RD04T - FLAGS FIELD (ALSO MENU, SEE RD06T)
|
||
|
||
RD04T: LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
LDB T4,[POINTR T1,DX$IOX] ;FIELD STORAGE IN .IODAP
|
||
ADD T4,[POINT 7,.IODAP(IO)] ;MAKE INTO BYTE POINTER
|
||
TXNE T1,DX$XTN ;EXTENSIBLE FIELD?
|
||
JRST RD04T5 ;YES
|
||
STOPCD <Fixed/variable length DAP flags field encountered in RD04T>
|
||
|
||
;LOOP READING EXTENSIBLE FLAG BYTES
|
||
|
||
RD04T5:
|
||
RCV < MOVEI T1,[ASCIZ \ [extensible flags field]\] ;TELL USER EXTENSIBLE FIELD
|
||
PUSHJ P,.TSTRG## > ; . . .
|
||
RD04T6: PUSHJ P,RDBYT1 ;READ NEXT FLAG BYTE
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
RCV < PUSHJ P,EXTENS > ;TYPE OUT EXTENSIBLE BYTE FROM T2
|
||
IDPB T2,T4 ;STORE FLAGS
|
||
TRNE T2,200 ;EXTENDED BYTE?
|
||
SOJG T3,RD04T6 ;YES, LOOP BACK AND FINISH THE FIELD
|
||
TRNE T2,200 ;REALLY THE END?
|
||
PJRST RDEIF ;ERROR IN FIELD - TOO BIG
|
||
TDZA T2,T2 ;NULL BYTE
|
||
IDPB T2,T4 ;CLEAR SOME FLAGS
|
||
SOJG T3,.-1 ;CLEAR REST OF FIELD
|
||
RCV < PUSHJ P,.TCRLF## ;FINISH THE LINE
|
||
PUSHJ P,FLGFLD > ;TYPE OUT FLAGS FROM THIS FIELD
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;RD05T - IMAGE BYTE FIELD
|
||
|
||
RD05T: LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH (BYTES)
|
||
LDB T4,[POINTR T1,DX$IOX] ;FIELD STORAGE IN .IODAP
|
||
ADD T4,[POINT 8,.IODAP(IO)] ;MAKE INTO BYTE POINTER
|
||
TXNE T1,DX$XTN ;EXTENSIBLE IMAGE FIELD?
|
||
JRST RD05T5 ;YES
|
||
TXNN T1,DX$VAR ;NO, VARIABLE LENGTH FIELD?
|
||
NORCV < JRST RD05T3 > ;NO, FIXED LENGTH
|
||
RCV < JRST RD05T1 > ;NO, FIXED LENGTH
|
||
PUSHJ P,RDBYT1 ;YES, READ ACTUAL FIELD SIZE
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
CAMLE T2,T3 ;WITHIN SPECS?
|
||
PJRST RDEIE ;NO, TOO BIG, ERROR IN FIELD
|
||
MOVE T3,T2 ;SET ACTUAL FIELD SIZE
|
||
RCV < MOVEI T1,[ASCIZ \ [var len image, len= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS VAR LENGTH IMAGE
|
||
PUSHJ P,VARLEN > ;TYPE OUT THE LENGTH
|
||
JRST RD05T3 ;AND ENTER LOOP
|
||
|
||
RCV <
|
||
RD05T1: MOVEI T1,[ASCIZ \ [fix len image, len from DAP spec= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS FIXED LENGTH IMAGE
|
||
PUSHJ P,FIXLEN ;TYPE OUT THE LENGTH
|
||
JRST RD05T3 > ;ENTER LOOP
|
||
|
||
;LOOP READING IMAGE BYTES
|
||
|
||
RD05T2: PUSHJ P,RDBYT1 ;NEXT IMAGE BYTE
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
IDPB T2,T4 ;STORE THIS BYTE
|
||
RCV < PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
PUSHJ P,.THEXB > ;TYPE-OUT BYTE FROM T2
|
||
RD05T3: SOJGE T3,RD05T2 ;LOOP FOR REST OF FIELD
|
||
TDZA T2,T2 ;TRAILING NULL
|
||
IDPB T2,T4 ;WIPE OUT TRAILING FIELD
|
||
SOJGE T3,.-1 ;CLEAR OUT REST OF FIELD
|
||
RCV < PUSHJ P,.TCRLF## > ;FINISH OFF THE LINE
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
;LOOP READING EXTENSIBLE IMAGE BYTES
|
||
|
||
RD05T5: STOPCD <Extensible DAP image field encountered in RD05T>
|
||
;RD06T - MENU FIELD
|
||
|
||
RD06T: TXNE T1,DX$SKP ;IS THIS AN "INVISIBLE" MENU?
|
||
NORCV < JRST .POPJ1## > ;*** YES, JUST IGNORE IT HERE
|
||
RCV < JRST [MOVEI T1,[ASCIZ \ ("invisible" menu, ignored)\]
|
||
PUSHJ P,.TSTRG##
|
||
PUSHJ P,.TCRLF##
|
||
JRST .POPJ1##] >
|
||
LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH
|
||
LDB T4,[POINTR T1,DX$IOX] ;FIELD STORAGE IN .IODAP
|
||
ADD T4,[POINT 7,.IODAP(IO)] ;MAKE INTO BYTE POINTER
|
||
DMOVEM T3,.IODRM(IO) ;SAVE FOR PROCESSING THE MENU FIELD
|
||
TXNE T1,DX$XTN ;EXTENSIBLE FIELD?
|
||
JRST RD06T5 ;YES
|
||
STOPCD <Fixed/variable length DAP menu field encountered in RD06T>
|
||
|
||
;LOOP READING EXTENSIBLE MENU FIELD
|
||
|
||
RD06T5:
|
||
RCV < MOVEI T1,[ASCIZ \ [extensible menu field]\] ;TELL USER EXTENSIBLE FIELD
|
||
PUSHJ P,.TSTRG## > ; . . .
|
||
RD06T6: PUSHJ P,RDBYT1 ;READ NEXT MENU BYTE
|
||
PJRST RDEIE ;ERROR IN FIELD
|
||
RCV < PUSHJ P,EXTENS > ;TYPE OUT EXTENSIBLE BYTE FROM T2
|
||
IDPB T2,T4 ;STORE AWAY MENU BYTE
|
||
TRNE T2,200 ;END OF EXTENSIBLE FIELD?
|
||
SOJG T3,RD06T6 ;NO, LOOP BACK AND FINISH IT OFF
|
||
TRNE T2,200 ;REALLY THE END?
|
||
PJRST RDEIF ;NO, ERROR IN FIELD
|
||
TDZA T2,T2 ;YES, A NULL
|
||
IDPB T2,T4 ;TO TERMINATE THE FIELD
|
||
SOJG T3,.-1 ;CLEAR REST OF FIELD
|
||
RCV < PUSHJ P,.TCRLF## > ;FINISHED LINE OF HEX MENU BYTES
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;NOW LOOP PROCESSING REST OF MESSAGE AS DESCRIBED BY THE MENU
|
||
|
||
RD06M1: ILDB P2,.IODRM+1(IO) ;GET A MENU BYTE
|
||
TROA P2,200 ;FORCE 7-BITS-WORTH OF LOOP
|
||
|
||
;LOOP WITHIN 7-BIT MENU SUBFIELD
|
||
|
||
RD06M2: LSH P2,-1 ;ADVANCE TO NEXT MENU BIT
|
||
AOS P1,.IODRX(IO) ;CORRESPONDING EXECUTION TABLE INDEX
|
||
TRZN P2,1 ;THIS FIELD PRESENT?
|
||
JUMPN P2,RD06M5 ;NO, TRY CHECK FOR REST OF MENU'ED MESSAGE
|
||
JUMPE P2,RD06M7 ;YES, UNLESS FAKE BIT ("TROA" ABOVE)
|
||
|
||
;READ IN MENU-SPECIFIED FIELD
|
||
|
||
MOVE T1,DAPXCT(P1) ;PICK UP EXECUTION TABLE ENTRY
|
||
LDB T2,[POINTR T1,DX$COD] ;FIELD "NUMBER"
|
||
LDB T3,[POINTR T1,DX$TYP] ;FIELD "TYPE"
|
||
CAILE T3,$DXTMX ;WITHIN MAXIMUM LIMITS?
|
||
STOPCD <DX$TYP menued DAP field type too big in RD06M>
|
||
MOVEM T2,.IODRF(IO) ;SET CURRENT INPUT FIELD "NUMBER"
|
||
CAIE T3,$DXTMS ;IF START OF MESSAGE,
|
||
CAIN T3,$DXTMN ; OR MENU
|
||
JRST RDEIF ;THEN ERROR IN FIELD
|
||
RCV < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX(P1) ;ADDR OF FIELD DESCRIPTIVE TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
MOVE T1,DAPXCT(P1) > ;PICK UP EXECUTION TABLE ENTRY
|
||
PUSH P,P2 ;SAVE P2
|
||
PUSHJ P,@RDDAPX(T3) ;DISPATCH ON FIELD TYPE
|
||
JRST [POP P,P2 ;ERROR, ADJUST STACK
|
||
POPJ P,] ;AND PROPAGATE THE ERROR
|
||
POP P,P2 ;RESTORE P2
|
||
RD06M5: LDB T3,[POINTR DAPXCT+1(P1),DX$TYP] ;PEEK AT NEXT FIELD TYPE
|
||
CAIE T3,$DXTMS ;END OF CURRENT MESSAGE?
|
||
JRST RD06M2 ;NO, STILL MORE FIELDS POSSIBLE
|
||
MOVE T1,P2 ;CURRENT MENU BYTE
|
||
JFFO T1,.+1 ;FIND THE FIRST BIT
|
||
LSH T1,1(T2) ;GET RID OF JUNK ("TROA") BIT
|
||
JUMPN T1,RDEIF ;IF STILL BITS (ALLEGING FIELDS) THEN ERROR
|
||
ILDB T1,.IODRM+1(IO) ;NEXT MENU BYTE
|
||
SOSLE .IODRM+0(IO) ;COUNT DOWN MENU BYTES LEFT
|
||
JRST .-3 ;CHECK THEM ALL OUT
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
RD06M7: SOS .IODRX(IO) ;THE "TROA" BIT DOESN'T COUNT AGAINST INDEX
|
||
SOSLE .IODRM+0(IO) ;COUNT DOWN MENU BYTES
|
||
JRST RD06M1 ;AND KEEP PROCESSING THEM
|
||
PJRST RDEIF ;ERROR IN FIELD
|
||
;RD0T7 - TIME FIELD
|
||
|
||
RD07T: LDB P3,[POINTR T1,DX$LNB] ;DAP FIELD LENGTH (BYTES)
|
||
MOVE P4,[POINT 7,.IODTM(IO)];TEMP HOLDING AREA POINTER
|
||
|
||
;FIRST STRIP OFF ANY LEADING SPACES (E.G., " 1-MAY-...") SO IT/THEY DON'T
|
||
;GET CONVERTED INTO COLONS . . .
|
||
|
||
RD07T1:
|
||
RCV < MOVEI T1,[ASCIZ \ [ASCII date/time field] \]
|
||
PUSHJ P,.TSTRG## > ;INFORM USER OF DATE/TIME FIELD
|
||
RD07T2: PUSHJ P,RDBYT1 ;GET A DATE/TIME CHARACTER
|
||
JRST RDEIE ;ERROR IN FIELD
|
||
CAIE T2," " ;IS THIS A LEADING SPACE?
|
||
JRST RD07T4 ;NO, VALID CHARACTER
|
||
SOJG P3,RD07T2 ;YES, LOOP EATING SPACES
|
||
SETZ T2, ;NO?????????????????
|
||
RCV < MOVEI T1,[ASCIZ \ ?? field is null ?? \]
|
||
PUSHJ P,.TSTRG## > ;INFORM USER OF DATE/TIME FIELD
|
||
JRST RD07T7 ;SO RETURN A ZERO DATE/TIME
|
||
|
||
;READ IN ASCII DATE/TIME STRING INTO SCRATCH HOLDING AREA
|
||
|
||
RD07T3: PUSHJ P,RDBYT1 ;NEXT ASCII DATE/TIME CHARACTER
|
||
JRST RDEIE ;ERROR IN FIELD
|
||
CAIN T2," " ;IS THIS DAP'S SPACE 'TWEEN DATE AND TIME?
|
||
MOVEI T2,":" ;YES, SCAN WANTS A COLON THERE
|
||
RD07T4: IDPB T2,P4 ;STASH THIS CHARACTER
|
||
RCV < MOVE T1,T2 ;GET THE CHAR
|
||
PUSHJ P,.TCHAR## > ;INFORM USER OF DATE/TIME FIELD CHAR
|
||
SOJG P3,RD07T3 ;LOOP FOR REST OF FIELD
|
||
IDPB P3,P4 ;ASCIZIZE THE STRING
|
||
|
||
;TRANSLATE ASCII STRING INTO 36-BIT INTERNAL DATE/TIME FORMAT
|
||
|
||
PUSHJ P,RD07X0 ;GET INTERNAL FORMAT DATE/TIME
|
||
JRST RDEIE ;ERROR IN FIELD
|
||
RD07T7: LDB T4,[POINTR DAPXCT(P1),DX$IOX] ;GET CDB OFFSET FOR THIS FIELD
|
||
ADDI T4,.IODAP(IO) ;RELOCATE INTO MEMORY
|
||
MOVEM T2,0(T4) ;SET DATE/TIME FIELD IN DAP BLOCK
|
||
RCV < PUSHJ P,.TCRLF## > ;FINISH LINE TO USER
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;HELPER TO TRANSLATE ASCIZ STRING INTO BINARY ("INTERNAL") DATE/TIME
|
||
|
||
RD07X0: PUSHJ P,.SAVE4## ;SCAN'S CH AND NM ARE OUR P3 AND P4 !!!
|
||
SETZM .IOXTO(IO) ;USE IOXTO AS COUNTER/FLAG HERE
|
||
XMOVEI T1,RD07XI ;OUR VERY OWN INPUT TYPER
|
||
PUSHJ P,.XTYPI## ;INTERCEPT "COMMAND" INPUT
|
||
XMOVEI T1,RD07XO ;OUR VERY OWN OUTPUT TYPER
|
||
PUSHJ P,.XTYPO## ;INTERCEPT "COMMAND" OUTPUT
|
||
MOVE T1,[POINT 7,[0]];A DUMMY STRING
|
||
MOVEM T1,.IOXTI(IO) ;SET IN CASE .CLRTI NEEDS SOMETHING
|
||
PUSHJ P,.CLRTI## ;SETUP LOWLEVEL COMMAND INPUT ROUTINES
|
||
MOVE T1,[POINT 7,.IODTM(IO)] ;BYTE POINTER TO ASCIZ STRING
|
||
MOVEM T1,.IOXTI(IO) ;SET FOR RD07XI
|
||
|
||
;NOW PARSE THE ASCIZ DATE/TIME STRING
|
||
|
||
RD07X3: PUSHJ P,.DYTIM## ;LET SCAN DO ITS THING
|
||
JRST RD07X7 ;ERROR - DIE
|
||
MOVE T2,NM ;POSITION DATE/TIME FOR CALLER
|
||
SKIPN .IOXTO(IO) ;IT BETTER NOT HAVE COMPLAINED
|
||
JRST .POPJ1## ;RETURN WITH DATE/TIME IN T2
|
||
RD07X7: STOPCD <Error in parsing received DATE/TIME message in RD07X>
|
||
|
||
|
||
;THE "COMMAND" INPUT ROUTINE
|
||
|
||
RD07XI: ILDB CH,.IOXTI(IO) ;GET NEXT CHARACTER FROM NAME STRING
|
||
JUMPN CH,.POPJ## ;RETURN IT
|
||
MOVEI CH,.CHLFD ;END OF STRING, RETURN EOL TO SCAN
|
||
POPJ P, ; . . .
|
||
|
||
|
||
;THE "COMMAND" OUTPUT ROUTINE
|
||
|
||
RD07XO: OUTCHR T1 ;OH WELL
|
||
AOS .IOXTO(IO) ;COUNT OCCURENCES
|
||
POPJ P, ;RETURN TO SCAN
|
||
;ERRORS READING DAP PROTOCOL
|
||
|
||
;UNKNOWN DAP MESSAGE TYPE
|
||
|
||
RDEUM: STOPCD <Unknown DAP message type>
|
||
|
||
|
||
;UNKNOWN DAP MESSAGE FIELD
|
||
|
||
RDEUF: STOPCD <Unknown DAP message field>
|
||
|
||
|
||
;ERROR (UNSPECIFIED) IN FIELD
|
||
|
||
RDEIE: STOPCD <Error in DAP field>
|
||
RDEIF: STOPCD <Error in DAP field>
|
||
;RDEAT -- EAT [REST OF] DAP MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RDEAT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died whilst reading whatever is left of the
|
||
;DAP input message.
|
||
;
|
||
;On normal return the DAP input message has been completely read, and
|
||
;is now ready for the next DAP input message (i.e., RDBYT will return
|
||
;with no data available, RDMSG must be called to start the next input
|
||
;message processing). If called to eat a data message the file data
|
||
;CRC will be updated to reflect the data bytes "eaten" (note that the
|
||
;caller is responsible to ensure that the RCN field of the data message
|
||
;has already been read).
|
||
;
|
||
;Uses ac T2.
|
||
|
||
ENTRY .RDEAT
|
||
INTERN RDEAT0, RDEAT1
|
||
|
||
.RDEAT: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RDEAT0:
|
||
RDEAT1: MOVE T2,.IODIM(IO) ;GET CURRENT DAP MESSAGE TYPE
|
||
CAIN T2,$DHDAT ;EATING INPUT FILE DATA?
|
||
JRST RDEAT4 ;YES, MUST KEEP CRC UPDATED
|
||
|
||
;HERE TO EAT NON-DATA DAP MESSAGES
|
||
|
||
RDEAT2: PUSHJ P,RDBYT1 ;READ ANOTHER DAP BYTE
|
||
CAIA ;NONE AVAILABLE
|
||
JRST RDEAT2 ;TRY FOR MORE
|
||
JUMPE M0,.POPJ1## ;IF NO DATA THEN SUCCESSFUL RETURN
|
||
POPJ P, ;OTHERWISE THE NETWORK DIED
|
||
|
||
;HERE TO EAT DAP DATA MESSAGES
|
||
|
||
RDEAT4: PUSHJ P,RDBYC1 ;READ ANOTHER DAP BYTE, UPDATING THE CRC
|
||
CAIA ;NONE AVAILABLE
|
||
JRST RDEAT4 ;TRY FOR MORE
|
||
JUMPE M0,.POPJ1## ;IF NO DATA THEN SUCCESSFUL RETURN
|
||
POPJ P, ;OTHERWISE THE NETWORK DIED
|
||
;RDBYC -- READ ONE DAP FILE DATA BYTE, CALCULATING CRC
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RDBYC
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return either the network died or the current input DAP
|
||
;data message is exhausted (M0 has 0).
|
||
;
|
||
;On normal return the next available file data byte is in T2,
|
||
;and the running file data CRC has been updated.
|
||
;
|
||
;This routine is functionally identical to RDBYT, except that the
|
||
;file data CRC is updated.
|
||
;
|
||
;Uses T2.
|
||
|
||
ENTRY .RDBYC
|
||
INTERN RDBYC0, RDBYC1
|
||
|
||
INTERN RDCRC1
|
||
|
||
.RDBYC: PUSHJ P,.SACIO## ;SETUP I/O CONTEXT
|
||
RDBYC0:
|
||
RDBYC1: PUSHJ P,RDBYT1 ;GET NEXT DAP BYTE
|
||
POPJ P, ;PROPAGATE EXCEPTION RETURN
|
||
RDCRC1: PUSH P,T2 ;SAVE RETURN DATA BYTE
|
||
ANDI T2,377 ;REDUCE TO JUST INTERESTING DATA
|
||
MOVE M0,.IODIK(IO) ;GET LAST FILE DATA CRC
|
||
XORB M0,T2 ;INCLUDE BYTE IN CRC
|
||
ANDI T2,377 ;COMPUTE OFFSET INTO CRC TABLE
|
||
LSH M0,-^D08 ;XOR REMAINING CRC FROM TABLE
|
||
XOR M0,DAPCRC(T2) ;COMPUTE NEW CRC
|
||
MOVEM M0,.IODIK(IO) ;AND STASH IT AWAY
|
||
POP P,T2 ;RESTORE DAP FILE DATA BYTE
|
||
JRST .POPJ1## ;AND SUCCESSFUL RETURN
|
||
;RDBYT -- READ ONE DAP BYTE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RDBYT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return either the network died or the current input DAP
|
||
;message is exhausted (M0 has 0).
|
||
;
|
||
;On normal return the next available DAP byte is in T2.
|
||
;
|
||
;This routine handles continuation messages (DF$MOR) internally - the
|
||
;caller is not required to be aware of them (and in fact is not even told
|
||
;if a continuation message is encountered).
|
||
;
|
||
;Uses ac T2.
|
||
|
||
ENTRY .RDBYT
|
||
INTERN RDBYT0, RDBYT1
|
||
|
||
.RDBYT: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RDBYT0:
|
||
RDBYT1: SKIPE T2,.IODIR(IO) ;GOT A BYTE TO BE RE-READ?
|
||
JFFO P,[SETZM .IODIR(IO) ;CLEAR OUT STALE BYTE
|
||
TLNE T2,(1B1) ;SAVED ERROR CODE (400000,,ERROR)?
|
||
TLZA T2,-1 ;NO, CLEAR OUT FLAG, LEAVING DATA BYTE
|
||
TROA M0,(T2) ;YES, POSITION ERROR CODE
|
||
AOS 0(P) ;SUCCESS RETURN
|
||
POPJ P,] ;FAILURE RETURN
|
||
SOSGE .IODIC(IO) ;ANY DAP BYTES LEFT?
|
||
JRST RDBYT4 ;PROBABLY NOT, BUT MIGHT BE CONTINUATION
|
||
PUSHJ P,RNBYT1 ;YES, READ NEXT BYTE FROM NETWORK
|
||
JRST RDBYT2 ;HMMM. PROBABLY BAD NEWS
|
||
AOS (P) ;SKIP
|
||
POPJ P, ; RETURN
|
||
;NETWORK REFUSED TO GIVE US A BYTE
|
||
|
||
RDBYT2: PJUMPN M0,.POPJ## ;IF NETWORK DIED, LET HIGHER UPS HANDLE IT
|
||
HLRZ T2,.IODIC(IO) ;GET DAP BYTE COUNT
|
||
CAIE T2,223344 ;WAS IT A DUMMY COUNT?
|
||
STOPCD <Network EOM before DAP EOM - DAP data lost>
|
||
SETZM .IODIC(IO) ;FLAG OK END OF DAP MESSAGE
|
||
|
||
;HERE WHEN THE CURRENT DAP MESSAGE IS EXHAUSTED. CHECK FOR A CONTINUATION
|
||
;MESSAGE (I.E., A DAP MESSAGE WHICH WAS BROKEN UP INTO SEGMENTS AND ACTUALLY
|
||
;TRANSMITTED AS SEVERAL DISTINCT (PRESUMABLY PHYSICAL NETWORK) MESSAGES.)
|
||
|
||
RDBYT4: SKIPE .IODIX(IO) ;IS THIS A RETRY?
|
||
JRST RDBYT6 ;YES
|
||
MOVE T2,.IODIF(IO) ;GET DAP INPUT HEADER FLAGS
|
||
TFNN T2,MOR ;ARE THERE MORE SEGMENTS COMING?
|
||
JRST RDBYT8 ;NO, RETURN EMPTY
|
||
SKIPE .IODIB(IO) ;IF CONTINUED, BETTER NOT BE RANDOM BITS LEFT
|
||
PJRST RDEID4 ;THERE WERE, ERROR IN FIELD
|
||
SKIPG T2,.IODIM(IO) ;GET CURRENT INPUT MESSAGE TYPE
|
||
STOPCD <XDBYT but no DAP message in progress>
|
||
MOVEM T2,.IODIX(IO) ;SAVE AND SET STATE FLAG
|
||
RDBYT6: PUSHJ P,RDBYU0 ;READ IN AND STARTUP A NEW MESSAGE
|
||
POPJ P, ;NETWORK DIED
|
||
MOVE M0,.IODIX(IO) ;GET PREVIOUS MESSAGE TYPE
|
||
SETZM .IODIX(IO) ;CLEAR CONTINUATION STATE
|
||
CAME T2,M0 ;IS CONTINUED MESSAGE SAME AS BEFORE?
|
||
PJRST RDEOS ;NO, DAP MESSAGE OUT OF SEQUENCE
|
||
JRST RDBYT1 ;YES, GO BACK AND FINISH READING IT
|
||
|
||
;HERE WHEN DAP MESSAGE IS EMPTY
|
||
|
||
RDBYT8: HRROS .IODIM(IO) ;NEGATIVE LH TO INDICATE OUT OF DAP MESSAGE
|
||
; (LEAVE CODE IN RH FOR ERROR ROUTINES)
|
||
SETZ M0, ;RETURN NULL
|
||
POPJ P, ;EMPTY RETURN
|
||
|
||
|
||
;HELPER TO READ CONTINUATION MESSAGE
|
||
|
||
RDBYU0: PUSHJ P,TSAV14## ;NEED TO PROTECT THE T'S
|
||
PUSHJ P,RDMSG0 ;START UP A NEW DAP MESSAGE
|
||
POPJ P, ;NET DIED?
|
||
MOVEM T2,-T2(P) ;PASS BACK THE NEW MESSAGE TYPE
|
||
JRST .POPJ1## ;AND RETURN WITH NEW MESSAGE READY TO CONTINUE
|
||
;RDBYR -- RE-READ DAP MESSAGE/DATA BYTE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RDBYR
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;RDBYR assumes that a call to RDBYT has been successfully executed,
|
||
;leaving a valid 8-bit DAP byte in T2. This byte will be set, and
|
||
;returned on the next call to RDBYT.
|
||
;
|
||
;The error return is not exercised.
|
||
;
|
||
;On normal return the next call to RDBYT will re-read the just-read
|
||
;(i.e., in T2) DAP 8-bit byte.
|
||
;
|
||
;Uses no acs.
|
||
|
||
ENTRY .RDBYR
|
||
INTERN RDBYR0, RDBYR1
|
||
|
||
.RDBYR: PUSHJ P,.SACIO## ;SETUP I/O CONTEXT
|
||
RDBYR0:
|
||
RDBYR1: HRROM T2,.IODIR(IO) ;SAVE CURRENT DAP BYTE
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;RDCLR -- CLEAR OUT DAP MESSAGE BASE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<MSG>
|
||
; PUSHJ P,RDCLR
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB; and <MSG> is
|
||
;the DAP message type ($DHxxx) whose base area within the .IODAP
|
||
;block is to be cleared.
|
||
;
|
||
;RDCLR zeroes all parameters, fields, values, etc. associated with
|
||
;the specified DAP message type contained within the .IODAP block
|
||
;within the I/O CDB (for example the attributes fields of the main
|
||
;attributes DAP message).
|
||
;
|
||
;On error return the specified <MSG> is illegal (error code in M0).
|
||
;
|
||
;On normal return the .IODAP area associated with the message type
|
||
;has been zeroed.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .RDCLR
|
||
INTERN RDCLR0, RDCLR1
|
||
|
||
.RDCLR: PUSHJ P,.SACIO## ;SET UP I/O CONTEXT
|
||
RDCLR0: ;WE DON'T USE THE P'S
|
||
RDCLR1: PUSHJ P,TSAV14## ;PRESERVE THE TEAS (ESPECIALLY T2!)
|
||
MOVEI T4,DAPIDX ;THE MESSAGE INDEX INTO THE EXECUTION TABLE
|
||
PUSHJ P,.CFIND## ;LOCATE THE MESSAGE WITHIN THE TEMPLATE
|
||
STOPCD <Unknown DAP message in RDCLR>
|
||
LDB T1,[POINTR DAPXCT(T1),DX$IOX] ;GET FIRST .IODAP ENTRY
|
||
HLRZ T2,1(T4) ;GET POINTER TO NEXT MESSAGE TYPE FIRST ENTRY
|
||
SKIPN T2 ;AT END OF TABLE?
|
||
SKIPA T2,[$DLDAP] ;YES, POINT TO END OF .IODAP AREA
|
||
LDB T2,[POINTR DAPXCT(T2),DX$IOX] ;NO, FETCH NEXT FIRST ENTRY
|
||
ADDI T1,.IODAP(IO) ;RELOCATE TO REAL MEMORY
|
||
SETZM (T1) ;CLEAR FIRST WORD
|
||
HRL T1,T1 ;CONCOCT A
|
||
ADDI T1,1 ; BLT POINTER
|
||
ADDI T2,.IODAP(IO) ;RELOCATE LAST WORD TO REAL MEMORY
|
||
BLT T1,-1(T2) ;CLEAR OUT DAP MESSAGE BASE
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;RDMSG -- READ IN AND STARTUP ONE DAP MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RDMSG
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died
|
||
;
|
||
;On normal return the DAP message code is in T2. Subsequent calls to
|
||
;RDBYT will read the rest of the DAP message.
|
||
;
|
||
;Uses ac T2.
|
||
|
||
ENTRY .RDMSG
|
||
INTERN RDMSG0, RDMSG1
|
||
|
||
.RDMSG: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RDMSG0: PUSHJ P,.SAVE4## ;WE NEED A FEW ACS HERE
|
||
RDMSG1: SKIPLE .IODIC(IO) ;ANY DAP BYTES STILL OUTSTANDING?
|
||
STOPCD <RDMSG called before end of current DAP message>
|
||
SKIPE .IODRS(IO) ;GOT A SAVED (RDREA) MESSAGE?
|
||
JRST [MOVSI T3,.IODRS(IO) ;YES,
|
||
HRRI T3,.IODIM(IO) ;CONCOCT A BLT POINTER
|
||
BLT T3,.IODIM+.IODRL-1(IO) ;TO BRING BACK INPUT MESSAGE
|
||
SETZM .IODRS(IO) ;CLEAR SAVED INPUT STATE
|
||
JRST RDMSZ] ;AND RETURN "NEW" INPUT MESSAGE
|
||
SETZM .IODIF(IO) ;RESET HEADER FLAGS
|
||
SETZM .IODIS(IO) ;RESET STREAM ID FIELD
|
||
SETZM .IODIB(IO) ;RESET TRAILING UNUSED BITS
|
||
|
||
;READ IN MESSAGE TYPE
|
||
|
||
PUSHJ P,RNBYT1 ;ANY NETWORK BYTES LEFT?
|
||
CAIA ;APPARENTLY NOT
|
||
JRST RDMSG2 ;YES, T2 HAS MESSAGE TYPE
|
||
JUMPN M0,.POPJ## ;ERROR RETURN IF NETWORK DIED
|
||
PUSHJ P,RNMSG0 ;READ IN A NEW NETWORK MESSAGE
|
||
POPJ P, ;NETWORK DIED
|
||
RDMSG2: HRRZM T2,.IODIM(IO) ;SET NEW MESSAGE TYPE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
RCV < PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.TCRLF ;SPACE TO MAKE NEW MESSAGE PROMINENT
|
||
MOVE T1,DAPXTX ;ADDR OF "DAP message type" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT
|
||
MOVEI T1,[ASCIZ / - /];A DASH
|
||
PUSHJ P,.TSTRG## ;TYPE THE DASH
|
||
MOVE T1,.IODIM(IO) ;GET THE DAP MESSAGE TYPE
|
||
MOVEI T2,"0" ;USE ZEROES FOR FILLER
|
||
PUSHJ P,.TDEC2## ;TYPE OUT THE MESSAGE TYPE
|
||
PUSHJ P,.TSPAC## ;A SPACE MAKES MESSAGE PRETTY
|
||
HRRZ T2,.IODIM(IO) ;GET MESSAGE TYPE
|
||
MOVEI T4,DAPIDX ;DAP INDEX TABLE
|
||
PUSHJ P,.CFIND## ;FIND THE INDEX ENTRY FOR THIS MESSAGE TYPE
|
||
PJRST RDEUM ;ERROR - UNKNOWN MESSAGE TYPE
|
||
MOVE T1,DAPXTX(T1) ;GET TEXT DESCRIBING DAP MESSAGE TYPE
|
||
PUSHJ P,.TSTRG## ;TYPE TEXT DESCRIPTION OF DAP MESSAGE
|
||
PUSHJ P,.TSPAC## ;SPACE
|
||
|
||
;TYPE <<From REMOTE to US>> WHERE US=OUR NODE NAME, REMOTE=REMOTE NODE NAME
|
||
|
||
PUSHJ P,.TLANG## ;<
|
||
PUSHJ P,.TLANG## ;<
|
||
MOVEI T1,[ASCIZ \From \] ;From
|
||
PUSHJ P,.TSTRG##
|
||
MOVE T1,.ION6M(IO) ;From REMOTE
|
||
PUSHJ P,.TSIXN##
|
||
MOVEI T1,[ASCIZ \ to \] ;From REMOTE to
|
||
PUSHJ P,.TSTRG##
|
||
MOVE T1,.MYNOD## ;From REMOTE to US
|
||
PUSHJ P,.TSIXN##
|
||
PUSHJ P,.TRANG## ;>
|
||
PUSHJ P,.TRANG## ;>
|
||
PUSHJ P,.TCRLF## ;FINISH OFF THE LINE
|
||
|
||
PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX+1 ;ADDR OF "Message header flags" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT
|
||
> ;END RCV
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;READ IN DAP MESSAGE HEADER FLAGS
|
||
|
||
MOVEI P3,$DBMHF ;LENGTH OF MESSAGE HEADER FLAGS
|
||
MOVE P4,[POINT 7,.IODIF(IO)] ;AND WHERE TO STORE THEM
|
||
SETZ P1, ;NO BYTE SEEN YET
|
||
RDMSG3: PUSHJ P,RNBYT0 ;READ A NETWORK BYTE
|
||
JRST [JUMPN M0,.POPJ## ;IF ERROR, PASS THE WORD
|
||
MOVE T2,.IODIF(IO) ;GET HEADER FLAGS SO FAR
|
||
TFZ T2,MOR ;CLEAR OK FLAG BIT
|
||
TRNE P1,200 ;SHOULD THERE BE ANOTHER BYTE?
|
||
PJRST RDEID0 ;YES, ERROR IN FLAGS FIELD
|
||
RCV < PUSHJ P,.TCRLF## > ;MAKE THE MESSAGE NEAT
|
||
JUMPE T2,RDMSZ ;MESSAGE OK IF NO FIELDS EXPECTED
|
||
PJRST RDEID0] ;ELSE ERROR IN FLAGS FIELD
|
||
IDPB T2,P4 ;STASH THIS FLAG BYTE
|
||
RCV < PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
PUSHJ P,.THEXB > ;TYPE-OUT FLAG BYTE FROM T2
|
||
MOVE P1,T2 ;SAVE EXTENSIBILITY FLAG
|
||
TRNE T2,200 ;END OF FLAGS?
|
||
SOJG P3,RDMSG3 ;NO, READ REST OF FIELD
|
||
TRNE T2,200 ;REALLY END OF FLAGS?
|
||
PJRST RDEID0 ;NO, FIELD TOO BIG, ERROR
|
||
RCV < MOVEI P1,1 ;SO .TFLAG GETS HEADER FLAG MESSAGES
|
||
MOVE P2,.IODIF(IO) ;PICK UP HEADER FLAGS
|
||
CLEAR P3, ;ONLY ONE WORD OF FLAGS
|
||
PUSHJ P,.TCRLF## ;FINISH THE LINE OF HEX FLAGS
|
||
PUSHJ P,.TFLAG > ;TYPE CORRESP. DAP MESSAGES
|
||
MOVE P1,.IODIF(IO) ;PICK UP HEADER FLAGS
|
||
|
||
;READ STREAM ID FIELD, IF PRESENT
|
||
|
||
TFZN P1,SID ;STREAM ID FIELD PRESENT?
|
||
JRST RDMSG4 ;NO
|
||
PUSHJ P,RNBYT0 ;YES, READ IT IN
|
||
JRST [JUMPE M0,RDEID1 ;ERROR IN SID FIELD
|
||
POPJ P,] ;ERROR IN NETWORK
|
||
MOVEM T2,.IODIS(IO) ;SET STREAM ID FIELD
|
||
RCV < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX+2 ;ADDR OF "Stream identification" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TCRLF## > ;FINISH WITH <CR><LF>
|
||
JUMPN T2,RDEID1 ;WE DON'T SUPPORT MULTIPLE SID'S
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;READ IN LENGTH FIELD
|
||
|
||
RDMSG4: TFNN P1,HLN ;HEADER LENGTH FIELD PRESENT?
|
||
JRST RDMSG5 ;NO
|
||
PUSHJ P,RNBYT0 ;YES, READ IT
|
||
JRST [JUMPE M0,RDEID2 ;ERROR IN LENGTH FIELD
|
||
POPJ P,] ;NETWORK DIED
|
||
MOVEM T2,.IODIC(IO) ;SET LENGTH OF DAP DATA
|
||
RCV < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX+3 ;ADDR OF "MSG data length (LSB)" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TCRLF## > ;FINISH WITH <CR><LF>
|
||
|
||
;READ IN SECOND HALF OF LENGTH FIELD
|
||
|
||
RDMSG5: TFNN P1,HL2 ;HIGH-ORDER HEADER LENGTH PRESENT?
|
||
JRST RDMSG6 ;NO
|
||
PUSHJ P,RNBYT0 ;YES, READ IT
|
||
JRST [JUMPE M0,RDEID3 ;ERROR IN EXTENDED LENGTH FIELD
|
||
POPJ P,] ;NETWORK DIED
|
||
DPB T2,[POINT 8,.IODIC(IO),27] ;SET HIGH-ORDER BYTE COUNT
|
||
RCV < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX+4 ;ADDR OF "MSG data length (MSB)" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TCRLF## > ;FINISH WITH <CR><LF>
|
||
|
||
RDMSG6: HRLOI T2,223344 ;DUMMY DAP BYTE COUNT
|
||
; (THIS WILL LEAVE A "223344" IN THE LH, OUR
|
||
; "INDICATION" THAT THE DAP COUNT IS NOT
|
||
; REALLY VALID, BUT KEPT POSITIVE JUST TO
|
||
; KEEP EVERYONE ELSE HAPPY - SEE RDBYT)
|
||
TFZN P1,<HLN,HL2> ;DAP MESSAGE HEADER CONTAIN ITS LENGTH?
|
||
MOVEM T2,.IODIC(IO) ;NO, USE DEFAULT
|
||
|
||
;READ IN TRAILING UNUSED BIT COUNT
|
||
|
||
TFZN P1,BCT ;ANY UNUSED BITS?
|
||
JRST RDMSG7 ;NO
|
||
PUSHJ P,RNBYT0 ;YES, READ THE COUNT
|
||
JRST [JUMPE M0,RDEID4 ;ERROR IN UNUSED BIT COUNT
|
||
POPJ P,] ;NETWORK DIED
|
||
MOVEM T2,.IODIB(IO) ;SET TRAILING UNUSED BIT COUNT
|
||
RCV < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX+5 ;ADDR OF "Trailing bit count" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TCRLF## > ;FINISH WITH <CR><LF>
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;CHECK FOR SYSPEC (SYSTEM-SPECIFIC) FIELD
|
||
|
||
RDMSG7: TFZN P1,SHX ;SYSTEM-SPECIFIC HEADER FIELD?
|
||
JRST RDMSG8 ;NO
|
||
PUSHJ P,RNBYT0 ;YES, GET LENGTH OF FOLLOWING IMAGE FIELD
|
||
JRST [JUMPE M0,RDEID5 ;ERROR IN SYSPEC FIELD
|
||
POPJ P,] ;NETWORK DIED
|
||
RCV < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX+6 ;ADDR OF "SYSPEC sys-specific data" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
PUSHJ P,.THEXB > ;TYPE THE HEX BYTE FROM T2
|
||
SKIPG T4,T2 ;COUNT OF IMAGE BYTES FOLLOWING
|
||
JRST RDMSG8 ;NONE, ALL DONE HERE
|
||
RDM7.1: PUSHJ P,RNBYT0 ;GET NEXT SYSPEC IMAGE BYTE
|
||
JRST [JUMPE M0,RDEID5 ;ERROR IS SYSPEC FIELD
|
||
POPJ P,] ;NETWORK DIED
|
||
RCV < PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
PUSHJ P,.THEXB > ;TYPE THE HEX BYTE FROM T2
|
||
SOJG T4,RDM7.1 ;EAT THE WHOLE SILLY THING
|
||
RCV < PUSHJ P,.TCRLF## > ;FINISH OFF WITH <CR><LF>
|
||
|
||
;NOW SEE IF THERE IS ANYTHING LEFT OVER
|
||
|
||
RDMSG8: TFZ P1,MOR ;CLEAR OK BIT
|
||
JUMPN P1,RDEID0 ;ANYTHING LEFT OVER IS AN ERROR
|
||
|
||
;NOW VERIFY THAT ALL THE FIELDS FIT TOGETHER
|
||
|
||
RDMSZ: MOVE T3,.IODIC(IO) ;GET INPUT BYTE COUNT
|
||
MOVEM T3,.IODRC(IO) ;AND SET IN CASE .RDREA IS CALLED
|
||
HRRZ T2,.IODIM(IO) ;RETURN NEW CURRENT INPUT MESSAGE TYPE
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;RDMSR -- RE-READ THE CURRENT DAP MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RDMSR
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;RDMSR assumes that a DAP message has just been started (i.e., RDMSG
|
||
;has been called, T2 has the current DAP message code, and no DAP
|
||
;data bytes have been read, which is to say neither RDDAP nor RDBYT
|
||
;have been called). RDMSR will "undo" the current message such that
|
||
;the next call to RDMSG will re-read it.
|
||
;
|
||
;On error return either a message was not in progress, or had been
|
||
;already partially read.
|
||
;
|
||
;On normal return the current DAP message will be readable via the
|
||
;next call to RDMSG.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .RDMSR
|
||
INTERN RDMSR0, RDMSR1
|
||
|
||
.RDMSR: PUSHJ P,.SACIO## ;SETUP I/O CONTEXT
|
||
RDMSR0:
|
||
RDMSR1: MOVE T3,.IODRC(IO) ;GET SAVED INITIAL DAP BYTE COUNT
|
||
CAME T3,.IODIC(IO) ;WON'T HAVE CHANGED UNLESS RDBYT CALLED
|
||
STOPCD <RDMSR not called immediately after RDMSG>
|
||
MOVSI T3,.IODIM(IO) ;START OF DAP INPUT MESSAGE STUFF
|
||
HRRI T3,.IODRS(IO) ;WHERE TO SAVE IT
|
||
BLT T3,.IODRS+.IODRL-1(IO) ;SAVE INPUT MESSAGE CONTEXT
|
||
SETZM .IODIM(IO) ;CLEAR START OF INPUT MESSAGE CONTEXT
|
||
MOVSI T3,.IODIM(IO) ;CONCOCT
|
||
HRRI T3,.IODIM+1(IO) ; A BLT POINTER TO
|
||
BLT T3,.IODIM+.IODRL-1(IO) ;CLEAR CURRENT INPUT MESSAGE CONTEXT
|
||
JRST .POPJ1## ;READY TO CALL .RDMSG AGAIN
|
||
;ERRORS READING DAP FIELDS
|
||
|
||
;ERROR IN DAP MESSAGE HEADER FLAGS
|
||
|
||
RDEID0: STOPCD <Error in received DAP message header flags>
|
||
|
||
|
||
;ERROR IN DAP MESSAGE HEADER STREAM ID FIELD
|
||
|
||
RDEID1: STOPCD <Error in received DAP message header stream ID field>
|
||
|
||
|
||
;ERROR IN DAP MESSAGE HEADER LENGTH FIELD
|
||
|
||
RDEID2: STOPCD <Error in received DAP message header length field>
|
||
|
||
|
||
;ERROR IN DAP MESSAGE HEADER LEN256 (EXTENDED LENGTH) FIELD
|
||
|
||
RDEID3: STOPCD <Error in received DAP message header length-256 field>
|
||
|
||
|
||
;ERROR IN DAP MESSAGE HEADER BITCNT FIELD
|
||
|
||
RDEID4: STOPCD <Error in received DAP message header trailing bit count field>
|
||
|
||
|
||
;ERROR ID DAP MESSAGE HEADER SYSPEC FIELD
|
||
|
||
RDEID5: STOPCD <Error in received DAP message header SYSPEC field>
|
||
|
||
|
||
;DAP MESSAGE OUT OF SEQUENCE
|
||
|
||
.RDEOS::
|
||
RDEOS: STOPCD <DAP message received out of sequence>
|
||
;XDACK -- SEND ACKNOWLEDGE MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XDACK
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;On error return the network aborted.
|
||
;
|
||
;On successful return an ACKNOWLEDGE message has been built and is
|
||
;ready to be shipped to the remote.
|
||
;
|
||
; THE CALLER MUST CALL XDFLS TO FORCE TRANSMISSION OF THE ACK
|
||
;
|
||
;Historically, before DAP %6.0, any ACK implied a line turnaround.
|
||
;With version 6 the DELETE/EXECUTE/RENAME functions can block multiple
|
||
;NAME/ATTRIBUTES/ACK sequences together, so XDACK doesn't flush the
|
||
;output automatically.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
ENTRY .XDACK
|
||
INTERN XDACK0, XDACK1
|
||
|
||
.XDACK: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDACK0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDACK1: MOVEI T2,$DHACK ;ACKNOWLEDGE MESSAGE CODE
|
||
PUSHJ P,XDMSG1 ;START UP A NEW DAP MESSAGE
|
||
JRST XDACK9 ;CAN'T, GO CHECK IT OUT
|
||
PUSHJ P,XDEOM1 ;CAP OFF THE DAP ACKNOWLEDGE MESSAGE
|
||
POPJ P, ;OOPS
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
XDACK9: CAIE M0,$ECTRA ;SHOULD WE TRY AGAIN?
|
||
POPJ P, ;NO, FATAL ERROR
|
||
JRST XDACK1 ;YES
|
||
;XDACL -- SEND SHORT-FORM ACCESS COMPLETE (CLOSE) MESSAGE
|
||
;XDAKL -- SEND SHORT-FORM ACCESS COMPLETE (KILL) MESSAGE
|
||
;XDARS -- SEND SHORT-FORM ACCESS COMPLETE (RESPONSE) MESSAGE
|
||
;XDASK -- SEND SHORT-FORM ACCESS COMPLETE (SKIP) MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XDACL/AKL/ARS/ASK
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;On error return the network aborted.
|
||
;
|
||
;On successful return an ACCOMP(xxx) message has been shipped to the
|
||
;remote file service. This access complete message will have only the
|
||
;A2F field set - neither the access options nor the file data checksum
|
||
;fields will be sent.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
;ACCOMP(CLOSE)
|
||
|
||
ENTRY .XDACL
|
||
INTERN XDACL0, XDACL1
|
||
|
||
.XDACL: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDACL0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDACL1: MOVEI T2,$DVACL ;"CLOSE" FUNCTION (NORMAL COMPLETION)
|
||
PJRST XDA2F1 ;CAP OFF SHORT-FORM ACCOMP(CLOSE)
|
||
|
||
|
||
|
||
;ACCOMP(KILL)
|
||
|
||
ENTRY .XDAKL
|
||
INTERN XDAKL0, XDAKL1
|
||
|
||
.XDAKL: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDAKL0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDAKL1: MOVEI T2,$DVAKL ;"KILL/RESET" FUNCTION
|
||
PJRST XDA2F1 ;CAP OFF SHORT-FORM ACCOMP(KILL)
|
||
;ACCOMP(RESPONSE)
|
||
|
||
ENTRY .XDARS
|
||
INTERN XDARS0, XDARS1
|
||
|
||
.XDARS: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDARS0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDARS1: MOVEI T2,$DVARS ;"RESPONSE" FUNCTION
|
||
PJRST XDA2F1 ;SHIP THE ACCOMP(RESPONSE)
|
||
|
||
|
||
|
||
;ACCOMP(SKIP)
|
||
|
||
ENTRY .XDASK
|
||
INTERN XDASK0, XDASK1
|
||
|
||
.XDASK: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDASK0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDASK1: MOVEI T2,$DVASK ;"SKIP" FUNCTION
|
||
PJRST XDA2F1 ;CAP OFF SHORT-FORM ACCOMP(SKIP)
|
||
|
||
|
||
|
||
;MAIN BODY OF SHORT-FORM ACCOMP(XXX)
|
||
|
||
XDA2F1: MOVD1M T2,A2F ;SET ACCOMP FUNCTION CODE
|
||
MOVDII T2,M07,A2F ;FLAG ONLY THE FUNCTION FIELD
|
||
MOVDM T2,M07 ;IN THE ACCOMP "HIDDEN" MENU
|
||
MOVEI T2,$DHACM ;ACCESS COMPLETE MESSAGE CODE
|
||
PUSHJ P,XDDAP1 ;PACKAGE THE ACCOMP MESSAGE
|
||
POPJ P, ;ERROR
|
||
PJRST XDFLS1 ;AND FORCE IT OUT INTO THE COLD CRUEL WORLD
|
||
;XDCAB -- SEND CONTINUE (ABORT) MESSAGE
|
||
;XDCRS -- SEND CONTINUE (RESUME) MESSAGE
|
||
;XDCTA -- SEND CONTINUE (TRY AGAIN) MESSAGE
|
||
;XDCSK -- SEND CONTINUE (SKIP AND CONTINUE) MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XDCTA/CRS/CTA/CSK
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;On error return the network aborted.
|
||
;
|
||
;On successful return a CONTINUE(xxx) message has been shipped to the
|
||
;remote file service.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
;CONTINUE(ABORT)
|
||
|
||
ENTRY .XDCAB
|
||
INTERN XDCAB0, XDCAB1
|
||
|
||
.XDCAB: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDCAB0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDCAB1: MOVEI T2,$DVCAB ;"ABORT" FUNCTION
|
||
PJRST XDC2F1 ;SKIP A CONTINUE(ABORT) MESSAGE
|
||
|
||
|
||
|
||
;CONTINUE(RESUME)
|
||
|
||
ENTRY .XDCRS
|
||
INTERN XDCRS0, XDCRS1
|
||
|
||
.XDCRS: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDCRS0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDCRS1: MOVEI T2,$DVCRS ;"RESUME" FUNCTION
|
||
PJRST XDC2F1 ;SHIP OFF THE CONTINUE(RESUME) MESSAGE
|
||
;CONTINUE(TRY AGAIN)
|
||
|
||
ENTRY .XDCTA
|
||
INTERN XDCTA0, XDCTA1
|
||
|
||
.XDCTA: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDCTA0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDCTA1: MOVEI T2,$DVCTA ;"TRY AGAIN" FUNCTION
|
||
PJRST XDC2F1 ;PACKAGE AND SHIP A CONTINUE(TRY AGAIN)
|
||
|
||
|
||
|
||
;CONTINUE(SKIP)
|
||
|
||
ENTRY .XDCSK
|
||
INTERN XDCSK0, XDCSK1
|
||
|
||
.XDCSK: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDCSK0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDCSK1: MOVEI T2,$DVCSK ;"SKIP AND CONTINUE" FUNCTION
|
||
PJRST XDC2F1 ;SHIP A CONTINUE(SKIP) MESSAGE
|
||
|
||
|
||
|
||
;COMMON CONTINUE(XXX)
|
||
|
||
XDC2F1: MOVX T3,IO.SID ;GET SEND-INTERRUPT-DATA FLAG
|
||
TDNE T3,.IOCCF(IO) ;WANT THIS CONTINUE(XXX) SENT AS INTERRUPT ?
|
||
JRST XDC2F2 ;YES, GO PACKAGE AS INTERRUPT DATA AND SHIP IT
|
||
MOVD1M T2,C2F ;NO, SAVE THE "CONTINUE" FUNCTION
|
||
MOVDII T2,M05,C2F ;MENU FIELD: FUNCTION ONLY
|
||
MOVDM T2,M05 ;SET CONTINUE "HIDDEN" MENU
|
||
MOVEI T2,$DHCNT ;DAP CONTINUE MESSAGE CODE
|
||
PUSHJ P,XDDAP1 ;PACKAGE THE CONTINUE MESSAGE
|
||
POPJ P, ;SOMETHING BROKE
|
||
PJRST XDFLS1 ;AND FORCE IT OUT NOW
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
XDC2F2: ANDCAM T3,.IOCCF(IO) ;CLEAR THE SEND-INTERRUPT-DATA FLAG
|
||
MOVEI P2,$DHCNT ;GET THE CONTINUE MESSAGE TYPE
|
||
LSH P2,^D28 ;POSITION IN THE MESSAGE IN P2
|
||
LSH T2,^D12 ;POSITION THE "CONTINUE" FUNCTION
|
||
IOR P2,T2 ;INCLUDE IN MESSAGE IN P2
|
||
|
||
MOVE P1,[XWD 3,2] ;<NO. BYTES,,NO. WORDS> IN P1/P2 STRING BLOCK
|
||
|
||
MOVE T2,[.NSFIS,,.NSAA1+1] ;.NSAFN SEND-INTERRUPT-DATA,,ARG COUNT
|
||
MOVE T3,.IONCH(IO) ;.NSACH DECNET CHANNEL
|
||
XMOVEI T4,P1 ;.NSAA1 POINTER TO STRING BLOCK
|
||
|
||
XMOVEI M0,T2 ;ARG POINTER TO SEND INTERRUPT DATA
|
||
NSP. M0, ;SEND IT
|
||
JRST NDRXE1 ;GO SEE WHY THIS DIED
|
||
JRST .POPJ1## ;RETURN HAPPILY
|
||
;XDEOF -- SEND "END OF FILE" STATUS MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; PUSHJ P,XDEOF
|
||
; error return
|
||
; normal return
|
||
;
|
||
;On error return the network aborted
|
||
;
|
||
;On normal return a DAP STATUS "EOF" has been packaged and transmitted to
|
||
;the remote. This status message contains only the status code, no other
|
||
;fields are transmitted.
|
||
;
|
||
;Uses T1 - T4.
|
||
|
||
ENTRY .XDEOF
|
||
INTERN XDEOF0, XDEOF1
|
||
|
||
.XDEOF: PUSHJ P,.SACIO## ;SETUP I/O CONTEXT
|
||
XDEOF0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDEOF1: MOVEI T2,50000+$DSEOF ;DAP "EOF" STATUS CODE
|
||
MOVD1M T2,STC ;SET STATUS CODE
|
||
MOVDII T2,M09,STC ;FLAG ONLY THE STATUS CODE IN THE MENU
|
||
MOVDM T2,M09 ;AND SET THE "HIDDEN" MENU FIELD
|
||
MOVEI T2,$DHSTS ;DAP STATUS MESSAGE TYPE
|
||
PJRST XDDAP1 ;OFF TO THE GENERAL DAP MESSAGE SENDER
|
||
;XDDAT -- START UP A DATA MESSAGE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2/T3,<RECN>
|
||
; PUSHJ P,XDDAT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and <RECN> is the
|
||
;64-bit double-precision integer record number to use in the DATA message.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On normal return a data message (code = $DHDAT) has been started
|
||
;and may be filled via calls to XDBYT.
|
||
;
|
||
;Uses T1 - T4
|
||
|
||
ENTRY .XDDAT
|
||
INTERN XDDAT0, XDDAT1
|
||
|
||
.XDDAT: PUSHJ P,.SACIO## ;SET UP I/O CDB INDEX
|
||
XDDAT0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDDAT1: MOVDM T2,RCN ;SET OUTPUT RECORD NUMBER TEMPLATE
|
||
MOVEI T2,$DHDAT ;DATA MESSAGE CODE
|
||
PUSHJ P,XDDAP2 ;START UP A DATA MESSAGE
|
||
POPJ P, ;ERROR
|
||
XMT < PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.TTABC## ;TAB ACROSS BEFORE TYPING DATA BYTES
|
||
MOVEI T1,[ASCIZ \<XMT> \] ;ENSURE USER KNOWS THIS IS TRANSMITTED DATA
|
||
PUSHJ P,.TSTRG## >
|
||
JRST .POPJ1## ;READY FOR DATA BYTES
|
||
;XDDAP -- BUILD AND SEND A GENERIC DAP MESSAGE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<code>
|
||
; PUSHJ P,XDDAP
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; <code> is the DAP message
|
||
;code for the message to be sent. Data messages (<code> = $DHDAT)
|
||
;are illegal.
|
||
;
|
||
;On error return either the network died (M0 has the error code) or
|
||
;an input message has been received and needs to be processed (in which
|
||
;case no data has been sent - the XDDAP call must be re-executed in
|
||
;order to send the desired DAP message).
|
||
;
|
||
;On normal return the DAP message has been built and is in the network
|
||
;output buffer (a call to XDFLS must be executed if the message must
|
||
;be guaranteed transmitted - otherwise the message may be kept in the
|
||
;network buffer in order to "piggyback" multiple DAP messages into one
|
||
;physical network transmission message).
|
||
;
|
||
;Uses T1, T2, T3, T4
|
||
|
||
ENTRY .XDDAP
|
||
INTERN XDDAP0, XDDAP1
|
||
|
||
.XDDAP: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDDAP0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
XDDAP1: PUSHJ P,TSAV12## ;SAVE T1 AND T2
|
||
CAIN T2,$DHDAT ;DATA MESSAGE?
|
||
STOPCD <XDDAP called for DATA message>
|
||
XDDAP2: MOVEI T4,DAPIDX ;INDEX TABLE
|
||
PUSHJ P,.CFIND## ;FIND STARTING INDEX INTO EXECUTION TABLE
|
||
STOPCD <XDDAP called with unknown DAP message>
|
||
HRRZM T1,.IODXX(IO) ;SET XDDAP EXECUTION TABLE INDEX
|
||
PUSHJ P,XDMSG1 ;START A NEW DAP MESSAGE
|
||
JRST XDDAP9 ;CAN'T, CHECK IT OUT
|
||
|
||
;LOOP BUILDING FIELDS IN THE DAP OUTPUT MESSAGE
|
||
|
||
XDDAP4: AOS P1,.IODXX(IO) ;NEXT MESSAGE FIELD
|
||
MOVE T1,DAPXCT(P1) ;FETCH COPY OF EXECUTION TABLE ENTRY
|
||
LDB T3,[POINTR T1,DX$TYP] ;FIELD "TYPE"
|
||
CAILE T3,$DXTMX ;WITHIN OUR LIMITS?
|
||
STOPCD <DX$TYP field type too big in XDDAP>
|
||
JUMPE T3,XDDAP7 ;EXIT IF END OF MESSAGE TEMPLATE
|
||
.XCREF $DXTMS ;CREF REFERENCE TO SYMBOLIC NAME
|
||
|
||
;DISPATCH TO FIELD HANDLER WITH P1/INDEX AND T1/DAPXCT TABLE ENTRY
|
||
|
||
TXNE T1,DX$ILM!DX$SKP;A FIELD THAT WE SHOULD IGNORE?
|
||
JRST [CAIN T3,$DXTMN ;YES - EXCEPT THAT
|
||
JRST .+1 ;MENUS REQUIRE SPECIAL ATTENTION
|
||
JRST XDDAP4] ;JUST SKIP THIS DAP FIELD
|
||
XMT < PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX(P1) ;ADDR OF FIELD DESCRIPTIVE TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
MOVE T1,DAPXCT(P1) > ;WE USED T1 SO RETRIEVE EXECUTION TABLE ENTRY
|
||
PUSHJ P,@XDDAPX(T3) ;DISPATCH ON FIELD TYPE
|
||
JRST XDDAP9 ;POSSIBLE ERROR SOMEWHERE
|
||
JRST XDDAP4 ;ADVANCE TO NEXT FIELD
|
||
|
||
;HERE WHEN DAP OUTPUT MESSAGE COMPLETED
|
||
|
||
XDDAP7: MOVE T2,.IODOM(IO) ;GET MESSAGE CODE
|
||
CAIN T2,$DHDAT ;IS IT A DATA MESSAGE?
|
||
JRST .POPJ1## ;YES, THEN MORE STILL TO COME
|
||
PJRST XDEOM1 ;NO, CAP OFF THE OUTPUT MESSAGE.
|
||
|
||
;HERE WHEN WE COULDN'T COMPLETE THE OUTPUT MESSAGE
|
||
|
||
XDDAP9: CAIE M0,$ECTRA ;SHOULD WE TRY AGAIN?
|
||
POPJ P, ;NO, HIGHER-UP'S INTERVENTION REQUIRED
|
||
MOVE T2,-T2(P) ;YES, FETCH MESSAGE CODE BACK
|
||
; EVEN THOUGH IT MIGHT SEEM LIKE AN ERROR
|
||
; TO DO THIS IF ENTERED AT XDMSG2 FROM XDDAT,
|
||
; $ECTRA SHOULD NEVER HAPPEN FOR DATA SINCE
|
||
; DATA MESSAGES ONLY NEED A FEW BYTES TO
|
||
; GET STARTED, WHICH THEY ARE GUARANTEED
|
||
; IF XDMSG RETURNS SUCCESSFULLY . . .
|
||
JRST XDDAP2 ;TRY AGAIN
|
||
|
||
;DAP MESSAGE FIELD PROCESSOR DISPATCH TABLE
|
||
|
||
;EACH FIELD PROCESSING ROUTINE IS ENTERED WITH:
|
||
; T1/DAPXCT TABLE ENTRY FOR THE FIELD
|
||
; P1/DAPXCT TABLE INDEX FOR THE FIELD
|
||
;ACS T1 - T4, AND P1 - P4 ARE AVAILABLE FOR USAGE WITHIN THE VARIOUS
|
||
;FIELD PROCESSING ROUTINES
|
||
|
||
XDDAPX: XD00T ;00 - START OF DAP MESSAGE TEMPLATE
|
||
XD01T ;01 - ASCII TEXT
|
||
XD02T ;02 - BINARY [INTEGER] DATA
|
||
XD03T ;03 - COMPRESSED (1 WORD/5 BYTES) BINARY
|
||
XD04T ;04 - FLAGS (BIT MAP)
|
||
XD05T ;05 - IMAGE 8-BIT BYTES
|
||
XD06T ;06 - MENU FIELD
|
||
XD07T ;07 - DATE/TIME FIELD
|
||
;XD00T - START OF NEW DAP MESSAGE TEMPLATE
|
||
|
||
XD00T: STOPCD <XD00T dispatch in XDDAP>
|
||
;XD01T - ASCII TEXT FIELD
|
||
|
||
XD01T: MOVE P2,T1 ;PROTECT COPY OF EXECUTION TABLE ENTRY
|
||
LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
LDB T4,[POINTR T1,DX$IOX] ;DAP AREA OFFSET
|
||
ADD T4,[POINT 7,.IODAP(IO)];MAKE INTO BYTE POINTER
|
||
TXNE T1,DX$XTN ;EXTENSIBLE ASCII?
|
||
JRST XD01T5 ;YES
|
||
TXNN T1,DX$VAR ;VARIABLE LENGTH ASCII?
|
||
JRST XD01T3 ;NO, FIXED LENGTH
|
||
PUSHJ P,XDBYT0 ;YES, ALLOCATE COUNT BYTE
|
||
POPJ P, ;OOPS
|
||
MOVE P3,.IONOP(IO) ;REMEMBER POINTER TO THE COUNT BYTE
|
||
JRST XD01T3 ;ENTER BYTE LOOP
|
||
|
||
;LOOP SENDING FIXED/VARIABLE ASCII OUTPUT FIELD
|
||
|
||
XD01T2: SOJL T3,XD01T9 ;FIELD SIZE OK?
|
||
PUSHJ P,XDBYT0 ;YES, STUFF THIS ASCII CHARACTER
|
||
POPJ P, ;OOPS
|
||
XD01T3: ILDB T2,T4 ;GET ANOTHER POSSIBLE ASCII CHARACTER
|
||
JUMPN T2,XD01T2 ;STORE IF NOT YET END OF STRING
|
||
LDB T2,[POINTR P2,DX$LNB] ;LENGTH (MAXIMUM) OF FIELD
|
||
SUB T2,T3 ;T2:=ACTUAL FIELD LENGTH
|
||
TXNE P2,DX$VAR ;VARIABLE LENGTH FIELD?
|
||
DPB T2,P3 ;YES, SET COUNT BYTE
|
||
TXNE P2,DX$VAR ;FIXED LENGTH FIELD?
|
||
NOXMT < JRST .POPJ1## ;NO, ALL DONE HERE
|
||
JUMPE T3,.POPJ1## > ;YES, FIELD STILL LEFT?
|
||
XMT < JRST XD01TV ;NO, ALL DONE HERE
|
||
JUMPE T3,XD01TF > ;YES, FIELD STILL LEFT?
|
||
SETZ T2, ;YES, NULL-FILL REMAINDER OF FIELD
|
||
PUSHJ P,XDBYT1 ;FILL WITH ANOTHER NULL
|
||
POPJ P, ;OOPS
|
||
SOJG T3,.-2 ;LOOP FOR REST OF FIELD
|
||
NOXMT < JRST .POPJ1## > ;SUCCESSFUL RETURN
|
||
XMT <
|
||
XD01TF: MOVEI T1,[ASCIZ \ [fix len ASCII, len from DAP spec= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS FIXED LENGTH ASCII
|
||
PUSHJ P,FIXLEN ;TYPE THE LENGTH
|
||
LDB T3,[POINTR DAPXCT(P1),DX$LNB] ;RETRIEVE FIELD LENGTH TO T3
|
||
JRST XD01T4 > ;ENTER LOOP
|
||
|
||
|
||
XMT <
|
||
XD01TV: MOVEI T1,[ASCIZ \ [var len ASCII, len= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS VAR LENGTH ASCII
|
||
LDB T3,P3 ;GET LENGTH OF VAR LENGTH STRING IN T3
|
||
PUSHJ P,VARLEN ;TYPE OUT FIELD LENGTH
|
||
JUMPN T3,XD01T4 ;IF ANY BYTES, GO TYPE THEM
|
||
PUSHJ P,.TCRLF## ;NO BYTES SO FINISH LINE
|
||
JRST .POPJ1## ;RETURN
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
XD01T4: ILDB T2,P3 ;GET A DATA BYTE FROM XMT BUFFER
|
||
PUSHJ P,.TSPAC## ;TYPE A SPACE
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE
|
||
SOJG T3,XD01T4 ;TYPE ALL THE HEX BYTES
|
||
JRST XD01T8 > ;GO TYPE OUT ASCII STRING OF THESE BYTES
|
||
|
||
;LOOP SENDING EXTENSIBLE ASCII OUTPUT
|
||
|
||
XD01T5:
|
||
XMT < MOVE P3,.IONOP(IO) ;REMEMBER POINTER TO CURRENT BYTE
|
||
MOVE P4,T3 > ;REMEMBER FIELD LENGTH
|
||
ILDB T2,T4 ;FIRST CHARACTER
|
||
JUMPN T2,XD01T7 ;OK IF NON-NULL STRING
|
||
PUSHJ P,XDBYT1 ;NULL STRING, FILL OUT THE FIELD
|
||
POPJ P, ;OOPS
|
||
XMT < JRST XD01EX > ;TELL USER THIS IS EXTENSIBLE ASCII
|
||
JRST .POPJ1## ;THAT'S ALL HERE
|
||
|
||
XD01T7: SOJL T3,XD01T9 ;MAKE SURE STILL ROOM
|
||
TRO T2,200 ;MAKE EXTENSIBLE BYTE
|
||
PUSHJ P,XDBYT1 ;AND PUT IN OUTPUT MESSAGE
|
||
POPJ P, ;OOPS
|
||
ILDB T2,T4 ;NEXT BYTE
|
||
JUMPN T2,XD01T7 ;LOOP WHILE STRING LASTS
|
||
LDB T2,.IONOP(IO) ;RE-FETCH LAST CHARACTER
|
||
TRZ T2,200 ;MARK END OF EXTENSIBLE STRING
|
||
DPB T2,.IONOP(IO) ;RE-STORE LAST CHARACTER OF FIELD
|
||
XMT <
|
||
XD01EX: MOVEI T1,[ASCIZ \ [extensible ASCII]\]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS EXTENSIBLE ASCII
|
||
ILDB T2,P3 ;RETRIEVE BYTE FROM XMT BUFFER
|
||
PUSHJ P,EXTENS ;TYPE OUT EXTENSIBLE BYTE
|
||
TRNE T2,200 ;ALL DONE IF "0" EXTENSIBLE FLAG
|
||
SOJG P4,.-3 ;LOOP FOR ALL BYTES
|
||
|
||
XD01T8: PUSHJ P,ASCSTR ;TYPE OUT ASCII STRING FOR THIS FIELD
|
||
PUSHJ P,.TCRLF## > ;FINISH THE LINE NEATLY
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
;STRING FIELD SIZE EXCEEDED
|
||
|
||
XD01T9: STOPCD <ASCII string too long for DAP field in XD01T>
|
||
;XD02T - BINARY DATA FIELD
|
||
;XD03T - COMPRESSED BINARY DATA
|
||
|
||
XD02T: ;THEY'RE THE SAME (ALMOST)
|
||
XD03T: MOVE P2,T1 ;SAVE A COPY OF THE EXECUTION TABLE ENTRY
|
||
LDB P3,[POINTR P2,DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
CAILE P3,^D9 ;WILL IT FIT OUR ALGORITHM?
|
||
STOPCD <Binary DAP field larger than 9 bytes in XD03T>
|
||
LDB T1,[POINTR P2,DX$LNB] ;SIZE OF FIELD IN 8-BIT BYTES
|
||
CAIG T1,4 ;MORE THAN ONE -10 WORDS' WORTH?
|
||
MOVEI T1,1 ;NO, ONE WORD IS SUFFICIENT
|
||
CAILE T1,4 ;LESS THAN TWO -10 WORDS' WORTH?
|
||
MOVEI T1,2 ;NO, TWO WORDS NEEDED
|
||
LDB T4,[POINTR P2,DX$TYP] ;FIELD TYPE
|
||
CAIN T4,$DXTCN ;COMPRESSED 1 WORD VALUE?
|
||
MOVEI T1,1 ;YES, SIZE IS ONE WORD THEN
|
||
LDB T2,[POINTR P2,DX$IOX] ;DAP AREA OFFSET
|
||
ADDI T2,.IODAP(IO) ;RELOCATE ADDRESS
|
||
SETZ T3, ;ASSUME ONLY ONE-WORD VALUE
|
||
CAIN T1,1 ;ONE-WORD FIELD?
|
||
MOVE T4,(T2) ;YES
|
||
CAIN T1,2 ;TWO-WORD FIELD?
|
||
DMOVE T3,(T2) ;YES
|
||
LSH T4,1 ;POSITION AND
|
||
LSHC T3,-1 ;CONCATENATE TWO HALVES
|
||
TXNE P2,DX$XTN ;EXTENSIBLE BINARY?
|
||
JRST XD03T7 ;YES
|
||
TXNN P2,DX$VAR ;NO, VARIABLE-LENGTH BINARY?
|
||
NOXMT < JRST XD03T3 > ;NO, FIXED-LENGTH FIELD
|
||
XMT < JRST XD03T1 > ;NO, FIXED-LENGTH FIELD
|
||
PUSHJ P,XDBYT0 ;YES, ALLOCATE COUNT BYTE
|
||
POPJ P, ;OOPS
|
||
XMT <
|
||
XD03T1: PUSH P,T3 ;SAVE THE BINARY VALUE FROM T3, T4 ON STACK
|
||
PUSH P,T4 > ; . . .
|
||
MOVE P4,.IONOP(IO) ;REMEMBER WHERE COUNT BYTE IS
|
||
JRST XD03T3 ;ENTER LOOP
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;LOOP SENDING FIXED/VARIABLE BINARY FIELD
|
||
|
||
XD03T2: ROTC T3,-^D8 ;POSITION NEXT LEAST SIGNIFICANT BYTE
|
||
LSHC T2,^D8 ;AND PUT THE BYTE IN T2
|
||
LSH T3,-^D8 ;CORRECT T3
|
||
SOJL P3,XD03T9 ;MAKE SURE STILL FITS
|
||
PUSHJ P,XDBYT0 ;STUFF AWAY THIS BYTE
|
||
NOXMT < POPJ P, > ;OOPS
|
||
XMT < JRST [ADJSP P,-2 ;FIX STACK
|
||
POPJ P, ] > ;TAKE THE ERROR RETURN
|
||
XD03T3: JUMPN T3,XD03T2 ;LOOP FOR ALL OF FIELD
|
||
JUMPN T4,XD03T2 ; (ALL TWO WORDS' WORTH)
|
||
LDB T2,[POINTR P2,DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
SUB T2,P3 ;ACTUAL FIELD LENGTH
|
||
TXNE P2,DX$VAR ;VARIABLE-LENGTH FIELD?
|
||
DPB T2,P4 ;YES, SET BYTE COUNT
|
||
TXNE P2,DX$VAR ;FIXED-LENGTH FIELD?
|
||
NOXMT < JRST .POPJ1## ;NO, ALL DONE HERE
|
||
JUMPLE P3,.POPJ1## > ;YES, FIELD FULL?
|
||
XMT < JRST XD03TV ;NO, ALL DONE HERE
|
||
JUMPLE P3,XD03TF > ;YES, FIELD FULL?
|
||
SETZ T2, ;NO, NEED NULL-FILL
|
||
PUSHJ P,XDBYT0 ;FILL REST OF FIELD
|
||
NOXMT < POPJ P, > ;OOPS
|
||
XMT < JRST [ADJSP P,-2 ;FIX STACK
|
||
POPJ P, ] > ;TAKE THE ERROR RETURN
|
||
SOJG P3,.-2 ;LOOP FOR REST OF FIELD
|
||
NOXMT < JRST .POPJ1## > ;ALL DONE
|
||
|
||
XMT <
|
||
XD03TF: MOVEI T1,[ASCIZ \ [fix len bin, len from DAP spec= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS FIXED LENGTH BINARY
|
||
PUSHJ P,FIXLEN ;TELL USER THE LENGTH
|
||
LDB T3,[POINTR DAPXCT(P1),DX$LNB] ;GET THE LENGTH IN T3
|
||
JRST XD03T5 > ;ENTER LOOP
|
||
|
||
XMT <
|
||
XD03TV: MOVEI T1,[ASCIZ \ [var len bin, len= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS VAR LENGTH BINARY
|
||
LDB T3,P4 ;GET THE FIELD LENGTH IN T3
|
||
PUSHJ P,VARLEN ;TYPE OUT FIELD LENGTH
|
||
JUMPN T3,XD03T5 ;TYPE OUT BYTES IF ANY
|
||
ADJSP P,-2 ;NO BYTES, WANT TO POP STACK TWICE
|
||
JRST XD03T6 ;GO FINISH THE LINE
|
||
|
||
XD03T5: ILDB T2,P4 ;GET A DATA BYTE FROM XMT BUFFER
|
||
PUSHJ P,.TSPAC## ;TYPE A SPACE
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE
|
||
SOJG T3,XD03T5 ;TYPE ALL THE HEX BYTES
|
||
|
||
POP P,T4 ;GET SECOND WORD OF BINARY NO.
|
||
POP P,T3 ;GET FIRST WORD OF BINARY NO.
|
||
PUSHJ P,BINFLD ;TYPE OUT BINARY VALUE
|
||
XD03T6: PUSHJ P,.TCRLF## ;FINISH OFF THE LINE
|
||
JRST .POPJ1## > ;SUCCESSFUL RETURN
|
||
|
||
;EXTENSIBLE BINARY FIELD
|
||
|
||
XD03T7: STOPCD <Extensible DAP binary field encountered in XD03T>
|
||
|
||
;BINARY FIELD TOO LARGE
|
||
|
||
XD03T9: STOPCD <Binary value exceeded DAP binary field size in XD03T>
|
||
;XD04T - SEND FLAGS (BIT MAP) FIELD
|
||
|
||
XD04T: LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
LDB T4,[POINTR T1,DX$IOX] ;DAP AREA OFFSET
|
||
ADD T4,[POINT 7,.IODAP(IO)];MAKE INTO BYTE POINTER
|
||
TXNE T1,DX$XTN ;EXTENSIBLE FIELD?
|
||
JRST XD04T2 ;YES
|
||
STOPCD <Fixed/variable length DAP flags field encountered in XD04T>
|
||
|
||
;LOOP SENDING EXTENSIBLE FLAGS FIELD
|
||
|
||
XD04T2:
|
||
XMT < MOVEI T1,[ASCIZ \ [extensible flags field]\] ;ASSUME EXTENS FLAGS
|
||
LDB T2,[POINTR DAPXCT(P1),DX$TYP] ;GET FIELD TYPE
|
||
CAIE T2,$DXTFL ;REALLY EXTENSIBLE FLAGS ?
|
||
MOVEI T1,[ASCIZ \ [extensible menu field]\] ;NO, MUST BE MENU
|
||
PUSHJ P,.TSTRG## ; . . .
|
||
MOVE P3,.IONOP(IO) ;SAVE POINTER TO OUTPUT BUFFER IN P3
|
||
MOVE P4,T3 > ;SAVE FIELD LENGTH IN P4
|
||
ILDB T2,T4 ;FIRST FLAG BYTE
|
||
TROA T2,200 ;GUARANTEE AT LEAST ONE BYTE
|
||
XD04T3: ILDB T2,T4 ;NEXT FLAG BYTE
|
||
JUMPE T2,XD04T9 ;SEE IF TRAILING NULL
|
||
XD04T4: TRO T2,200 ;SET EXTENSIBLE BIT
|
||
PUSHJ P,XDBYT1 ;PUT INTO OUTPUT MESSAGE
|
||
POPJ P, ;OOPS
|
||
SOJG T3,XD04T3 ;LOOP FOR REST OF FIELD
|
||
XD04T5: LDB T2,.IONOP(IO) ;RE-FETCH LAST BYTE
|
||
TRZ T2,200 ;CLEAR EXTENSIBLE BIT
|
||
DPB T2,.IONOP(IO) ;RE-STORE LAST BYTE OF EXTENSIBLE FIELD
|
||
XMT < MOVE T4,P4 ;GET FIELD LENGTH IN T4
|
||
XD04T6: ILDB T2,P3 ;GET EXTENSIBLE FLAG BYTE
|
||
PUSHJ P,EXTENS ;TYPE OUT THE EXTENSIBLE BYTE
|
||
TRNE T2,200 ;ALL DONE IF "0" EXTENSIBLE FLAG
|
||
SOJG T4,XD04T6 ;LOOP IF FIELD NOT EXHAUSTED
|
||
|
||
PUSHJ P,.TCRLF## ;FINISH THE LINE
|
||
LDB T1,[POINTR DAPXCT(P1),DX$TYP] ;GET FIELD TYPE
|
||
CAIN T1,$DXTFL ;EXTENSIBLE FLAGS ?
|
||
PUSHJ P,FLGFLD > ;YES,TYPE CORRESP. FLAG MESSAGES
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
XD04T9: MOVE T1,T3 ;SAVE BYTE COUNT
|
||
SOJLE T3,XD04T5 ;COUNT DOWN TRAILING NULLS
|
||
ILDB T2,T4 ;FETCH NEXT BYTE'S WORTH OF FLAGS
|
||
JUMPE T2,.-2 ;COMPRESS OUT NULLS
|
||
SUB T1,T3 ;NON-NULL FLAG,
|
||
MOVEI T2,200 ;EXTENSIBLE NULL BYTE
|
||
PUSHJ P,XDBYT1 ;FILL OUT NULL BYTES
|
||
POPJ P, ;OOPS
|
||
SOJG T1,.-2 ;LOOP FOR EMBEDDED NULLS
|
||
LDB T2,T4 ;RE-FETCH NON-NULL FLAG BYTE
|
||
JRST XD04T4 ;AND SEND IT OUT
|
||
;XD05T - IMAGE 8-BIT BYTES
|
||
|
||
XD05T: LDB T3,[POINTR T1,DX$LNB] ;FIELD LENGTH
|
||
LDB T4,[POINTR T1,DX$IOX] ;DAP AREA OFFSET
|
||
ADD T4,[POINT 8,.IODAP(IO)];MAKE INTO BYTE POINTER
|
||
TXNE T1,DX$XTN ;EXTENSIBLE IMAGE?
|
||
JRST XD05T5 ;YES
|
||
TXNN T1,DX$VAR ;NO, VARIABLE-LENGTH IMAGE FIELD?
|
||
NOXMT < JRST XD05T2 > ;NO, FIXED LENGTH
|
||
XMT < JRST XD05T1 > ;NO, FIXED LENGTH
|
||
MOVE T2,T3 ;VARIABLE-LENGTH, GET SIZE OF FIELD
|
||
PUSHJ P,XDBYT1 ;ALLOCATE BYTE COUNT BYTE
|
||
POPJ P, ;OOPS
|
||
XMT < MOVEI T1,[ASCIZ \ [var len image, len= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS VAR LENGTH IMAGE
|
||
PUSHJ P,VARLEN ;TYPE OUT FIELD LENGTH
|
||
JRST XD05T2 > ;ENTER LOOP
|
||
|
||
XMT <
|
||
XD05T1: MOVEI T1,[ASCIZ \ [fix len image, len from DAP spec= \]
|
||
PUSHJ P,.TSTRG## ;TELL USER IT IS FIXED LENGTH IMAGE
|
||
PUSHJ P,FIXLEN > ;TYPE OUT FIELD LENGTH
|
||
|
||
;LOOP SENDING ENTIRE IMAGE FIELD (FOR NOW AT LEAST)
|
||
|
||
XD05T2: ILDB T2,T4 ;NEXT IMAGE BYTE
|
||
PUSHJ P,XDBYT1 ;STUFF INTO MESSAGE
|
||
POPJ P, ;OOPS
|
||
XMT < PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
PUSHJ P,.THEXB > ;TYPE-OUT BYTE FROM T2
|
||
SOJG T3,XD05T2 ;LOOP FOR REST OF MESSAGE FIELD
|
||
XMT < PUSHJ P,.TCRLF## > ;FINISH LINE
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
;LOOP SENDING EXTENSIBLE IMAGE FIELD
|
||
|
||
XD05T5: STOPCD <Extensible DAP image field encountered in XD05T>
|
||
;XD06T - MENU FIELD
|
||
|
||
XD06T: TXNE T1,DX$SKP ;"INVISIBLE" MENU?
|
||
NOXMT < JRST XD06T1 > ;YES, DON'T TRANSMIT IT, BUT STILL PROCESS IT
|
||
XMT < JRST [MOVEI T1,[ASCIZ \ ("invisible" menu, ignored)\]
|
||
PUSHJ P,.TSTRG##
|
||
PUSHJ P,.TCRLF##
|
||
JRST XD06T1]>;DON'T TRANSMIT IT, BUT STILL PROCESS IT
|
||
PUSHJ P,XD04T ;SEND MENU AS FLAGS
|
||
POPJ P, ;OOPS
|
||
XD06T1: MOVE P1,.IODXX(IO) ;RESTORE DAPXCT INDEX (JUST TO BE SURE)
|
||
LDB T3,[POINTR DAPXCT(P1),DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
LDB T4,[POINTR DAPXCT(P1),DX$IOX] ;FIELD OFFSET WITHIN DAP AREA
|
||
ADD T4,[POINT 7,.IODAP(IO)] ;MAKE INTO BYTE POINTER
|
||
DMOVEM T3,.IODXM(IO) ;SET DAP MENU COUNTER/POINTER
|
||
|
||
;LOOP BUILDING REST OF MESSAGE AS DESCRIBED BY THE MENU
|
||
|
||
XD06M1: ILDB P2,.IODXM+1(IO) ;GET A MENU BYTE
|
||
TROA P2,200 ;FORCE 7-BITS-WORTH OF LOOP
|
||
|
||
;LOOP WITHIN 7-BIT MENU BYTE
|
||
|
||
XD06M2: LSH P2,-1 ;NEXT MENU BIT
|
||
AOS P1,.IODXX(IO) ;CORRESPONDING EXECUTION TABLE INDEX
|
||
TRZN P2,1 ;THIS FIELD WANT TO BE SENT?
|
||
JUMPN P2,XD06M5 ;NO, SEE IF ANYTHING MORE
|
||
JUMPE P2,XD06M7 ;YES - UNLESS FAKE BIT ("TROA" ABOVE)
|
||
|
||
;BUILD MENU-SPECIFIED FIELD AND PUT IT IN THE OUTPUT MESSAGE
|
||
|
||
MOVE T1,DAPXCT(P1) ;EXECUTION TABLE ENTRY FOR THIS FIELD
|
||
LDB T3,[POINTR T1,DX$TYP] ;FIELD "TYPE"
|
||
CAILE T3,$DXTMX ;ONE WE KNOW ABOUT?
|
||
STOPCD <DX$TYP field too large in XD06M>
|
||
CAIE T3,$DXTMS ;YES, START OF MESSAGE?
|
||
CAIN T3,$DXTMN ;OR MENU?
|
||
STOPCD <SOM or MENU field encountered within menu in XD06M>
|
||
XMT < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
MOVE T1,DAPXTX(P1) ;ADDR OF FIELD DESCRIPTIVE TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
MOVE T1,DAPXCT(P1) > ;PICK UP EXECUTION TABLE ENTRY
|
||
PUSH P,P2 ;SAVE P2
|
||
PUSHJ P,@XDDAPX(T3) ;OK MESSAGE TYPE, BUILD THE FIELD
|
||
JRST [POP P,P2 ;ERROR, ADJUST STACK
|
||
POPJ P,] ;PROPAGATE THE ERROR
|
||
POP P,P2 ;RESTORE MENU BYTE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
XD06M5: LDB T3,[POINTR DAPXCT+1(P1),DX$TYP] ;PEEK AT NEXT FIELD TYPE
|
||
CAIE T3,$DXTMS ;END OF CURRENT MESSAGE TEMPLATE?
|
||
JRST XD06M2 ;NO, MORE FIELDS TO TRY
|
||
MOVE T1,P2 ;YES, WHAT'S LEFT OF CURRENT MENU BYTE
|
||
JFFO T1,.+1 ;FIND THE FIRST BIT SET
|
||
LSH T1,1(T2) ;AND TOSS IT OUT ("TROA" ABOVE)
|
||
JUMPN T1,XD06M9 ;IF ANY BITS SET THEN ERROR
|
||
ILDB T1,.IODXM+1(IO) ;NEXT MENU BYTE
|
||
SOSLE .IODXM+0(IO) ;MAKE SURE IT'S OK (BLANK) TOO
|
||
JRST .-3 ; . . .
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
XD06M7: SOS .IODXX(IO) ;THE "TROA" BIT DOESN'T COUNT AGAINST INDEX
|
||
SOSLE .IODXM+0(IO) ;COUNT DOWN MENU BYTES
|
||
JRST XD06M1 ;AND PROCESS THE NEXT ONE
|
||
|
||
XD06M9: STOPCD <Too many menu bits/bytes in XD06M>
|
||
;XD07T - SEND DATE/TIME FIELD
|
||
|
||
XD07T: LDB P3,[POINTR T1,DX$LNB] ;DAP FIELD LENGTH
|
||
LDB P4,[POINTR T1,DX$IOX] ;DAP AREA OFFSET
|
||
ADDI P4,.IODAP(IO) ;P4:=ADDRESS OF DATE/TIME WORD
|
||
XMT < MOVEI T1,[ASCIZ \ [ASCII date/time field] \]
|
||
PUSHJ P,.TSTRG## > ;INFORM USER OF DATE/TIME FIELD
|
||
PUSHJ P,XD07DT ;PUT ASCIZ DATE/TIME IN .IODTM(IO)
|
||
|
||
;NOW CAN SAFELY SEND THE ASCIZ STRING (AND GET BLOCKED IF NEEDED)
|
||
|
||
SKIPA P2,[":"] ;MARK DATE/TIME TRANSITION
|
||
XD07T4: CAIE T2,0 ;IF STRING TERMINATED LEAVE TRAILING NULLS
|
||
ILDB T2,P4 ;GET NEXT ASCII CHARACTER
|
||
CAME T2,P2 ;DATE/TIME TRANSITION?
|
||
JRST XD07T5 ;NO, TAKE CHARACTER VERBATIM
|
||
MOVEI T2," " ;YES, DAP WANTS A SPACE HERE
|
||
SETO P2, ;ONLY ONE TRANSITION
|
||
XD07T5: PUSHJ P,XDBYT0 ;SEND THIS DATE/TIME CHARACTER
|
||
POPJ P, ;OOPS
|
||
XMT < MOVE T1,T2 ;GET THE CHAR
|
||
PUSHJ P,.TCHAR## > ;INFORM USER OF DATE/TIME FIELD CHAR
|
||
SOJG P3,XD07T4 ;LOOP FOR ENTIRE FIELD'S WORTH
|
||
|
||
XMT < PUSHJ P,.TCRLF## > ;FINISH LINE
|
||
JRST .POPJ1## ;SUCCESS RETURN
|
||
|
||
;ROUTINE TO MOVE DATE TO .IODTM(IO) AS ASCIZ STRING
|
||
|
||
XD07DT: XMOVEI T1,XD07TO ;HELPER TYPEOUT
|
||
PUSHJ P,.XTYPO## ;SET OUTPUT ROUTINE
|
||
SKIPE T1,(P4) ;GET THE DATE/TIME WORD
|
||
TLNN T1,700000 ;DOES IT LOOK REASONABLE?
|
||
STOPCD <Null/Archaic universal date/time value in XD07T>
|
||
MOVE P4,[POINT 7,.IODTM(IO)] ;POINTER TO HOLDING AREA
|
||
MOVEM P4,.IOXTO(IO) ;SET OUTPUT STUFFER
|
||
PUSHJ P,.TDTTM## ;TYPE OUT DATE/TIME
|
||
SETZ T1, ;NULL
|
||
IDPB T1,.IOXTO(IO) ;ASCIZIZE THE STRING
|
||
POPJ P, ;RETURN
|
||
|
||
;SLAVE HELPER CALLED BY SCAN WITH T1/ASCII CHARACTER
|
||
|
||
XD07TO: CAIL T1,"a" ;LOWER-CASE LETTER?
|
||
CAILE T1,"z" ; (I.E., FROM MONTH)
|
||
CAIA ;NO
|
||
XORI T1,"a"-"A" ;YES, SHIFT TO UPPER CASE
|
||
IDPB T1,.IOXTO(IO) ;STASH THIS CHARACTER
|
||
POPJ P, ;RETURN TO WHENCE-EVER
|
||
;XDBYC -- OUTPUT ONE DAP FILE-DATA-LEVEL BYTE, HANDLING CRC
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<byte>
|
||
; PUSHJ P,XDBYC
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; <byte> is the 8-bit DAP
|
||
;file data byte to be sent (eventually) to the remote DAP receiver.
|
||
;
|
||
;On error return T1 and T2 are preserved. The error or exception code is in
|
||
;M0. If the error is recoverable (e.g., output aborted due to arrival
|
||
;of input message) then the call to XDBYC may simply be re-executed.
|
||
;
|
||
;On successful return the DAP file data byte is safely enscounced away
|
||
;in the output data message being built.
|
||
;
|
||
;XDBYC is functionally identical to XDBYT but the file data CRC is
|
||
;updated to reflect the file data flow.
|
||
;
|
||
;Preserves all acs.
|
||
|
||
ENTRY .XDBYC
|
||
INTERN XDBYC0, XDBYC1
|
||
|
||
INTERN XDCRC1
|
||
|
||
.XDBYC: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDBYC0:
|
||
XDBYC1: PUSHJ P,XDBYT0 ;FIRST STUFF THE FILE DATA BYTE
|
||
POPJ P, ;PROPAGATE EXCEPTION RETURN
|
||
XDCRC1: PUSH P,T2 ;SAVE FILE DATA BYTE
|
||
ANDI T2,377 ;REDUCE TO JUST INTERESTING DATA
|
||
MOVE M0,.IODOK(IO) ;RETRIEVE OLD FILE DATA CRC
|
||
XORB M0,T2 ;INCLUDE BYTE IN CRC
|
||
ANDI T2,377 ;COMPUTE OFFSET INTO CRC TABLE
|
||
LSH M0,-^D08 ;XOR REMAINING CRC FROM TABLE
|
||
XOR M0,DAPCRC(T2) ;COMPUTE NEW CRC
|
||
MOVEM M0,.IODOK(IO) ;SAVE UPDATED CRC
|
||
POP P,T2 ;RESTORE CALLER'S BYTE
|
||
XMT < PUSHJ P,TSAV11## ;PRESERVE T1 (CONTAINS ADDRESS I/O CDB)
|
||
PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.THEXB ;TYPE-OUT BYTE FROM T2
|
||
PUSHJ P,.TLPRN## ;TYPE LEFT PARENTHESIS
|
||
LDB T1,[POINT 7,T2,35] ;GET 7 BITS OF THE DATA BYTE
|
||
JUMPN T1,XDCRC2 ;IF NOT A NULL GO TYPE IT
|
||
MOVEI T1,[ASCIZ \<NUL>\] ;KLUDGE BECAUSE .TFCHR
|
||
PUSHJ P,.TSTRG## ;CALLS NULLS ALTMODES
|
||
SKIPA ;AND SWISCN NEEDS THAT
|
||
XDCRC2: PUSHJ P,.TFCHR## ;TYPE THE BYTE
|
||
PUSHJ P,.TRPRN## ;FINISH OFF WITH RIGHT PARENTHESIS
|
||
PUSHJ P,.TSPAC## > ;SPACE BETWEEN BYTES IS NEATER
|
||
JRST .POPJ1## ;AND SUCCESSFULLY RETURN
|
||
;XDBYT -- OUTPUT ONE DAP MESSAGE-LEVEL BYTE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<byte>
|
||
; PUSHJ P,XDBYT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; <byte> is the 8-bit DAP
|
||
;message byte to be sent (eventually) to the remote DAP receiver.
|
||
;
|
||
;On error return T1 and T2 are preserved. The error or exception code is in
|
||
;M0. If the error is recoverable (e.g., non-blocking return) then the call
|
||
;to XDBYT may simply be re-executed.
|
||
;
|
||
;On successful return the DAP message byte is safely enscounced away
|
||
;in the output message being built.
|
||
;
|
||
;XDBYT will take care of shipping either continuation messages (i.e.,
|
||
;DAP "MOR" flag set, segmenting a single logical DAP message into multiple
|
||
;physical messages) or large messages sans the length field as needed -
|
||
;the caller does not need to worry about message blocking.
|
||
;
|
||
;Preserves all acs.
|
||
|
||
ENTRY .XDBYT
|
||
INTERN XDBYT0, XDBYT1
|
||
|
||
.XDBYT: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDBYT0:
|
||
XDBYT1: SOSGE .IODOC(IO) ;ROOM FOR ANOTHER MESSAGE BYTE?
|
||
JRST XDBYT2 ;NO, NEED TO MAKE ROOM
|
||
PUSHJ P,XNBYT0 ;YES, OUTPUT ANOTHER NETWORK BYTE
|
||
AOSA .IODOC(IO) ;OOPS - FAILED, ADJUST DAP BYTE COUNT BACK
|
||
AOS (P) ;SUCCESSFUL
|
||
POPJ P, ; RETURN
|
||
;HERE WHEN OUT OF ROOM TO SHIP THE DAP MESSAGE
|
||
|
||
XDBYT2: PUSHJ P,TSAV14## ;WE NEED SOME ACS HERE
|
||
SKIPLE T2,.IODOX(IO) ;BEEN HERE ALREADY?
|
||
JRST XDBYT6 ;YES, SKIP THIS PART THEN
|
||
JUMPL T2,XDBYU0 ;IF FUNNY BUSINESS, TRY TO RESUME
|
||
SKIPG T2,.IODOM(IO) ;NO, GET CURRENT OUTPUT MESSAGE TYPE
|
||
STOPCD <XDBYT called but no DAP message in progress>
|
||
MOVD T3,CNF ;GET CONFIGURATION FLAGS
|
||
CAIN T2,$DHDAT ;IS OVERFLOW DATA OR NON-DATA MESSAGE?
|
||
TFNN T3,DSG ;DATA - CAN REMOTE HANDLE DAP SEGMENTATION?
|
||
JRST XDBYV0 ;NO, DRASTIC MEASURES ARE NEEDED
|
||
|
||
;HERE TO SEGMENT THE OUTPUT DATA MESSAGE INTO MULTIPLE CONTINUED MESSAGES
|
||
|
||
XDBYT4: MOVEM T2,.IODOX(IO) ;SET FLAG IN CASE "INTERRUPTED"
|
||
PUSHJ P,XDMOR0 ;SHIP CURRENT MESSAGE AS A CONTINUED MESSAGE
|
||
POPJ P, ;BLETCH
|
||
MOVE T2,.IODOX(IO) ;RETRIEVE MESSAGE TYPE TO BE CONTINUED
|
||
|
||
;HERE TO START A NEW MESSAGE SEGMENT
|
||
|
||
XDBYT6: PUSHJ P,XDMSG0 ;STARTUP A NEW DAP MESSAGE
|
||
POPJ P, ;BLETCH
|
||
XDBYT8: SKIPG .IODOC(IO) ;MAKE SURE WE HAVE A BUFFER
|
||
STOPCD <XDMSG returned successfully with 0-length buffer in XDBYT>
|
||
SETZM .IODOX(IO) ;CLEAR INTERLOCK
|
||
MOVE T2,-T2(P) ;RESTORE ORIGINAL MESSAGE BYTE
|
||
JRST XDBYT1 ;AND STUFF IT IN THE OUTPUT BUFFER
|
||
;HERE ON "CONTINUATION" FROM SOME SORT OF BUFFER COMPRESSION
|
||
|
||
XDBYU0: PUSHJ P,XNFLS0 ;FLUSH OUT THE NETWORK BUFFER
|
||
POPJ P, ;STILL NO GO
|
||
XDBYU2: MOVE T1,.IODOX(IO) ;GET "STATE" VARIABLE
|
||
AOJE T1,XDBYV2 ;TIME TO "TRY AGAIN"
|
||
AOJE T1,XDBYV6 ;"BLT" THE INCOMPLETE MESSAGE UP
|
||
STOPCD <Confusion reigns in XDBYT at XDBYU2>
|
||
|
||
|
||
|
||
;HERE WHEN EITHER THE DAP MESSAGE LENGTH FIELD OVERFLOWS OR THE
|
||
;NETWORK BUFFER OVERFLOWS (AND THE REMOTE CAN'T HANDLE DATA MESSAGE
|
||
;SEGMENTATION). TRY TO SHIP WHAT WE HAVE AND FINISH THE REST OF THE
|
||
;CURRENT DAP MESSAGE LATER.
|
||
|
||
XDBYV0: SETOM .IODOX(IO) ;FLAG STATE AT FLUSHING AND TRY AGAIN
|
||
DMOVE T3,.IODXA(IO) ;FETCH IONOC/IONOP AT LAST DAP BOM TIME
|
||
CAME T3,.IONLM(IO) ;IS THIS THE ONLY MESSAGE IN THE BUFFER?
|
||
SKIPLE .IONOC(IO) ;OR IS THERE STILL ROOM IN THE BUFFER?
|
||
JRST XDBYW0 ;YES, SEND SANS LENGTH/LEN256/BITCNT FIELDS
|
||
|
||
;DAP MESSAGES ALREADY STASHED IN THE BUFFER, FLUSH THEM OUT
|
||
|
||
CAIN T2,$DHDAT ;WORKING ON A DATA OR OTHERWISE MESSAGE?
|
||
JRST XDBYV4 ;DATA, CAN'T THROW IT AWAY, LOTS OF WORK
|
||
|
||
;HERE ON NON-DATA MESSAGE OVERFLOWING, THROW THE CURRENT ATTEMPT AWAY,
|
||
;SHIP WHAT'S IN THE BUFFER, THEN TRY THE NON-DATA MESSAGE AGAIN
|
||
|
||
PUSHJ P,XDABM0 ;ABORT THE CURRENT NON-DATA MESSAGE
|
||
; NOTE - NEVER "SUCCEEDS"
|
||
PUSHJ P,XDFLS0 ;FLUSH OUT PRECEDING DAP MESSAGES
|
||
POPJ P, ;NET DIED?
|
||
XDBYV2: SETZM .IODOX(IO) ;CLEAR ABORTING STATE
|
||
MOVEI M0,$ECTRA ;THE "TRY AGAIN" EXCEPTION RETURN
|
||
POPJ P, ;TELL XDDAP/ET AL TO TRY AGAIN
|
||
;HERE ON A DATA MESSAGE THAT OVERFLOWED THE NETWORK BUFFER, FLUSH OUT
|
||
;PRECEDING DAP MESSAGES THEN "BLT" THE CURRENT DATA MESSAGE UP TO THE
|
||
;TOP OF THE BUFFER AND CONTINUE ON OUR MERRY WAY.
|
||
|
||
XDBYV4: SOS .IODOX(IO) ;SET STATE TO DATA MESSAGE FLUSHING
|
||
MOVEM T3,.IONOC(IO) ;RESTORE COUNTER AND
|
||
MOVEM T4,.IONOP(IO) ; POINTER TO PRECEDE CURRENT [INCOMPLETE]
|
||
PUSHJ P,XNEOM0 ; MESSAGE AND FLUSH PRECEDING DATA OUT
|
||
POPJ P, ;NET DIED?
|
||
|
||
;MOVE INCOMPLETE DATA MESSAGE TO TOP OF BUFFER AND CONTINUE
|
||
|
||
XDBYV6: DMOVE T2,.IODXA(IO) ;T2:=COUNT OF SAVED MESSAGE BYTES
|
||
;T3:=START OF SAVED MESSAGE BYTES
|
||
MOVE T4,.IONOP(IO) ;T4:=START OF FRESH MESSAGE BUFFER
|
||
PUSHJ P,.BYBLT## ;SHUFFLE OLD MESSAGE TO TOP OF BUFFER
|
||
STOPCD ;CAN'T HAPPEN
|
||
MOVE T3,.IONOC(IO) ;FRESH COUNTER
|
||
EXCH T4,.IONOP(IO) ;FRESH POINTER (UPDATING CURRENT)
|
||
MOVN T1,.IODXA(IO) ;REFETCH SAVED COUNT
|
||
ADDM T1,.IONOC(IO) ;UPDATE BYTES LEFT IN "FRESH" BUFFER
|
||
DMOVEM T3,.IODXA(IO) ;AND SET NEW ABORTION POINTERS
|
||
|
||
;NOW TO RELOCATE ALL THE "SAVED" DAP MESSAGE BYTE POINTERS
|
||
|
||
MOVE T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
ADDM T1,.IODO0(IO) ;RELOCATE SAVED BOD COUNTER
|
||
MOVN T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
ADJBP T1,.IODO1(IO) ;RELOCATE "HEADER" FLAGS BYTE POINTER
|
||
MOVEM T1,.IODO1(IO) ; AND SAVE IT FOR OTHERS
|
||
; MOVN T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
; ADJBP T1,.IODO2(IO) ;RELOCATE "STREAMID" BYTE POINTER
|
||
; MOVEM T1,.IODO2(IO) ; AND SAVE IT FOR OTHERS
|
||
MOVN T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
ADJBP T1,.IODO3(IO) ;RELOCATE "LENGTH" BYTE POINTER
|
||
MOVEM T1,.IODO3(IO) ; AND SAVE IT FOR OTHERS
|
||
MOVN T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
ADJBP T1,.IODO4(IO) ;RELOCATE "LEN256" BYTE POINTER
|
||
MOVEM T1,.IODO4(IO) ; AND SAVE IT FOR OTHERS
|
||
MOVN T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
ADJBP T1,.IODO5(IO) ;RELOCATE "BITCNT" BYTE POINTER
|
||
MOVEM T1,.IODO5(IO) ; AND SAVE IT FOR OTHERS
|
||
MOVN T1,.IONOC(IO) ;DISTANCE THE MESSAGE SHIFTED
|
||
ADJBP T1,.IODO9(IO) ;RELOCATE "BOD" BYTE POINTER
|
||
MOVEM T1,.IODO9(IO) ; AND SAVE IT FOR OTHERS
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;NOW CALCULATE THE NEW DAP BYTE COUNT
|
||
|
||
MOVE T4,.IODOF(IO) ;DAP MESSAGE HEADER FLAGS
|
||
TFNN T4,HLN ;GOT A LENGTH FIELD?
|
||
JRST XDBYW5 ;NO, NO LIMIT
|
||
MOVEI T2,377 ;YES, ASSUME 2**8 BYTE LIMIT
|
||
TFNE T4,HL2 ;GOT A LEN256 FIELD?
|
||
MOVEI T2,177777 ;YES, THEN 2**16 BYTE LIMIT
|
||
SUB T2,.IODO0(IO) ;CALCULATE MAX POSSIBLE ROOM LEFT
|
||
ADD T2,.IONOC(IO) ; BASED ON ALREADY-PRESENT DATA
|
||
CAMLE T2,.IONOC(IO) ;LIMITED BY BUFFER SIZE STILL?
|
||
MOVE T2,.IONOC(IO) ;YES, CHOOSE SMALLER LIMIT
|
||
PJRST XDBYW8 ;FINISH OFF AND OUTPUT THE DAP BYTE
|
||
;SINGLE DAP MESSAGE OVERFLOWS THE NETWORK BUFFER, STRIP OFF THE LENGTH
|
||
;AND UNUSED BITCOUNT FIELDS, AND START SHIPPING NETWORK BUFFERS AS THEY
|
||
;ARE FILLED (ASSUME THE MESSAGE SIZE IS UNLIMITED).
|
||
|
||
XDBYW0: SKIPN .IODO3(IO) ;GOT A LENGTH FIELD?
|
||
JRST XDBYW5 ;NO, NOTHING TO COMPRESS, JUST OUTPUT
|
||
; (ACTUALLY WE MIGHT STILL BE ABLE TO COMPRESS
|
||
; OUT A BITCOUNT FIELD, BUT WHY BOTHER?)
|
||
MOVEI T1,1 ;ONE BYTE FOR THE "LENGTH" FIELD
|
||
SKIPE .IODO4(IO) ;GOT A "LEN256" FIELD?
|
||
ADDI T1,1 ;ONE MORE BYTE
|
||
SKIPE .IODO5(IO) ;GOT A BITCOUNT FIELD?
|
||
ADDI T1,1 ;YEAH, COMPRESS IT OUT TOO ON G.P.S
|
||
MOVE T2,T1 ;COUNT OF BYTES TO SHIFT
|
||
ADDB T1,.IONOC(IO) ;ADJUST NETWORK BYTE COUNTER
|
||
ADDB T2,.IODO0(IO) ;ADJUST SAVED DAP BOD BYTE COUNTER
|
||
SUB T2,T1 ;T2:=AMOUNT OF BYTES TO COMPRESS UP
|
||
MOVNI T3,1 ;ALLOW FOR THE "I" OF .BYBLT'S ILDB LOOP
|
||
ADJBP T3,.IODO9(IO) ;T3:= ILDB POINTER TO PRE-COMPRESSION DATA
|
||
MOVNI T4,1 ;ALLOW FOR THE "I" OF .BYBLT'S IDPB LOOP
|
||
ADJBP T4,.IODO3(IO) ;T4:= IDPB POINTER TO POST-COMPRESSION DATA
|
||
PUSHJ P,.BYBLT## ;COMPRESS OUT THE LENGTH/ETC. FIELDS
|
||
STOPCD ;CAN'T HAPPEN
|
||
MOVEM T4,.IONOP(IO) ;SET COMPRESSED NETWORK BUFFER STUFFER
|
||
|
||
;NOW ADJUST OUR COPIES OF WHAT FIELDS ARE LEFT
|
||
|
||
MOVE T4,.IODOF(IO) ;DAP HEADER FLAGS
|
||
TFZ T4,<HLN,HL2,BCT>;CLEAR NEWLY-NON-EX FIELDS
|
||
MOVEM T4,.IODOF(IO) ;SAVE UPDATED FLAGS
|
||
SETZ T3, ;CLEAR EXTRANEOUS BITS
|
||
LSHC T4,^D07 ;POSITION FIRST BYTE OF FLAGS
|
||
DPB T3,.IODO1(IO) ;SAVE UPDATED FLAGS IN DAP MESSAGE TOO
|
||
|
||
;SETUP FOR "EXTENDED" MESSAGE SIZE
|
||
|
||
XDBYW5: SETZM .IODO3(IO) ;NO "LENGTH" FIELD LEFT
|
||
SETZM .IODO4(IO) ;NO "LEN256" FIELD LEFT
|
||
SETZM .IODO5(IO) ;NO "BITCNT" FIELD LEFT (EVEN IF SHIPPED)
|
||
MOVX T2,ID.SNM ;THE OK-TO-SEGMENT-NETWORK-MESSAGES FLAG
|
||
IORM T2,.IODPF(IO) ;TELL XNBYT WE KNOW WHAT WE'RE DOING
|
||
HRLOI T2,223344 ;AN ARBITRARILY LARGE BYTE COUNT
|
||
XDBYW8: MOVEM T2,.IODOC(IO) ;SET NEW DAP BYTE COUNT
|
||
JRST XDBYT8 ;TRY TO OUTPUT THE BYTE AGAIN
|
||
;XDMSG -- START UP A NEW DAP OUTPUT MESSAGE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<code>
|
||
; PUSHJ P,XDMSG
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and<code> is the DAP
|
||
;message type to be started.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On successful return a new DAP message has been started and calls
|
||
;may be made to XDBYT.
|
||
;
|
||
;Uses acs T1, T2, T3, T4.
|
||
|
||
ENTRY .XDMSG
|
||
INTERN XDMSG0, XDMSG1
|
||
|
||
.XDMSG: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDMSG0: PUSHJ P,.SAVE4## ;NEED A FEW MORE ACS
|
||
XDMSG1: PUSHJ P,TSAV14## ;SAVE THE T'S TOO
|
||
XDMSG2: SKIPLE .IODOM(IO) ;IN MIDDLE OF A DAP MESSAGE ALREADY?
|
||
STOPCD <XDMSG called before current DAP message finished>
|
||
|
||
;START UP A NEW MESSAGE
|
||
|
||
XDMSG4: MOVE T3,.IONOC(IO) ;CURRENT OUTPUT COUNTER
|
||
MOVE T4,.IONOP(IO) ;AND POINTER AT START OF DAP MESSAGE
|
||
DMOVEM T3,.IODXA(IO) ;SAVE FOR XDABM
|
||
HRRZM T2,.IODOM(IO) ;SET NEW CURRENT OUTPUT MESSAGE TYPE
|
||
XMT < PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.TCRLF ;SPACE TO MAKE NEW MESSAGE PROMINENT
|
||
MOVE T1,DAPXTX ;ADDR OF "DAP message type" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT
|
||
MOVEI T1,[ASCIZ / - /];A DASH
|
||
PUSHJ P,.TSTRG## ;TYPE THE DASH
|
||
MOVE T1,.IODOM(IO) ;GET THE DAP MESSAGE TYPE
|
||
MOVEI T2,"0" ;USE ZEROES FOR FILLER
|
||
PUSHJ P,.TDEC2## ;TYPE OUT THE MESSAGE TYPE
|
||
PUSHJ P,.TSPAC## ;A SPACE MAKES MESSAGE PRETTY
|
||
HRRZ T2,.IODOM(IO) ;GET MESSAGE TYPE
|
||
MOVEI T4,DAPIDX ;DAP INDEX TABLE
|
||
PUSHJ P,.CFIND## ;FIND THE INDEX ENTRY FOR THIS MESSAGE TYPE
|
||
STOPCD <XDMSG called with unknown DAP message>
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
MOVE T1,DAPXTX(T1) ;GET TEXT DESCRIBING DAP MESSAGE TYPE
|
||
PUSHJ P,.TSTRG## ;TYPE TEXT DESCRIPTION OF DAP MESSAGE
|
||
PUSHJ P,.TSPAC## ;SPACE
|
||
|
||
;TYPE <<From US to REMOTE>> WHERE US=OUR NODE NAME, REMOTE=REMOTE NODE NAME
|
||
|
||
PUSHJ P,.TLANG## ;<
|
||
PUSHJ P,.TLANG## ;<
|
||
MOVEI T1,[ASCIZ \From \] ;From
|
||
PUSHJ P,.TSTRG##
|
||
MOVE T1,.MYNOD## ;From US
|
||
PUSHJ P,.TSIXN##
|
||
MOVEI T1,[ASCIZ \ to \] ;From US to
|
||
PUSHJ P,.TSTRG##
|
||
MOVE T1,.ION6M(IO) ;From US to REMOTE
|
||
PUSHJ P,.TSIXN##
|
||
PUSHJ P,.TRANG## ;>
|
||
PUSHJ P,.TRANG## ;>
|
||
PUSHJ P,.TCRLF## ;FINISH OFF THE LINE
|
||
|
||
HRRZ T2,.IODOM(IO) ;RESTORE CURRENT OUTPUT MESSAGE TYPE
|
||
> ;END XMT
|
||
PUSHJ P,XNBYT1 ;AND PUT IN THE OUTPUT BUFFER
|
||
STOPCD <XNBYT failed at XDMSG4>
|
||
MOVD T3,CNF ;GENERIC [REMOTE] CONFIGURATION
|
||
MOVDII P1,MHF,<HLN,HL2>;INITIAL DAP MESSAGE HEADER FLAGS
|
||
CAIE T2,$DHCFG ;IF A CONFIGURATION MESSAGE,
|
||
TFNN T3,<BLR,BLU> ;OR IF NOT ALLOWED TO BLOCK MESSAGES,
|
||
TFZ P1,<HLN,HL2> ;THEN DON'T SEND LENGTH FIELDS
|
||
TFNN T3,C25 ;IS "LEN256" FIELD SUPPORTED?
|
||
TFZ P1,HL2 ;NO, THEN DON'T SEND ONE
|
||
CAIE T2,$DHDAT ;DATA MESSAGE?
|
||
JRST XDMSH ;NO, ALL SET
|
||
MOVD T2,DTY ;GET DATA TYPE
|
||
TFNN T2,ASC ;IF ASCII DATA
|
||
TFNN T3,BTC ;OR IF BITCOUNT NOT SUPPORTED BY REMOTE
|
||
JRST XDMSH ;THEN DON'T REQUEST BITCOUNT FIELD
|
||
MOVD1 T2,BSZ ;DAP DATA BYTE SIZE
|
||
TRNE T2,7 ;DATA A MULTIPLE OF 8?
|
||
TFO P1,BCT ;NO, SUPPLY UNUSED BITCOUNT FIELD
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;BUILD REST OF DAP MESSAGE HEADER BASED ON "MENU" IN P1
|
||
|
||
;NOTE THAT THE SAVE DAP MESSAGE HEADER BYTE POINTERS ARE SUBJECT TO
|
||
;DYNAMIC RELOCATION. THEY SHOULD THEREFORE NEVER BE SAVED ON THE STACK
|
||
;OR ANYWHERE ELSE. IF ANY NEW ONES ARE ADDED, BY SURE TO ALSO UPDATE
|
||
;XDBYT TO RELOCATE THEM AS WELL.
|
||
|
||
XDMSH: MOVE T3,P1 ;POSITION WORKING COPY
|
||
MOVEM P1,.IODOF(IO) ;ALSO SAVE FOR OTHERS
|
||
SETZ T2, ;CLEAR EXTRANEOUS BITS
|
||
LSHC T2,^D7 ;POSITION FIRST BYTE OF FLAGS
|
||
CAIE T3,0 ;MORE FOLLOWING?
|
||
STOPCD <Too many DAP message header flags in XDMSH>
|
||
PUSHJ P,XDMSB1 ;OUTPUT FLAGS BYTE
|
||
JRST XDMSK9 ;PROBLEM, CHECK IT OUT
|
||
MOVE T4,.IONOP(IO) ;OUTPUT BYTE POINTER
|
||
MOVEM T4,.IODO1(IO) ;SAVE FOR XDMOR
|
||
|
||
;SEND STREAM ID FIELD
|
||
|
||
TFNN P1,SID ;STREAM ID WANTED?
|
||
JRST XDMSH4 ;NO
|
||
STOPCD <DAP stream ID requested in XDMSH>
|
||
|
||
;SEND LENGTH FIELD
|
||
|
||
XDMSH4: TFNN P1,HLN ;NEED TO SEND A HEADER LENGTH?
|
||
JRST XDMSH5 ;NO
|
||
PUSHJ P,XDMSB0 ;YES, ALLOCATE A BYTE
|
||
JRST XDMSK9 ;PROBLEM, CHECK IT OUT
|
||
SKIPA T2,.IONOP(IO) ;GET BYTE POINTER
|
||
XDMSH5: SETZ T2, ;NO LENGTH FIELD
|
||
MOVEM T2,.IODO3(IO) ;SAVE FOR XDEOM
|
||
|
||
;SEND LEN256 FIELD
|
||
|
||
TFNN P1,HL2 ;NEED TO SEND EXTENDED HEADER LENGTH FIELD?
|
||
JRST XDMSH6 ;NO
|
||
PUSHJ P,XDMSB0 ;YES, ALLOCATE A BYTE
|
||
JRST XDMSK9 ;PROBLEM, CHECK IT OUT
|
||
SKIPA T2,.IONOP(IO) ;GET BYTE POINTER
|
||
XDMSH6: SETZ T2, ;NO LEN256 FIELD
|
||
MOVEM T2,.IODO4(IO) ;SAVE FOR XDEOM
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;SEND TRAILING UNUSED BIT COUNT
|
||
|
||
TFNN P1,BCT ;WANT TRAILING UNUSED BITS?
|
||
JRST XDMSH7 ;NO
|
||
PUSHJ P,XDMSB0 ;YES, ALLOCATE A BYTE
|
||
JRST XDMSK9 ;PROBLEM, CHECK IT OUT
|
||
SKIPA T2,.IONOP(IO) ;GET BYTE POINTER
|
||
XDMSH7: SETZ T2, ;NO BITCNT FIELD
|
||
MOVEM T2,.IODO5(IO) ;SAVE FOR XDEOM
|
||
|
||
;NOW SET DAP BYTE COUNTER
|
||
|
||
MOVE T2,.IONOC(IO) ;INITIALLY, LIMIT AT BUFFER END
|
||
; (XDBYT WILL TAKE CARE OF MESSAGE OVERFLOW
|
||
; FROM A "SHORT" COUNT HERE)
|
||
TFNN P1,HLN ;SENDING HEADER LENGTH FIELD?
|
||
JRST XDMSH9 ;NO
|
||
TFNN P1,HL2 ;YES, LIMITED TO ONE BYTE?
|
||
CAIG T2,377 ;YES, WILL WE FIT?
|
||
CAIA ;ALL SET
|
||
MOVEI T2,377 ;USE SMALLER ONE-BYTE LIMIT
|
||
XDMSH9: MOVEM T2,.IODOC(IO) ;SET DAP OUTPUT BYTE COUNTER
|
||
MOVE T2,.IONOC(IO) ;CURRENT OUTPUT BUFFER BYTE COUNTER
|
||
MOVEM T2,.IODO0(IO) ;SAVE FOR XDEOM
|
||
MOVE T2,.IONOP(IO) ;CURRENT OUTPUT BUFFER BYTE POINTER
|
||
IBP T2 ;POINT TO FIRST DAP MESSAGE BYTE
|
||
MOVEM T2,.IODO9(IO) ;SAVE FOR XDBYT
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
|
||
|
||
;HERE WHEN CAN'T SHIP A MESSAGE HEADER BYTE
|
||
|
||
XDMSK9: CAIE M0,$ECTRA ;XDMSB WANT US TO TRY AGAIN?
|
||
POPJ P, ;NOPE, BAD ERROR
|
||
MOVE T2,-T2(P) ;YES, FETCH ORIGINAL MESSAGE TYPE
|
||
JRST XDMSG4 ;AND TRY AGAIN
|
||
|
||
|
||
|
||
;HERE TO SHIP ONE MESSAGE HEADER BYTE
|
||
|
||
XDMSB0: SETZ T2, ;A NICE NULL FILLER BYTE
|
||
XDMSB1: SKIPLE .IONOC(IO) ;ROOM LEFT IN THE NETWORK BUFFER?
|
||
PJRST XNBYT0 ;YES, ALL SET
|
||
PUSHJ P,XDABM2 ;NO, ABORT CURRENT EMBYRIONIC MESSAGE
|
||
; NOTE -NEVER SUCCEEDS
|
||
PUSHJ P,XDFLS1 ;FLUSH OUT PRECEDING DAP DATA
|
||
POPJ P, ;OOPS
|
||
MOVEI M0,$ECTRA ;TRY TRY AGAIN
|
||
POPJ P, ;EXCEPTION RETURN
|
||
;XDABM -- ABORT THE CURRENT OUTPUT DAP MESSAGE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XDABM
|
||
; error return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;Note that this routine always take the error return, preserving caller's M0!
|
||
;
|
||
;Uses acs T1, T2.
|
||
|
||
ENTRY .XDABM
|
||
INTERN XDABM0, XDABM1
|
||
|
||
.XDABM: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDABM0:
|
||
XDABM1: SKIPG T1,.IODOM(IO) ;GET MESSAGE TYPE
|
||
POPJ P, ;NOTHING TO ABORT, PROPAGATE THE ERROR
|
||
CAIN T1,$DHDAT ;DATA MESSAGE?
|
||
STOPCD <Can't abort data message in XDABM>
|
||
MOVE T1,.IODPF(IO) ;GET DAP LOGIC CONTROL FLAGS
|
||
TXNE T1,ID.SNM ;HAVE WE ALREADY COMMITTED TO THIS MESSAGE?
|
||
STOPCD <Can't abort already-partially-transmitted DAP message in XDABM>
|
||
XDABM2: DMOVE T1,.IODXA(IO) ;SAVED MESSAGE ABORTION POINTER
|
||
JUMPE T1,XDABM5 ;SKIP IF NO SAVED POINTER
|
||
MOVEM T1,.IONOC(IO) ;RESET NETWORK BYTE COUNTER AND
|
||
MOVEM T2,.IONOP(IO) ;POINTER TO EAT CURRENT MESSAGE
|
||
XDABM5: SETZM .IODOM(IO) ;NO MESSAGE BEING BUILT NOW
|
||
SETOM .IODOC(IO) ;JUST TO MAKE SURE
|
||
SETZM .IODOB(IO) ;CLEAR TRAILING UNUSED BIT COUNT
|
||
POPJ P, ;PROPAGATE ERROR RETURN
|
||
;XDMOR -- SEND A MESSAGE SEGMENT (MESSAGE WITH "MOR" FLAG)
|
||
;XDEOM -- SEND DAP MESSAGE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XDEOM/XDMOR
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On normal return the current DAP output message has been closed off.
|
||
;If needed (can't piggyback messages or data message) the output message
|
||
;will be shipped to the remote.
|
||
;
|
||
;Uses T1, T2, T3, T4
|
||
|
||
ENTRY .XDMOR
|
||
INTERN XDMOR0, XDMOR1
|
||
|
||
.XDMOR: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDMOR0:
|
||
XDMOR1: SKIPG .IODOM(IO) ;IN MIDDLE OF MESSAGE PROCESSING?
|
||
STOPCD <XDMOR but no DAP message in progress>
|
||
MOVD T3,CNF ;GET REMOTE'S CONFIGURATION
|
||
TFNN T3,DSG ;DAP SEGMENTATION SUPPORTED?
|
||
STOPCD <XDMOR called but remote doesn't support segmentation>
|
||
MOVE T2,.IODOF(IO) ;GET DAP HEADER FLAGS
|
||
TFO T2,MOR ;FLAG MORE TO COME AFTER THIS SEGMENT
|
||
SETZ T1, ;CLEAR EXTRANEOUS BITS
|
||
LSHC T1,^D07 ;POSITION FIRST BYTE OF FLAGS
|
||
DPB T1,.IODO1(IO) ;SET IN MESSAGE HEADER FLAGS
|
||
JRST XDEOM0 ;GO SEND THE MESSAGE [SEGMENT]
|
||
ENTRY .XDEOM
|
||
INTERN XDEOM0, XDEOM1
|
||
|
||
.XDEOM: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDEOM0:
|
||
XDEOM1: SKIPG .IODOM(IO) ;IN MIDDLE OF MESSAGE PROCESSING?
|
||
STOPCD <XDEOM but no DAP message in progress>
|
||
XMT < PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
MOVE T1,.IODOM(IO) ;GET THE MESSAGE TYPE JUST ENDED
|
||
CAIN T1,$DHDAT ;WAS IT A DATA MESSAGE ?
|
||
PUSHJ P,.TCRLF## ;YES, FINISH LINE OF DATA NEATLY
|
||
PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TLBRK## ;TYPE LEFT BRACKET
|
||
MOVE T1,DAPXTX+1 ;ADDR OF "Message header flags" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT
|
||
PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
LDB T2,.IODO1(IO) ;GET MESSAGE HEADER FLAGS IN T2
|
||
PUSHJ P,.THEXB ;TYPE-OUT FLAG BYTE FROM T2
|
||
PUSHJ P,.TRBRK## ;TYPE RIGHT BRACKET
|
||
PUSHJ P,.TCRLF## ;FINISH WITH <CR><LF>
|
||
MOVEI P1,1 ;SO .TFLAG GETS HEADER FLAG MESSAGES
|
||
MOVE P2,.IODOF(IO) ;GET MESSAGE HEADER FLAGS IN P2
|
||
CLEAR P3, ;ONLY ONE WORD OF FLAGS
|
||
PUSHJ P,.TFLAG > ;TYPE CORRESP. DAP MESSAGES
|
||
SKIPN T2,.IODO3(IO) ;SENDING LENGTH FIELD?
|
||
JRST XDEOM3 ;NO
|
||
MOVE T1,.IODO0(IO) ;YES, GET SAVED BYTE COUNT
|
||
SUB T1,.IONOC(IO) ;T1:=SIZE OF DAP "OPERAND"
|
||
DPB T1,T2 ;SET LOW ORDER LENGTH
|
||
XMT < PUSH P,T1 ;SAVE T1
|
||
PUSH P,T2 ;SAVE T2
|
||
PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TLBRK## ;TYPE LEFT BRACKET
|
||
MOVE T1,DAPXTX+3 ;ADDR OF "MSG data length (LSB)" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
LDB T2,T2 ;GET LSB IN T2
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TRBRK## ;TYPE RIGHT BRACKET
|
||
PUSHJ P,.TCRLF## ;FINISH WITH <CR><LF>
|
||
POP P,T2 ;RESTORE T2
|
||
POP P,T1 > ;RESTORE T1
|
||
LSH T1,-^D8 ;POSITION HIGH ORDER LENGTH
|
||
SKIPE T2,.IODO4(IO) ;HIGH ORDER FIELD PRESENT?
|
||
JRST XDEOM2 ;YES
|
||
JUMPE T1,XDEOM3 ;NO, OK UNLESS SIZE .GT. ^O377
|
||
STOPCD <DAP length greater than ^D255 but no LEN256 field in XDEOM>
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
XDEOM2: DPB T1,T2 ;SET HIGH ORDER LENGTH FIELD
|
||
XMT < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TLBRK## ;TYPE LEFT BRACKET
|
||
MOVE T1,DAPXTX+4 ;ADDR OF "MSG data length (MSB)" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
LDB T2,T2 ;GET MSB
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TRBRK## ;TYPE RIGHT BRACKET
|
||
PUSHJ P,.TCRLF## > ;FINISH WITH <CR><LF>
|
||
XDEOM3: SETZ T1, ;RESET COUNT TO 0
|
||
EXCH T1,.IODOB(IO) ;UNUSED BIT COUNT FIELD
|
||
SKIPE T2,.IODO5(IO) ;WANT UNUSED BITS?
|
||
JRST XDEOM4 ;YES
|
||
JUMPE T1,XDEOM7 ;NO, OK UNLESS THERE ARE UNUSED BITS
|
||
MOVE T2,.IODOM(IO) ;NO UNUSED BITCNT POINTER
|
||
CAIE T2,$DHDAT ;ENDING A DATA MESSAGE?
|
||
JRST XDEOM7 ;NO, THEN IT DOESN'T REALLY MATTER
|
||
STOPCD <DAP data bits unused but no BITCNT field in XDEOM>
|
||
|
||
XDEOM4: DPB T1,T2 ;YES
|
||
XMT < PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TLBRK## ;TYPE LEFT BRACKET
|
||
MOVE T1,DAPXTX+5 ;ADDR OF "Trailing bit count" TEXT
|
||
PUSHJ P,.TSTRG## ;TYPE THAT TEXT
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
LDB T2,T2 ;GET TRAILING BIT COUNT
|
||
PUSHJ P,.THEXB ;TYPE THE HEX BYTE FROM T2
|
||
PUSHJ P,.TRBRK## ;TYPE RIGHT BRACKET
|
||
PUSHJ P,.TCRLF## > ;FINISH WITH <CR><LF>
|
||
XDEOM7: SETOM .IODOC(IO) ;NO MORE DAP BYTES UNTIL XDMSG
|
||
SETZM .IODOM(IO) ;NOT IN MESSAGE ANYMORE
|
||
SETZM .IODXA(IO) ;JUST TO MAKE SURE
|
||
SKIPE .IODO3(IO) ;IS LENGTH FIELD MISSING?
|
||
SKIPG .IONOC(IO) ;OR NETWORK BUFFER EMPTY?
|
||
PJRST XNEOM1 ;YES, THEN FORCE THIS BUFFER OUT NOW
|
||
;*** MOVD1 T1,FST ;*** GET REMOTE FILE SYSTEM TYPE
|
||
;*** CAIN T1,$DVFF1 ;*** IS THIS FCS-11 (RSX-11)?
|
||
;*** PJRST XNEOM1 ;*** YES, NEVER BLOCK MESSAGES TOGETHER
|
||
;*** ;*** FCS-11 FAL HAS SOME OBSCURE BUG THAT
|
||
;*** ;*** DOESN'T ALWAYS LIKE BLOCKED MESSAGES
|
||
;*** ;*** EVEN THOUGH IT SOMETIMES WORKS . . .
|
||
JRST .POPJ1## ;TRY TO PIGGYBACK FOLLOWING DAP MESSAGES
|
||
;XDFLS -- FLUSH OUT ANY PENDING DAP OUTPUT
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XDFLS
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return either the network died or an input message has been
|
||
;received and awaits processing.
|
||
;
|
||
;On normal return all pending DAP output messages have been given to
|
||
;the monitor to be sent to the remote receiver.
|
||
;
|
||
;Uses T1.
|
||
|
||
ENTRY .XDFLS
|
||
INTERN XDFLS0, XDFLS1
|
||
|
||
.XDFLS: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XDFLS0:
|
||
XDFLS1: SKIPLE .IODOM(IO) ;IN MESSAGE PROCESSING?
|
||
STOPCD <XDFLS called with DAP output message is progress>
|
||
SETOM .IODOC(IO) ;MAKE SURE XDBYT NOT CONFUSED
|
||
XDFLS3: SKIPLE T1,.IONOC(IO) ;GET OUTPUT BUFFER SPACE LEFT
|
||
CAME T1,.IONLM(IO) ;[MAXIMUM-MESSAGE-SIZE] BUFFER EMPTY?
|
||
PJRST XNEOM0 ;NO, SEND IT OUT
|
||
JRST .POPJ1## ;YES, ALL DONE
|
||
SUBTTL DAP Protocol Tables
|
||
|
||
;*** SOME RANDOM DEFINITIONS FOR EASE OF DEBUGGING
|
||
|
||
.CREF .IDRCN ;DATA MESSAGE RECORD NUMBER
|
||
.CREF .IDSTC ;STATUS MESSAGE STATUS CODE
|
||
.CREF .IDSRA ;STATUS MESSAGE RECORD ADDRESS
|
||
.CREF .IDSRN ;STATUS MESSAGE RECORD NUMBER
|
||
.CREF .IDSTV ;STATUS MESSAGE SECODARY STATUS
|
||
SUBTTL Miscellaneous routines used for DAP message trace
|
||
|
||
;VARLEN -- TYPE LENGTH PORTION OF A VARIABLE LENGTH DAP FIELD
|
||
;Call is:
|
||
;
|
||
; MOVX T3,<LEN>
|
||
; PUSHJ P,VARLEN
|
||
; always return here
|
||
;
|
||
;Where <LEN> is the length of the variable length field.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
VARLEN: PUSHJ P,TSAV13 ;SAVE T1 - T3
|
||
MOVE T2,T3 ;GET FIELD LENGTH IN T2 FOR .THEXB
|
||
PUSHJ P,.THEXB ;TELL THE LENGTH IN HEX
|
||
MOVEI T1,[ASCIZ \ (\] ;TYPE A LEFT PARENTHESIS
|
||
PUSHJ P,.TSTRG## ; . . .
|
||
MOVE T1,T3 ;GET THE LENGTH IN T1
|
||
PUSHJ P,.TDECW## ;TYPE THE DECIMAL LENGTH (SMASHES T1-T3)
|
||
PUSHJ P,.TDOT## ;TYPE A DECIMAL POINT
|
||
PUSHJ P,.TRPRN## ;TYPE A RIGHT PARENTHESIS
|
||
PUSHJ P,.TRBRK## ;TYPE A RIGHT BRACKET
|
||
POPJ P, ;RETURN
|
||
>
|
||
|
||
;FIXLEN -- TYPE LENGTH PORTION OF A FIXED LENGTH DAP FIELD
|
||
;Call is:
|
||
;
|
||
; MOVX P1,<IDX>
|
||
; PUSHJ P,FIXLEN
|
||
; always return here
|
||
;
|
||
;Where <IDX> is the current RDDAP (for rcv) or XDDAP (for xmt) execution index.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
FIXLEN: PUSHJ P,TSAV13 ;SAVE T1 - T3
|
||
LDB T1,[POINTR DAPXCT(P1),DX$LNB] ;GET THE LENGTH IN T1
|
||
PUSHJ P,.TDECW## ;TYPE THE DECIMAL LENGTH (SMASHES T1-T3)
|
||
PUSHJ P,.TDOT## ;TYPE A DECIMAL POINT
|
||
PUSHJ P,.TRBRK## ;TYPE A RIGHT BRACKET
|
||
POPJ P, ;RETURN
|
||
>
|
||
;EXTENS -- TYPE AN EXTENSIBLE BYTE AS HEX FOLLOWED BY THE EXTENSIBLE
|
||
; FLAG BIT AND THE 7-BIT OCTAL BYTE
|
||
;Call is:
|
||
;
|
||
; MOVX T2,<BYT>
|
||
; PUSHJ P,EXTENS
|
||
; always return here
|
||
;
|
||
;Where <BYT> is the extensible byte.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
EXTENS: PUSHJ P,TSAV13 ;SAVE T1 - T3
|
||
PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
PUSHJ P,.THEXB ;TYPE-OUT BYTE FROM T2
|
||
PUSHJ P,.TLPRN## ;TYPE LEFT PARENTHESIS
|
||
MOVEI T1,"0" ;ASSUME NOT AN EXTENSIBLE BYTE
|
||
TRNE T2,200 ;AN EXTENSIBLE BYTE ?
|
||
MOVEI T1,"1" ;YES, THEN WE SHALL TYPE THE EXTENSIBLE FLAG
|
||
PUSHJ P,.TCHAR## ;INDICATE IF EXTENSIBLE OR NOT
|
||
PUSHJ P,.TSPAC## ;SPACE AFTER EXTENSIBILITY FLAG
|
||
LDB T1,[POINT 7,T2,35] ;GET 7 BITS OF THE EXTENSIBLE BYTE
|
||
PUSHJ P,.TOCTW## ;TYPE THE OCTAL VALUE (SMASHES T1-T3)
|
||
PUSHJ P,.TRPRN## ;FINISH OFF WITH RIGHT PARENTHESIS
|
||
POPJ P, ;RETURN
|
||
>
|
||
|
||
;ASCSTR -- TYPE ASCIZ STRING FROM .IODAP FIELD IN I/O CDB
|
||
;Call is:
|
||
;
|
||
; MOVX P1,<IDX>
|
||
; PUSHJ P,ASCSTR
|
||
; always return here
|
||
;
|
||
;Where <IDX> is the current RDDAP (for rcv) or XDDAP (for xmt) execution index.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
ASCSTR: PUSHJ P,TSAV11 ;SAVE T1
|
||
MOVEI T1,[ASCIZ \ (\] ;TYPE A LEFT PARENTHESIS
|
||
PUSHJ P,.TSTRG## ; . . .
|
||
LDB T1,[POINTR DAPXCT(P1),DX$IOX] ;FIELD STORAGE IN .IODAP
|
||
ADDI T1,.IODAP(IO) ; . . .
|
||
PUSHJ P,.TSTRG## ;TYPE THE STRING
|
||
PUSHJ P,.TRPRN## ;TYPE A RIGHT PARENTHESIS
|
||
POPJ P, ;RETURN
|
||
>
|
||
;BINFLD -- TYPE OCTAL AND DECIMAL REPRESENTATIONS OF BINARY DAP FIELD
|
||
; AND CALL .TVALU TO GIVE TEXTUAL DESCRIPTION IF FIELD HAS ONE
|
||
;Call is:
|
||
;
|
||
; MOVX T3,<MSW>
|
||
; MOVX T4,<LSW>
|
||
; MOVX P1,<IDX>
|
||
; PUSHJ P,BINFLD
|
||
; always return here
|
||
;
|
||
;Where <MSW> is the most significant word of the binary number.
|
||
; <LSW> is the least significant word of the binary number.
|
||
; <IDX> is the current RDDAP (for rcv) or XDDAP (for xmt) execution index.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
BINFLD: PUSHJ P,.SAVE4 ;SAVE P1 - P4
|
||
PUSHJ P,TSAV13 ;SAVE T1 - T3
|
||
DMOVEM T3,P3 ;SAVE BINARY NO. FROM T3 & T4 IN P3 & P4
|
||
MOVEI T1,[ASCIZ \ (\] ;TYPE A LEFT PARENTHESIS
|
||
PUSHJ P,.TSTRG## ; . . .
|
||
DMOVE T1,P3 ;GET THE BINARY FIELD IN T1 & T2
|
||
PUSHJ P,.TOCTD## ;TYPE FIELD AS SIGNED OCTAL DOUBLE-WORD NUMBER
|
||
MOVEI T1,"=" ;TYPE AN EQUALS SIGN
|
||
PUSHJ P,.TCHAR## ; . . .
|
||
DMOVE T1,P3 ;GET THE BINARY FIELD IN T1 & T2
|
||
PUSHJ P,.TDECD## ;TYPE FIELD AS SIGNED DECIMAL DOUBLE-WORD NUMBER
|
||
PUSHJ P,.TDOT## ;TYPE A DECIMAL POINT
|
||
PUSHJ P,.TRPRN## ;TYPE A RIGHT PARENTHESIS
|
||
DMOVE T3,P3 ;RESTORE THE BINARY NO. INTO T3 & T4
|
||
MOVE T1,DAPXCT(P1) ;GET EXECUTION TABLE ENTRY FOR THIS FIELD
|
||
TXNN T1,DX$VAR ;VARIABLE LENGTH FIELD?
|
||
PUSHJ P,.TVALU ;NO, TYPE MESSAGE DESCRIBING FIELD VALUE
|
||
POPJ P, ;RETURN
|
||
>
|
||
;FLGFLD -- EXTRACT FLAG BITS FROM .IODAP FIELD IN I/O CDB
|
||
; AND CALL .TFLAG TO TYPE FLAG DESCRIPTIONS.
|
||
;Call is:
|
||
;
|
||
; MOVX P1,<IDX>
|
||
; PUSHJ P,FLGFLD
|
||
; always return here
|
||
;
|
||
;Where <IDX> is the current RDDAP (for rcv) or XDDAP (for xmt) execution index.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
FLGFLD: PUSHJ P,.SAVE3## ;SAVE P1 - P3
|
||
PUSHJ P,TSAV13## ;SAVE T1 - T3
|
||
LDB T3,[POINTR DAPXCT(P1),DX$LNB] ;FIELD LENGTH (DAP BYTES)
|
||
LDB T1,[POINTR DAPXCT(P1),DX$IOX] ;FIELD STORAGE IN .IODAP
|
||
ADDI T1,.IODAP(IO) ; . . .
|
||
MOVE P2,(T1) ;GET 1ST FLAGS WORD
|
||
CLEAR P3, ;ASSUME NO 2ND FLAGS WORD
|
||
CAILE T3,^D5 ;DO THEY FIT IN ONE WORD ?
|
||
MOVE P3,1(T1) ;NO, THEN GET 2ND FLAGS WORD
|
||
PUSHJ P,.TFLAG ;TYPE CORRESP. DAP MESSAGES
|
||
POPJ P, ;RETURN
|
||
>
|
||
;TRCRCV -- TRACE A RECEIVED DAP DATA MESSAGE
|
||
;
|
||
;Call is:
|
||
;
|
||
; PUSHJ P,TRCRCV or PUSHJ P,TRCRC0
|
||
; always return here always return here
|
||
;
|
||
;This routine has two entry points: TRCRCV and TRCRC0
|
||
;
|
||
;The call to TRCRCV is made from RDDAT to trace a DAP data message received.
|
||
;If the data message is incomplete when the NSP data buffer is emptied, the
|
||
;rest of the data message is traced by a call to TRCRC0 from RNBYT after
|
||
;RNBUF has filled the NSP data buffer with the rest of the message.
|
||
;
|
||
;Unfortunately, when simultaneously tracing messages received and transmitted,
|
||
;for example COPY REMOTE::FOO.BAR=REMOTE::FRED.BAR, the call to TRCRC0 may
|
||
;come after a trace of data transmitted. Thus the trace of the remainder of
|
||
;received data is appended to the trace of transmitted data. This is a minor
|
||
;inconvenience because <RCV> and <XMT> text is prepended to received and
|
||
;transmitted message trace making it easy to recognise when this situation has
|
||
;occurred and still possible to see where data belongs in the trace.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
|
||
RCV <
|
||
|
||
TRCRCV: PUSHJ P,TSAV14## ;SAVE T1 - T4
|
||
PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
PUSHJ P,.TTABC## ;TAB ACROSS BEFORE TYPING DATA BYTES
|
||
MOVE T3,.IODIC(IO) ;GET COUNT OF DAP DATA BYTES IN MESSAGE
|
||
CAMLE T3,.IONIC(IO) ;FEWER DAP MESSAGE BYTES THAN BYTES IN BUFFER ?
|
||
MOVE T3,.IONIC(IO) ;NO, THEN TRACE OUT BYTES LEFT IN BUFFER
|
||
AOJ T3, ;FIX BECAUSE RDBYT HAS READ AHEAD
|
||
SETO T4, ;GET POINTER TO FIRST BYTE
|
||
ADJBP T4,.IONIP(IO) ;AND FIX BECAUSE RDBYT HAS READ AHEAD
|
||
JRST TRCRC3
|
||
|
||
TRCRC0: PUSHJ P,TSAV14## ;SAVE T1 - T4
|
||
PUSHJ P,TRCFIL ;DIRECT TRACE, IF ANY, AS DETERMINED BY .JBOPC
|
||
PUSHJ P,.XTYPO## ; . . .
|
||
MOVE T3,.IODIC(IO) ;GET COUNT OF DATA BYTES IN BUFFER
|
||
AOJ T3, ;FIX BECAUSE RDBYT HAS READ AHEAD
|
||
CAMLE T3,.IONIC(IO) ;FEWER DAP MESSAGE BYTES THAN BYTES IN BUFFER ?
|
||
MOVE T3,.IONIC(IO) ;NO, THEN TRACE OUT BYTES LEFT IN BUFFER
|
||
MOVE T4,.IONIP(IO) ;GET POINTER TO FIRST BYTE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
TRCRC3: MOVEI T1,[ASCIZ \<RCV> \] ;ENSURE USER KNOWS THIS IS RECEIVED DATA
|
||
PUSHJ P,.TSTRG##
|
||
TRCRC4: SOSGE T3 ;ANY BYTES LEFT ?
|
||
POPJ P, ;NO, RETURN
|
||
ILDB T2,T4 ;YES, PUT THE BYTE IN T2
|
||
PUSHJ P,.THEXB ;TYPE-OUT BYTE FROM T2
|
||
PUSHJ P,.TLPRN## ;TYPE LEFT PARENTHESIS
|
||
LDB T1,[POINT 7,T2,35] ;GET 7 BITS OF THE DATA BYTE
|
||
JUMPN T1,TRCRC5 ;IF NOT A NULL GO TYPE IT
|
||
MOVEI T1,[ASCIZ \<NUL>\] ;KLUDGE BECAUSE .TFCHR
|
||
PUSHJ P,.TSTRG## ;CALLS NULLS ALTMODES
|
||
SKIPA ;AND SWISCN NEEDS THAT
|
||
TRCRC5: PUSHJ P,.TFCHR## ;TYPE THE BYTE
|
||
PUSHJ P,.TRPRN## ;FINISH OFF WITH RIGHT PARENTHESIS
|
||
PUSHJ P,.TSPAC## ;SPACE BETWEEN BYTES IS NEATER
|
||
JRST TRCRC4 ;LOOP FOR MORE DATA BYTES
|
||
|
||
> ;END RCV
|
||
SUBTTL DAP Protocol Tables - Execution table index table
|
||
|
||
;THE DAP EXECUTION TABLE INDEX
|
||
|
||
DAPIDX::DODAP(IDX)
|
||
SUBTTL DAP Protocol Tables - Execution table
|
||
|
||
;AND THE DAP EXECUTION TABLE
|
||
|
||
DAPXCT::DODAP(XCT)
|
||
SUBTTL DAP Protocol Tables - Field-text table
|
||
|
||
;THE DAP MESSAGE/FIELD TEXT DESCRIPTION TABLE
|
||
|
||
DAPXTX::DODAP(XTX)
|
||
SUBTTL DAP Protocol Tables - Status-code text table
|
||
|
||
;THE DAP STATUS CODE TEXT DESCRIPTION TABLE
|
||
|
||
DAPSTS::DODAP(STS)
|
||
SUBTTL DAP Protocol Tables - CRC polynomial table
|
||
|
||
;THE DAP CRC POLYNOMIAL TABLE
|
||
|
||
DAPCRC::BLDCRC (164405) ;X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X^1 + 1
|
||
SUBTTL Expand tables used to trace DAP messages
|
||
|
||
$TRACE < DFVMSG: FVMSG > ;THE ACTUAL MESSAGES
|
||
$TRACE < DFVIDX: FVIDX > ;POINTERS TO MESSAGES PARALLEL TO DAPXCT
|
||
SUBTTL Network Link Control - Link initialization
|
||
|
||
;NTNIA -- INITIALIZE ACTIVE NETWORK CHANNEL
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<NOD>
|
||
; PUSHJ P,NTNIA
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and <NOD> is the SIXBIT
|
||
;node name with whom communications are desired.
|
||
;
|
||
;The caller is responsible for setting up all other network parameters
|
||
;such as object type and name, optional user data, etc.
|
||
;
|
||
;On error return, a connection could not be established, an error code
|
||
;is in M0.
|
||
;
|
||
;On normal return, a network channel has been assigned (and is returned
|
||
;in .IONCH) and the "Connect Initiate" message has been posted to the
|
||
;specified node.
|
||
;
|
||
;Note that NTNIA only requests a network logical link, it does not in any
|
||
;way ensure that the specified node will accept the request - a call to
|
||
;NTNCW must be executed to "block" waiting for completion of the request.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNIA
|
||
INTERN NTNIA0, NTNIA1
|
||
|
||
.NTNIA: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNIA0: PUSHJ P,.SAVE4## ;PRESERVE A FEW ACS
|
||
NTNIA1: SKIPE .IONCH(IO) ;MAKE SURE CDB NOT ALREADY ACTIVE
|
||
STOPCD <NTNIA called with outstanding network channel>
|
||
|
||
;SELECT THE DESTINATION NETWORK NODE
|
||
|
||
MOVE T3,T2 ;POSITION NODE SPECIFIER
|
||
PUSHJ P,.NDNAM## ;TRY TO MAKE SENSE OF IT
|
||
MOVEM T1,.ION6M(IO) ;SET NODE NAME (SIXBIT) FOR INTEREST
|
||
JUMPL T2,NDNIA1 ;IF NOT KNOWN ANF, THEN ASSUME DECNET
|
||
; JRST NANIA1 ;USE ANF NETWORK
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;HERE FOR ANF ENTER ACTIVE
|
||
|
||
NANIA1: MOVEM T2,.I1NSC+0(IO) ;SET TSK. NODE NUMBER IN DESTINATION NPD
|
||
SKIPN .IONDF(IO) ;WE REQUIRE A DESTINATION NPD FROM CALLER
|
||
STOPCD <No destination NPD in NANIA1>
|
||
|
||
;SETUP AND BUILD THE TSK.-STYLE CONNECT INFO
|
||
|
||
PUSHJ P,NAS1I1 ;INITIALIZE FOR STRING BUILDING
|
||
STOPCD <NAS1I1 failed in NANIA1>
|
||
PUSHJ P,.XTYPO## ;SELECT BYTE TYPER
|
||
MOVEI P2,"0" ;DEFAULT IS RANDOM TASK
|
||
PUSHJ P,NAS2I1 ;ENCODE THE SOURCE AND DESTINATION NPD
|
||
STOPCD <NAS2I1 failed in NANIA1>
|
||
MOVEI P2,0 ;NO DEFAULT FOR USER ID STUFF
|
||
PUSHJ P,NAS3I1 ;ENCODE USER ID/PASSWORD/AD NAUSEUM
|
||
STOPCD <NAS3I1 failed in NANAI1>
|
||
SKIPL T1,.IONP3(IO) ;DID IT ALL FIT?
|
||
STOPCD <Strings too big in NANIA1>
|
||
HRRZM T1,.I1NSC+1(IO) ;SET TSK. NPD BYTE COUNT
|
||
|
||
;NOW ASSIGN A TASK CHANNEL AND REQUEST A NETWORK CONNECT INIT
|
||
|
||
NANIA5: MOVX M0,IO.NET!IO.ANF;FLAG ANF-STYLE NETWORK CHANNEL
|
||
IORM M0,.IOCCF(IO) ;UPDATE CHANNEL CONTROL
|
||
PUSHJ P,NAS4I1 ;ASSIGN A TSK: CHANNEL, ETC
|
||
POPJ P, ;ERROR
|
||
MOVX P1,.TKFEA ;FUNCTION: ENTER ACTIVE
|
||
MOVE T1,[4,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;SEND A CONNECT INIT
|
||
JRST NACIE1 ;PROCESS TSK. CONNECT ERROR
|
||
JRST .POPJ1## ;CONNECT INIT POSTED
|
||
;HERE FOR DECNET-STYLE ENTER ACTIVE
|
||
|
||
NDNIA1: MOVE T2,T1 ;POSITION SIXBIT NAME IN T2
|
||
MOVE P3,[6,,.IONNM] ;8-BIT NAME POINTER
|
||
PUSHJ P,N6TO8 ;CONVERT 6-BIT TO 8-BIT NAME
|
||
STOPCD <Node name N6TO8 failed in NTNIA>
|
||
HRLI P3,$NTNBL ;SET MAXIMUM "NAME BLOCK LENGTH"
|
||
MOVSM P3,.IONNM(IO) ;SET BYTE,,WORD COUNTS FOR NODE NAME BLOCK
|
||
|
||
;COMMON CODE TO INITIALIZE FOR NSP.
|
||
|
||
PUSHJ P,NDS1I1 ;SETUP NSP. ARGUMENTS
|
||
STOPCD <NDS1I1 failed in NDNAI1>
|
||
|
||
;"QUEUE" THE REQUEST WITH NETWORK SERVICES VIA THE MONITOR
|
||
|
||
MOVX M0,IO.NET!IO.DCN;FLAG ACTIVE DECNET CHANNEL
|
||
IORM M0,.IOCCF(IO) ;SET IN THE CDB
|
||
XMOVEI P3,.I1NSC(IO) ;NSP. CONNECT BLOCK ADDRESS
|
||
SETZ P2, ;NO CHANNEL YET
|
||
MOVE P1,[.NSFEA,,.NSAA1+1] ;"ENTER ACTIVE" FUNCTION
|
||
TXO P1,NS.WAI ;*** IT STILL DOESN'T WORK!!!!!!!!!!
|
||
XMOVEI M0,P1 ;NSP. ARG BLOCK TO
|
||
NSP. M0, ;ASK FOR AN ACTIVE NETWORK CHANNEL
|
||
JRST NDCIE1 ;PROCESS NSP. CONNECT ERROR
|
||
HRRZM P2,.IONCH(IO) ;SUCCESS, SAVE NETWORK CHANNEL
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;NTNIP -- INITIALIZE PASSIVE NETWORK CHANNEL
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<NOD>
|
||
; PUSHJ P,NTNIP
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and <NOD> is the SIXBIT
|
||
;node name with whom communications are desired (or 0 (or "*") if any
|
||
;node is acceptable).
|
||
;
|
||
;The caller is responsible for setting such information as the source
|
||
;and/or destination process descriptors, and so forth.
|
||
;
|
||
;On error return, a network channel could not be established (e.g., not
|
||
;enough monitor resources, etc.), an error code in in M0.
|
||
;
|
||
;On normal return, a network channel has been assigned (and is returned
|
||
;in .IONCH) and is awaiting a "Connect Initiate" message.
|
||
;
|
||
;Note that NTNIP only requests a network logical link, it does not in any
|
||
;way ensure that anyone has connected to the logical link - a call to
|
||
;.NTNCW will "block" waiting for a connection.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNIP
|
||
INTERN NTNIP0, NTNIP1
|
||
|
||
.NTNIP: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNIP0: PUSHJ P,.SAVE4## ;PRESERVE A FEW ACS
|
||
NTNIP1: SKIPE .IONCH(IO) ;MAKE SURE CDB NOT ALREADY ACTIVE
|
||
STOPCD <NTNIP called with outstanding network channel>
|
||
MOVEM T2,.ION6M(IO) ;SET NODE NAME (SIXBIT) FOR INTEREST
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL FLAGS
|
||
TXNE T1,IO.ANF ;ANF-STYLE NETWORK?
|
||
JRST NANIP1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET-STYLE NETWORK?
|
||
JRST NDNIP1 ;YES
|
||
STOPCD <Neither ANF nor DECnet selected in NTNIP>
|
||
;HERE FOR ANF ENTER PASSIVE
|
||
|
||
NANIP1: CAME T2,['* '] ;EXPLICITLY WILD NODE?
|
||
CAIN T2,0 ;IMPLICITLY WILD NODE?
|
||
SETO T2, ;TSK.-STYLE WILD NODE!
|
||
MOVEM T2,.I1NSC+0(IO) ;SET NODE SPECIFIER IN TSK. ARG BLOCK
|
||
SKIPN .IONDF(IO) ;"DESTINATION" NPD IS REQUIRED
|
||
STOPCD <No destination NPD in NDNIP1>
|
||
|
||
;NOW SETUP TSK.-STYLE ARGUMENTS
|
||
|
||
PUSHJ P,NAS1I1 ;INITIALIZE FOR STRING WIZARDRY
|
||
STOPCD <NAS1I1 failed in NANIP1>
|
||
PUSHJ P,.XTYPO## ;SELECT BYTE TYPER
|
||
MOVEI P2,"*" ;DEFAULT HERE IS FULLY WILD
|
||
PUSHJ P,NAS2I1 ;SETUP SOURCE/DESTINATION NPDS
|
||
STOPCD <NAS2I1 failed in NANIP1>
|
||
MOVEI P2,"*" ;ACCEPT ANYTHING BY DEFAULT HERE TOO
|
||
PUSHJ P,NAS3I1 ;SETUP USER ID/ET AL
|
||
STOPCD <NAS3I1 failed in NANIP1>
|
||
SKIPL T1,.IONP3(IO) ;DID IT ALL FIT?
|
||
STOPCD <Strings too big in NANIP1>
|
||
HRRZM T1,.I1NSC+1(IO) ;SET TSK.-STYLE NPD BYTE COUNT
|
||
|
||
;NOW GET A TASK CHANNEL
|
||
|
||
MOVX M0,IO.NET!IO.ANF!IO.NEP;FLAG PASSIVE ANF-STYLE NETWORK CHANNEL
|
||
IORM M0,.IOCCF(IO) ;UPDATE CHANNEL CONTROL
|
||
PUSHJ P,NAS4I1 ;ASSIGN TSK: CHANNEL
|
||
POPJ P, ;ERROR
|
||
MOVX P1,.TKFEP ;FUNCTION: ENTER PASSIVE
|
||
MOVE T1,[4,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;ENTER PASSIVE CONNECT WAIT
|
||
JRST NACIE1 ;PROCESS TSK. CONNECT ERROR
|
||
|
||
;ALL DONE HERE
|
||
|
||
JRST .POPJ1## ;RETURN AWAITING A CONNECTION
|
||
;HERE FOR DECNET-STYLE ENTER PASSIVE
|
||
|
||
NDNIP1: MOVE P3,[6,,.IONNM] ;8-BIT POINTER
|
||
PUSHJ P,N6TO8 ;CONVERT TO 8-BIT NODE NAME
|
||
STOPCD <Node name N6TO8 failed in NTNIP>
|
||
HRLI P3,$NTNBL ;SELECT MAXIMUM NAME BLOCK LENGTH
|
||
MOVSM P3,.IONNM(IO) ;SET BYTE,,WORD COUNTER IN NAME BLOCK
|
||
|
||
;COMMON CODE TO SETUP THE NSP. ARGUMENTS
|
||
|
||
PUSHJ P,NDS1I1 ;INITIALIZE THE NSP. ARG BLOCK
|
||
STOPCD <NDS1I1 failed in NDNIP1>
|
||
|
||
;"QUEUE" THE REQUEST WITH NETWORK SERVICES VIA THE MONITOR
|
||
|
||
MOVX M0,IO.NET!IO.DCN;THE "NETWORK-BASED COMMUNICATIONS" BIT
|
||
IORM M0,.IOCCF(IO) ;SET IN THE CDB
|
||
XMOVEI P3,.I1NSC(IO) ;NSP. CONNECT BLOCK ADDRESS
|
||
SETZ P2, ;NO CHANNEL YET
|
||
MOVE P1,[NS.WAI!<.NSFEP,,.NSAA1+1>] ;"ENTER PASSIVE" FUNCTION
|
||
TXNN T3,IO.NBT ;WANT THIS NON-BLOCKING?
|
||
SKIPE .IOSCH(IO) ;OR IS THERE AN I/O SCHEDULER LURKING ABOUT?
|
||
TXZ P1,NS.WAI ;YES TO ONE OF THE ABOVE, NON-BLOCKING
|
||
XMOVEI M0,P1 ;NSP. ARG BLOCK TO
|
||
NSP. M0, ;ASK FOR A PASSIVE NETWORK CHANNEL
|
||
JRST NDCIE1 ;PROCESS NSP CONNECT ERROR
|
||
HRRZM P2,.IONCH(IO) ;SUCCESS, SAVE NETWORK CHANNEL
|
||
MOVX P1,IO.NET!IO.NEP;"PASSIVE NETWORK COMMUNICATIONS" BITS
|
||
IORM P1,.IOCCF(IO) ;ADJUST THE CDB ACCORDINGLY
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;RANDOM SUBROUTINES FOR ENTER ACTIVE/PASSIVE
|
||
|
||
;As ANF-10 basically doesn't support any of the "wonderous" errata of
|
||
;DECnet such as user-id, password, ad nauseum, the TSK. monitor call
|
||
;was invented to give the user fuller control over the network logical
|
||
;link. In particular, in conjunction with versions 3 and later of the
|
||
;DECnet Compatible Port (in the DN8x), the "network process descriptor"
|
||
;was made available to the "user" in order to encode all that stuff in
|
||
;such a way that the DCP can convert it into something the DECnet side
|
||
;understood. The result is a very arcane NPD string (for which honesty
|
||
;requires that I not claim any credit) given to the TSK. in the active
|
||
;and passive init functions. The form of that NPD string, for the first
|
||
;time anywhere ever put in writing, is:
|
||
;
|
||
; <0> ;leading null byte
|
||
; DST ;"destination" process identifier
|
||
; <0> ;punctuation byte
|
||
; SRC ;"source" process identifier
|
||
; <0> ;punctuation byte
|
||
; USERID ;user id string
|
||
; <0> ;punctuation byte
|
||
; PASSWORD ;password string for user id
|
||
; <0> ;punctuation byte
|
||
; ACCOUNT ;account string for user id
|
||
; <0> ;punctuation byte
|
||
; OPTDATA ;"optional user data" a la DECnet connect init
|
||
; <0> ;punctuation byte
|
||
;
|
||
;DST and SRC both are one of the following forms:
|
||
;
|
||
; OBJ ;format 0: DECnet object type
|
||
; OBJ.NAM ;format 1: DECnet object type and task name
|
||
; ; note the "." punctuation character
|
||
; OBJ.[P,PN]NAM ;format 2: DECnet object type, user ppn and name
|
||
; ; note the ".", "[" and "]" punctuation
|
||
;
|
||
;OBJ is the object type as an ASCII octal number - e.g., "21" for DAP.
|
||
;NAM, USERID, PASSWORD, ACCOUNT, and OPTDATA are all "ASCII" character
|
||
;strings - i.e., 7-bit bytes (with no nulls).
|
||
;NAS1I1 - INITIALIZE FOR STRING MAGIC
|
||
|
||
NAS1I1: MOVE P3,[XWD <<.NSCUD+.NSDPN+.NSDPN>*5>,.I1NSC+2]
|
||
PUSHJ P,NP3P4 ;SET BYTE COUNTER AND POINTER
|
||
STOPCD <NP3P4 failed in NAS1I1>
|
||
MOVSI T1,(POINT 7,(IO)) ;TSK. USES 7-BIT BYTES
|
||
HLLM T1,.IONP4(IO) ;SO OVERRIDE .IONP4
|
||
XMOVEI T1,NTYPO ;BYTE TYPER
|
||
JRST .POPJ1## ;RETURN
|
||
|
||
|
||
|
||
;NAS2I1 - ENCODE SOURCE AND DESTINATION "NPD"S
|
||
|
||
NAS2I1: XMOVEI P1,.IONDF(IO) ;ADDRESS DESTINATION NPD FIELDS
|
||
PUSHJ P,NAS1N0 ;ENCODE ONE "NPD"
|
||
STOPCD <NAS1N0 failed in NAS2I1>
|
||
XMOVEI P1,.IONSF(IO) ;ADDRESS SOURCE NPD FIELDS
|
||
PUSHJ P,NAS1N0 ;ENCODE ONE MORE "NPD"
|
||
STOPCD <NAS1N0 failed in NAS2I1>
|
||
JRST .POPJ1## ;SUCCESSFUL SO FAR
|
||
|
||
|
||
|
||
;NAS3I1 - ENCODE USER ID, PASSWORD, ACCOUNT STRING, OPTIONAL DATA
|
||
|
||
NAS3I1: XMOVEI P1,.IONUS(IO) ;ADDRESS OF USER ID STRING BLOCK
|
||
PUSHJ P,NAS8S0 ;ENCODE USER ID STRING
|
||
STOPCD <NAS8S0 - user id - failed in NAS3I1>
|
||
XMOVEI P1,.IONPW(IO) ;ADDRESS OF PASSWORD STRING BLOCK
|
||
PUSHJ P,NAS8S0 ;ENCODE PASSWORD STRING
|
||
STOPCD <NAS8S0 - password - failed in NAS3I1>
|
||
XMOVEI P1,.IONAC(IO) ;ADDRESS OF ACCOUNT STRING BLOCK
|
||
PUSHJ P,NAS8S0 ;ENCODE ACCOUNT STRING
|
||
STOPCD <NAS8S0 - account - failed in NAS3I1>
|
||
XMOVEI P1,.IONUD(IO) ;ADDRESS OF OPTIONAL DATA STRING BLOCK
|
||
PUSHJ P,NAS8S0 ;ENCODE OPTIONAL DATA
|
||
STOPCD <NAS8S0 - optional data - failed in NAS3I1>
|
||
PJRST NAS0B0 ;CAP OFF WITH A NULL
|
||
;NAS4I1 - GET TASK CHANNEL, SETUP FOR TSK.
|
||
|
||
;Note that ANF TSK: channels must be run UU.AIO (non-blocking) so that
|
||
;a "dummy" IN can be performed in order to kick the monitor into sending
|
||
;data requests to the "other" guy. If the dummy IN is not performed, then
|
||
;both sides end up "deadlocked" trying to send the initial DAP CONFIG
|
||
;message, with neither side having sent any data requests!
|
||
|
||
NAS4I1: MOVX P1,FO.ASC!.FOCRE;ASSIGN CHANNEL, CREATE CHANNEL
|
||
MOVX P2,UU.PHY!UU.AIO!UU.IBC!.IOBYT ;DEVIOS WORD
|
||
MOVSI P3,'TSK' ;DEVICE NAME IS TSK:
|
||
MOVSI P4,.IONOH(IO) ;OUTPUT RING HEADER ADDRESS
|
||
HRRI P4,.IONIH(IO) ;INPUT RING HEADER ADDRESS
|
||
MOVE T1,[4,,P1] ;FILOP. ARG POINTER TO
|
||
FILOP. T1, ;ASSIGN A TSK CHANNEL
|
||
JRST NAS4I9 ;FILOP. ERROR
|
||
LDB P2,[POINTR P1,FO.CHN] ;EXTRACT CHANNEL NUMBER RETURNED
|
||
MOVEM P2,.IONCH(IO) ;SAVE FOR POSTERITY
|
||
SETOM .I1NSP+0(IO) ;DUMMY SOURCE NPD NODE NUMBER
|
||
SETZM .I1NSP+1(IO) ;DUMMY SOURCE NPD PROCESS ID STRING
|
||
MOVEI P3,.I1NSP(IO) ;ADDRESS OF "SOURCE" NPD FOR TSK.
|
||
HRLI P3,3 ;LENGTH OF SAME
|
||
MOVEI P4,.I1NSC(IO) ;ADDRESS OF "DESTINATION" NPD FOR TSK.
|
||
HRLI P4,<.NSCUD+1+.NSDPN+1+.NSDPN+1> ;LENGTH OF SAME
|
||
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
;HERE WHEN FILOP. OPEN TSK: FAILS
|
||
|
||
NAS4I9: LDB P2,[POINTR P1,FO.CHN] ;EXTRACT CHANNEL NUMBER, IF ANY
|
||
CAIE P2,0 ;DID MONITOR ASSIGN US A CHANNEL?
|
||
RESDV. P2, ;YES (PROBABLY), STOMP IT
|
||
JFCL ;HO HUM
|
||
SETZ M0, ;NO ERROR CODE SELECTED YET
|
||
MOVE T2,T1 ;POSITION ERROR CODE
|
||
XMOVEI T4,NAS4IT ;AND ERROR CODE TRANSLATION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO MAP FILOP. ERROR
|
||
MOVEI T1,$EFTNA ;FALLBACK "TASK DEVICE NOT AVAILABLE"
|
||
MOVE M0,T1 ;POSITION ERROR CODE IN ERROR AC
|
||
POPJ P, ;ERROR RETURN
|
||
|
||
;FILOP. OPEN ERRORS
|
||
|
||
NAS4IT: $EFISU,,ERISU% ;ILLEGAL SEQUENCE OF UUOS
|
||
$EFILU,,ERILU% ;ILLEGAL FILOP. CALL
|
||
$EFNLI,,ERNLI% ;ILLEGAL NOT LOGGED IN
|
||
$EFENC,,ERENC% ;EXCEEDED NETWORK CAPACITY
|
||
$EFTNA,,ERTNA% ;TASK DEVICE NOT AVAILABLE
|
||
$EFNSN,,ERUNN% ;NO SUCH NODE NAME
|
||
$EFNPC,,ERNPC% ;NO PER-PROCESS SPACE AVAILABLE
|
||
$EFNFC,,ERNFC% ;NO FREE I/O CHANNELS
|
||
0 ;THAT ABOUT DOES IT
|
||
;NAS1N0 - ENCODE ONE "NPD"
|
||
|
||
NAS1N0: PUSHJ P,NAS0B0 ;START OFF WITH A NULL
|
||
JFCL ;CAN'T HAPPEN
|
||
NAS1N1: HRRZ T1,0(P1) ;OBJECT TYPE
|
||
JUMPE T1,[SKIPE T1,P2 ;NONE, SELECT DEFAULT
|
||
PUSHJ P,.TCHAR## ;OUTPUT DEFAULT, IF ANY
|
||
JRST .POPJ1##] ;THAT'S ALL FOR THIS NPD
|
||
XMOVEI T2,.TOCTW## ;OBJECT TYPE IS OUTPUT IS OCTAL
|
||
CAIN T1,-1 ;UNLESS -1,
|
||
XMOVEI T2,.TASTR## ;IN WHICH CASE OUTPUT IS "*"
|
||
PUSHJ P,0(T2) ;DO WHATEVER'S APPROPRIATE
|
||
HLRZ T1,0(P1) ;FORMAT TYPE
|
||
JUMPE T1,.POPJ1## ;0 = OBJECT TYPE ONLY
|
||
SOJE T1,NASIN3 ;1 = OBJECT TYPE AND NAME
|
||
SOJE T1,NASIN5 ;2 = OBJECT TYPE, PPN, AND NAME
|
||
STOPCD <Illegal format type in NASIN1>
|
||
|
||
|
||
;HERE FOR FORMAT 1 - OBJ.NAM
|
||
|
||
NASIN3: PUSHJ P,.TDOT## ;SEPARATE OBJECT TYPE AND NAME
|
||
ADDI P1,.IONSN-.IONSF;RELOCATE P1 TO NAME STRING BLOCK ADDRESS
|
||
JRST NAS8S1 ;COPY NAME STRING
|
||
|
||
|
||
;HERE FOR FORMAT 2 - OBJ.[P,PN]NAM
|
||
|
||
NASIN5: PUSHJ P,.TDOT## ;SEPARATE OBJECT TYPE AND PPN/NAME
|
||
ADDI P1,.IONSP-.IONSF;RELOCATE P1 TO PPN
|
||
MOVE T1,0(P1) ;FETCH USER PPN
|
||
PUSHJ P,.TPPNW## ;AND TYPE IT OUT AS "[P,PN]"
|
||
ADDI P1,.IONSN-.IONSP;RELOCATE P1 TO NAME STRING BLOCK ADDRESS
|
||
JRST NAS8S1 ;COPY NAME STRING
|
||
;NAS8S0 - COPY 8-BIT STRING BLOCK
|
||
|
||
NAS8S0: PUSHJ P,NAS0B0 ;START OFF WITH A NULL
|
||
JFCL ;CAN'T HAPPEN
|
||
NAS8S1: HLRZ T4,0(P1) ;GET ACTUAL BYTE COUNT
|
||
JUMPE T4,[SKIPE T1,P2 ;NONE, SELECT DEFAULT NAME
|
||
PUSHJ P,.TCHAR## ;ISSUE DEFAULT NAME
|
||
JRST .POPJ1##] ;AND THAT'S THAT
|
||
MOVE T3,[POINT 8,1(P1)] ;BYTE POINTER TO 8-BIT NAME STRING
|
||
NAS8S4: ILDB T1,T3 ;GET NEXT NAME CHARACTER
|
||
CAIE T1,0 ;COMPRESS OUT NULLS
|
||
PUSHJ P,.TCHAR## ;ISSUE ONE MORE CHARACTER
|
||
SOJG T4,NAS8S4 ;LOOP FOR WHOLE NAME
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
|
||
|
||
|
||
;NAS0B0 - OUTPUT NULL BYTE
|
||
|
||
NAS0B0: SETZ T1, ;A NULL BYTE
|
||
NAS0B1: PUSHJ P,NTYPO ;ISSUE ONE CHARACTER
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN ALWAYS
|
||
;NDS1I1 - SETUP FOR DECNET NSP. ENTER ACTIVE OR PASSIVE
|
||
|
||
;SETUP THE SOURCE PROCESS DESCRIPTOR BLOCK
|
||
|
||
NDS1I1: MOVEI P1,.NSDPN+1 ;LENGTH OF PROCESS DESCRIPTOR BLOCK
|
||
MOVEM P1,.I1NSS+.NSDFL(IO) ;SET IN PROCESS BLOCK
|
||
MOVE P1,.IONSF(IO) ;SOURCE FORMAT,,OBJECT TYPE
|
||
HLREM P1,.I1NSS+.NSDFM(IO) ;SET FORMAT TYPE IN PROCESS BLOCK
|
||
HRREM P1,.I1NSS+.NSDOB(IO) ;SET OBJECT TYPE IN PROCESS BLOCK
|
||
MOVE P1,.IONSP(IO) ;SOURCE "PPN"
|
||
MOVEM P1,.I1NSS+.NSDPP(IO) ;SET IN PROCESS BLOCK
|
||
XMOVEI P1,.IONSN(IO) ;SOURCE NAME BLOCK ADDRESS
|
||
MOVEM P1,.I1NSS+.NSDPN(IO) ;SET IN SOURCE PROCESS BLOCK
|
||
MOVEI M0,$NTNBL ;LENGTH OF A NAME BLOCK
|
||
HRRM M0,@P1 ;SET WORD COUNT OF SOURCE TASK NAME
|
||
|
||
;SETUP THE DESTINATION PROCESS DESCRIPTOR BLOCK
|
||
|
||
NDS1I3: MOVEI P1,.NSDPN+1 ;LENGTH OF PROCESS DESCRIPTOR BLOCK
|
||
MOVEM P1,.I1NSD+.NSDFL(IO) ;SET IN PROCESS BLOCK
|
||
MOVE P1,.IONDF(IO) ;DESTINATION FORMAT,,OBJECT TYPE
|
||
HLREM P1,.I1NSD+.NSDFM(IO) ;SET FORMAT TYPE IN PROCESS BLOCK
|
||
HRREM P1,.I1NSD+.NSDOB(IO) ;SET OBJECT TYPE IN PROCESS BLOCK
|
||
MOVE P1,.IONDP(IO) ;DESTINATION "PPN"
|
||
MOVEM P1,.I1NSD+.NSDPP(IO) ;SET IN PROCESS BLOCK
|
||
XMOVEI P1,.IONDN(IO) ;DESTINATION NAME BLOCK ADDRESS
|
||
MOVEM P1,.I1NSD+.NSDPN(IO) ;SET IN DESTINATION PROCESS BLOCK
|
||
MOVEI M0,$NTNBL ;LENGTH OF A NAME BLOCK
|
||
HRRM M0,@P1 ;SET WORD COUNT OF DESTINATION TASK NAME
|
||
|
||
;SETUP NSP. CONNECT BLOCK POINTERS
|
||
|
||
NDS1I5: MOVEI P1,.NSCUD+1 ;LENGTH OF CONNECT BLOCK
|
||
MOVEM P1,.I1NSC+.NSCNL(IO) ;SET CONNECT BLOCK LENGTH (WORDS)
|
||
XMOVEI P1,.IONNM(IO) ;NODE NAME ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCND(IO) ;SET IN CONNECT BLOCK
|
||
XMOVEI P1,.I1NSS(IO) ;SOURCE PROCESS BLOCK ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCSD(IO) ;SET IN CONNECT BLOCK
|
||
XMOVEI P1,.I1NSD(IO) ;DESTINATION PROCESS BLOCK ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCDD(IO) ;SET IN CONNECT BLOCK
|
||
MOVEI M0,$NTSBL ;MAXIMUM "STRING BLOCK ADDRESS"
|
||
XMOVEI P1,.IONUS(IO) ;USER ID ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCUS(IO) ;SET IN CONNECT BLOCK
|
||
HRRM M0,@P1 ;SET STRING BLOCK WORD COUNT
|
||
XMOVEI P1,.IONPW(IO) ;USER PASSWORD ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCPW(IO) ;SET IN CONNECT BLOCK
|
||
HRRM M0,@P1 ;SET STRING BLOCK WORD COUNT
|
||
XMOVEI P1,.IONAC(IO) ;USER ACCOUNT DATA ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCAC(IO) ;SET IN CONNECT BLOCK
|
||
HRRM M0,@P1 ;SET STRING BLOCK WORD COUNT
|
||
XMOVEI P1,.IONUD(IO) ;USER DATA ADDRESS
|
||
MOVEM P1,.I1NSC+.NSCUD(IO) ;SET IN CONNECT BLOCK
|
||
HRRM M0,@P1 ;SET STRING BLOCK WORD COUNT
|
||
|
||
JRST .POPJ1## ;RETURN HAPPILY
|
||
;NTNCW -- WAIT FOR CONNECT CONFIRM/CONNECT INITIATE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,NTNCW
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;On error return the network died (channel aborted), error code is returned
|
||
;in M0.
|
||
;
|
||
;On normal return, an active channel has successfully connected to a
|
||
;remote network process, or a passive channel has received a "Connect
|
||
;Initiate" request and must either accept or reject it.
|
||
;
|
||
;The connect block is filled in accordingly.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNCW
|
||
INTERN NTNCW0, NTNCW1
|
||
|
||
.NTNCW: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNCW0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
NTNCW1: SKIPN P2,.IONCH(IO) ;NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNCW>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANCW1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNCW1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNCW>
|
||
;HERE FOR ANF CONNECT WAIT
|
||
|
||
NANCW1: MOVX P1,.TKFWT ;FUNCTION: WAIT FOR CONNECT EVENT
|
||
MOVE T1,[2,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;WAIT FOR A CONNECT EVENT
|
||
JRST NACIE1 ;PROCESS TSK. CONNECT ERROR
|
||
|
||
;LINK IS UP AND ACTIVE, READ IN TSKSER'S NPD
|
||
|
||
NANCW3: MOVEI P4,.I1NSC(IO) ;ADDRESS OF OUR TSK. NPD BLOCK
|
||
HRLI P4,<.NSCUD+1+.NSDPN+1+.NSDPN+1> ;LENGTH OF SAME
|
||
SETZ P3, ;NO SOURCE WANTED
|
||
MOVX P1,.TKFRS ;FUNCTION: READ STATUS
|
||
MOVE T1,[4,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;READ IN STATUS AND NPD STRING
|
||
JRST NACIE1 ;PROCESS TSK. CONNECT ERROR
|
||
CAIN P3,.TKSOK ;IS THE LINK ESTABLISHED AND "RUNNING"
|
||
JRST NANCW5 ;YES
|
||
PUSHJ P,NTZAP0 ;*** NO, GET RID OF IT
|
||
JFCL ;*** HO HUM
|
||
MOVEI M0,$EFURO ;*** ASSUME "NO FILE SERVICE" FOR NOW
|
||
POPJ P, ;*** NO LINK
|
||
|
||
;SET NODE NAME FOR INTERESTED PARTIES
|
||
|
||
NANCW5: MOVE T3,.I1NSC(IO) ;RETURNED NODE NAME (OCTAL)
|
||
PUSHJ P,.NDNAM## ;TRY TO MAKE A PRINTABLE NAME OUT OF IT
|
||
MOVEM T1,.ION6M(IO) ;SAVE IN CASE ANYONE IS INTERESTED
|
||
|
||
;ALL DONE IF AN "ACTIVE" LINK, GRUNDGE IF A PASSIVE ONE
|
||
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL FLAGS
|
||
TXNN T1,IO.NEP ;ACTIVE OR PASSIVE?
|
||
JRST .POPJ1## ;ACTIVE (DCP RETURNS USELESS NPD)
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;PASSIVE LINK, DECODE THE NPD "CONNECT" INFORMATION
|
||
|
||
NANCW7: MOVE P3,.I1NSC+1(IO) ;RETURNED NPD BYTE COUNT
|
||
MOVE P4,[POINT 7,.I1NSC+2(IO)] ;POINTER TO RETURNED NPD STRING
|
||
PUSHJ P,NAS0R0 ;READ IN FIRST BYTE
|
||
CAIE T1,0 ;MUST BE A NULL
|
||
STOPCD <Junk returned NPD in NANCW5>
|
||
XMOVEI P1,.IONDF(IO) ;ADDRESS OF "DESTINATION" NPD STUFF
|
||
PUSHJ P,NAS3R0 ;DECODE DESTINATION INFO
|
||
STOPCD <NAS3R0 (dest) failed in NANCW5>
|
||
XMOVEI P1,.IONSF(IO) ;ADDRESS OF "SOURCE" NPD STUFF
|
||
PUSHJ P,NAS3R0 ;DECODE SOURCE INFO
|
||
STOPCD <NAS3R0 (source) failed in NANCW5>
|
||
XMOVEI P1,.IONUS(IO) ;ADDRESS OF USER ID STRING BLOCK
|
||
PUSHJ P,NAS2R0 ;DECODE USER ID
|
||
STOPCD <NAS2R0 (userid) failed in NANCW5>
|
||
XMOVEI P1,.IONPW(IO) ;ADDRESS OF PASSWORD STRING BLOCK
|
||
PUSHJ P,NAS2R0 ;DECODE PASSWORD
|
||
STOPCD <NAS2R0 (password) failed in NANCW5>
|
||
XMOVEI P1,.IONAC(IO) ;ADDRESS OF ACCOUNT STRING BLOCK
|
||
PUSHJ P,NAS2R0 ;DECODE ACCOUNT STRING
|
||
STOPCD <NAS2R0 (account) failed in NANCW5>
|
||
XMOVEI P1,.IONUD(IO) ;ADDRESS OF USER DATA STRING BLOCK
|
||
PUSHJ P,NAS2R0 ;DECODE USER DATA
|
||
STOPCD <NAS2R0 (usrdata) failed in NANCW5>
|
||
|
||
;ALL CONNECT INFO RETURNED
|
||
|
||
JRST .POPJ1## ;RETURN SUCCESSFULLY
|
||
;HERE FOR DECNET CONNECT WAIT
|
||
|
||
NDNCW1: TXNE T1,IO.NEP ;NETWORK PASSIVE CHANNEL?
|
||
JRST NDNCW3 ;YES
|
||
|
||
;HERE TO WAIT FOR ACTIVE LINK TO BE READY
|
||
|
||
XMOVEI P3,.IONUD(IO) ;OPTIONAL CONNECT CONFIRM DATA BLOCK ADDRESS
|
||
MOVEI M0,$NTSBL ;MAXIMUM "STRING BLOCK LENGTH"
|
||
HRRM M0,@P3 ;SET DATA BLOCK MAXIMUM WORD COUNT
|
||
MOVE P1,[NS.WAI!<.NSFRC,,.NSAA1+1>] ;READ CONNECT INFO
|
||
XMOVEI M0,P1 ;ADDRESS OF NSP. ARG BLOCK TO
|
||
NSP. M0, ;READ CONNECT CONFIRM DATA, WAIT IF NEEDED
|
||
JRST NDCXE1 ;FAILED
|
||
LDB P2,[POINTR P2,NS.STA] ;GET CURRENT LINK STATE
|
||
CAIN P2,.NSSRN ;LINK STATE READY?
|
||
JRST .POPJ1## ;YES, LINK IS UP AND RUNNING, ALL SET THEN
|
||
MOVEI M0,NSRBO% ;ASSUME CONNECT REJECTED
|
||
CAIN P1,.NSSDR ;"DISCONNECT RECEIVED"?
|
||
JRST NDCXE1 ;PROCESS "NSP. ERROR"
|
||
STOPCD <Funny state in active NDNCW>
|
||
|
||
|
||
|
||
;HERE TO WAIT FOR PASSIVE LINK TO BE READY
|
||
;
|
||
;ASSUMES CONNECT BLOCK IS CORRECTLY SETUP BY NTNIP
|
||
|
||
NDNCW3: XMOVEI P3,.I1NSC(IO) ;CONNECT BLOCK ADDRESS
|
||
MOVE P1,[NS.WAI!<.NSFRI,,.NSAA1+1>] ;READ CONNECT INIT ARGUMENT
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;READ CONNECT INIT DATA
|
||
JRST NDCXE1 ;FAILED
|
||
PUSHJ P,TSAV12## ;SAVE T2
|
||
MOVEI P4,.IONNM ;8-BIT NODE NAME OFFSET
|
||
PUSHJ P,N8TO6 ;MAKE A 6-BIT NAME OUT OF IT
|
||
JFCL ;DUH?
|
||
MOVEM T2,.ION6M(IO) ;SET 6-BIT NAME FOR INTERESTED PARTIES
|
||
JRST .POPJ1## ;RETURN WITH PASSIVE CONNECTION READY
|
||
;ANF SUBROUTINES FOR NANCW
|
||
|
||
;NAS0R0 - READ NEXT NPD BYTE
|
||
|
||
NAS0R0: SOSGE P3 ;ANY MORE DATA?
|
||
TDZA T1,T1 ;NO, RETURN A NULL
|
||
ILDB T1,P4 ;YES, RETURN NEXT NPD BYTE
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
|
||
;NAS0R3 - READ OCTAL NPD SUBSTRING
|
||
|
||
NAS0R3: SETZ T2, ;INITIALIZE OCTAL VALUE
|
||
NAS0R4: PUSHJ P,NAS0R0 ;READ NEXT BYTE
|
||
CAIL T1,"0" ;IS IT OCTAL?
|
||
CAILE T1,"7" ; . . .
|
||
POPJ P, ;NO, END OF SUBSTRING
|
||
LSH T1,^D33 ;YES, POSITION AND
|
||
ROTC T1,^D03 ;ACCUMULATE OCTAL OBJECT TYPE
|
||
JRST NAS0R4 ;READ IN REST OF OBJECT TYPE
|
||
|
||
|
||
|
||
;NAS2R0 - READ STRING
|
||
|
||
NAS2R0: SETZ T3, ;INITIALIZE ACTUAL BYTE COUNTER
|
||
MOVE T4,[POINT 8,1(P1)] ;AND BYTE POINTER
|
||
NAS2R1: PUSHJ P,NAS0R0 ;READ NEXT BYTE
|
||
JUMPE T1,NAS2R3 ;NULL TERMINATES STRING
|
||
IDPB T1,T4 ;ACCUMULATE STRING
|
||
AOJA T3,NAS2R1 ;AND COUNT IT UP
|
||
|
||
NAS2R3: HRLM T3,0(P1) ;STORE ACTUAL BYTE COUNT
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;NAS3R0 - READ ENCODED NPD STRING
|
||
|
||
NAS3R0: PUSHJ P,NAS0R3 ;READ IN OCTAL SUBSTRING
|
||
HRRZM T2,0(P1) ;ASSUME FORMAT = 0; OBJECT TYPE RETURNED
|
||
JUMPE T1,.POPJ1## ;IF FORMAT 0 THEN ALL DONE
|
||
CAIE T1,"." ;ELSE MUST HAVE PUNCTUATION HERE
|
||
STOPCD <Junk encoded NPD string in NAS3R3>
|
||
MOVE T2,P4 ;PRESERVE COPY OF BYTE POINTER
|
||
PUSHJ P,NAS0R0 ;READ FIRST "NAME" STRING CHARACTER
|
||
CAIN T1,"[" ;LOOK LIKE A PPN?
|
||
JRST NAS3R5 ;YUP, MUST BE FORMAT 2
|
||
|
||
;FORMAT 1, SIMPLE NAME
|
||
|
||
NAS3R3: MOVEI T1,1 ;TASK NAME COMING UP, FORMAT TYPE 1
|
||
HRLM T1,0(P1) ;SET NEW FORMAT TYPE
|
||
ADDI P1,.IONDN-.IONDF;SET P1 TO TASK NAME STRING BLOCK
|
||
MOVE P4,T2 ;RESTORE BYTE POINTER TO FIRST NAME CHAR
|
||
AOJA P3,NAS2R0 ;AND READ NAME STRING
|
||
|
||
;FORMAT 2 - PPN AND NAME
|
||
|
||
NAS3R5: ADDI P1,.IONDP-.IONDF;RELOCATE P1 TO PPN WORD
|
||
PUSHJ P,NAS0R3 ;READ IN OCTAL SUBSTRING (PROJECT)
|
||
CAIE T2,0 ;MUST NOT BE BLANK
|
||
CAIE T1,"," ;AND MUST BE PROPERLY PUNCTUATED
|
||
STOPCD <Junk encoded project NPD string in NAS3R5>
|
||
HRLM T2,0(P1) ;STORE PROJECT NUMBER
|
||
PUSHJ P,NAS0R3 ;READ IN ANOTHER OCTAL SUBSTRING (PROGRAMMER)
|
||
CAIE T2,0 ;MUST NOT BE BLANK
|
||
CAIE T1,"]" ;AND MUST BE PROPERLY PUNCTUATED
|
||
STOPCD <Junk encoded programmer NPD string in NAS3R5>
|
||
HRRM T2,0(P1) ;STORE PROGRAMMER NUMBER
|
||
ADDI P1,.IONDN-.IONDP;RELOCATE P1 TO NAME STRING BLOCK
|
||
JRST NAS2R0 ;AND READ REMAINING NPD NAME STRING
|
||
;NTNCA -- PASSIVE CHANNEL CONNECT ACCEPT
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T3,<DAT>
|
||
; PUSHJ P,NTNCA
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and <DAT> is the address
|
||
;of any optional connect data to be sent as part of the connect accept
|
||
;(must be 0 if no optional data).
|
||
;
|
||
;On error return the network aborted.
|
||
;
|
||
;On successful return the network channel is "up and running". Normal
|
||
;communications may take place.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNCA
|
||
INTERN NTNCA0, NTNCA1
|
||
|
||
.NTNCA: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNCA0: PUSHJ P,.SAVE4## ;SAVE SOME ACS
|
||
NTNCA1: SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNCA>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANCA1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNCA1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNCA>
|
||
;HERE FOR ANF CONNECT ACCEPT
|
||
|
||
NANCA1: JRST .POPJ1## ;CONFIRM FAIT ACCOMPLI
|
||
|
||
|
||
|
||
;HERE FOR DECNET CONNECT ACCEPT
|
||
|
||
NDNCA1: MOVE P3,T3 ;OPTIONAL USER CONNECT DATA
|
||
MOVE P1,[.NSFAC,,.NSAA1+1] ;"ACCEPT CONNECT" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;ACCEPT THE CONNECT INITIATE
|
||
JRST NDCXE1 ;FAILED, CLEAN UP
|
||
JRST .POPJ1## ;CHANNEL UP AND RUNNING
|
||
;NTNCR -- PASSIVE CHANNEL CONNECT REJECT
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<DAT>
|
||
; MOVX T3,<RSN>
|
||
; PUSHJ P,NTNCR
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; <RSN> is the NSP reason why
|
||
;the connection is being rejected; and <DAT> is the address
|
||
;of any optional connect data to be sent as part of the connect reject
|
||
;(must be 0 if no optional data).
|
||
;
|
||
;On error return the network aborted.
|
||
;
|
||
;On successful return the connect initiate has been rejected. The
|
||
;network channel has been aborted and released.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNCR
|
||
INTERN NTNCR0, NTNCR1
|
||
|
||
.NTNCR: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNCR0: PUSHJ P,.SAVE4## ;SAVE SOME ACS
|
||
NTNCR1: SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNCR>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANCR1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNCR1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNCR>
|
||
;HERE FOR ANF CONNECT REJECT
|
||
|
||
NANCR1: MOVEI P3,100(T3) ;POSITION "ABORT" CODE
|
||
MOVEI P1,.TKFEI ;FUNCTION: ENTER IDLE STATE (DISCONNECT)
|
||
MOVE M0,[3,,P1] ;TSK. ARG POINTER TO
|
||
TSK. M0, ;BREAK (SEND DISCONNECT) THE NET LINK
|
||
JRST NANAB1 ;ABORT THE LINK
|
||
PJRST NTNRL1 ;AND RELEASE THE TASK CHANNEL
|
||
; (CONSISTENT WITH SILLY DECNET NSP. UUO)
|
||
|
||
|
||
|
||
;HERE FOR DECNET CONNECT REJECT
|
||
|
||
NDNCR1: DMOVE P3,T2 ;OPTIONAL USER REJECT DATA, REASON
|
||
MOVE P1,[.NSFRJ,,.NSAA2+1] ;"REJECT CONNECT" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;REJECT THE CONNECT INITIATE
|
||
PJRST NTNRL1 ;HUH?? WE DON'T WANT IT!!!!!
|
||
PJRST NTFIN1 ;MARK NETWORK CHANNEL DEFUNCT
|
||
SUBTTL Network Link Control - Link management
|
||
|
||
;NTNRS -- RETURN NETWORK CHANNEL STATUS
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,NTNRS
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On normal return the network status is returned in T2.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNRS
|
||
INTERN NTNRS0, NTNRS1
|
||
|
||
.NTNRS: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNRS0: PUSHJ P,.SAVE4## ;NEED SOME ACS
|
||
NTNRS1: STOPCD <NTNRS called but not yet implemented>
|
||
SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNRS>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANRS1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNRS1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNRS>
|
||
;HERE FOR ANF RETURN STATUS
|
||
|
||
NANRS1: HALT
|
||
|
||
|
||
|
||
;HERE FOR DECNET RETURN STATUS
|
||
|
||
NDNRS1: MOVE P1,[.NSFRS,,.NSAA1+1] ;"READ STATE" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;READ NETWORK STATE
|
||
JRST NDRXE1 ;CONVERT ERROR CODE
|
||
MOVE T2,P3 ;RETURN STATE IN T2
|
||
HALT
|
||
;NTNSQ -- SET NETWORK CHANNEL QUOTA AND PERCENTAGES
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<QTA>
|
||
; MOVX T3,<PCT>
|
||
; PUSHJ P,NTNSQ
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; <QTA> is the "link quota"
|
||
;for the current network channel; <PCT> is the relative percentage of
|
||
;the link quota to be devoted to input buffering (integer range 1 to 99).
|
||
;
|
||
;On error return the monitor would not accept the range specified; error
|
||
;code is in M0.
|
||
;
|
||
;On normal return the channel parameters have been set as requested.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNSQ
|
||
INTERN NTNSQ0, NTNSQ1
|
||
|
||
.NTNSQ: PUSHJ P,.SACIO## ;SWITCH TO IO CONTEXT
|
||
NTNSQ0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
NTNSQ1: SKIPN P2,.IONCH(IO) ;GET NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNSQ>
|
||
MOVE T1,.IOCCF(IO) ;GET CHANNEL CONTROL FLAGS
|
||
TXNE T1,IO.ANF ;ANF NETWORK PROTOCOL?
|
||
JRST NANSQ1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK PROTOCOL?
|
||
JRST NDNSQ1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNSQ>
|
||
;HERE FOR ANF SET LINK QUOTAS
|
||
|
||
NANSQ1: JRST .POPJ1## ;SO MUCH FOR THAT
|
||
|
||
|
||
|
||
;HERE FOR DECNET SET LINK QUOTAS
|
||
|
||
NDNSQ1: MOVE P1,[.NSFSQ,,.NSAA2+1] ;NSP. FUNCTION WORD
|
||
SKIPG P3,T2 ;LINK QUOTA
|
||
SETO P3, ;NONE SPECIFIED
|
||
SKIPG P4,T3 ;RELATIVE PERCENT INPUT
|
||
SETO P4, ;NONE SPECIFIED
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;SET LINK QUOTA AND PERCENTAGE
|
||
JRST NDRXE1 ;FAILED?
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
SUBTTL Network Link Control - Link termination
|
||
|
||
;NTNSD -- NETWORK DISCONNECT
|
||
;CALL IS:
|
||
;
|
||
; MOVE T1,<CDB>
|
||
; MOVX T3,<DAT>
|
||
; PUSHJ P,NTNSD
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O <CDB>; <RSN> is the NSP reason
|
||
;code for why the network link is disconnecting; and <DAT> is the address
|
||
;of any optional disconnect data to be sent as part of the disconnect
|
||
;process (must be 0 if no optional data).
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On successful return the disconnect has been sent (but the network
|
||
;channel is still "active" and able to receive data sent by the other
|
||
;side).
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNSD
|
||
INTERN NTNSD0, NTNSD1
|
||
|
||
.NTNSD: PUSHJ P,.SACIO## ;SETUP I/O CDB ADDRESS
|
||
NTNSD0: PUSHJ P,.SAVE4## ;SAVE A FEW ACS
|
||
NTNSD1: SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNSD>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANSD1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNSD1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNSD>
|
||
;HERE FOR ANF SYNCHRONOUS DISCONNECT
|
||
|
||
NANSD1: MOVX P1,.TKFEI ;FUNCTION: ENTER "IDLE" STATE
|
||
MOVE T1,[2,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;SEND A DISCONNECT INITIATE
|
||
JRST NARXE1 ;CONVERT TSK. ERROR CODE
|
||
JRST .POPJ1## ;SUCCESSFUL
|
||
|
||
|
||
|
||
;HERE FOR DECNET SYNCHRONOUS DISCONNECT
|
||
|
||
NDNSD1: MOVE P3,T3 ;OPTIONAL USER DATA
|
||
MOVE P1,[.NSFSD,,.NSAA1+1] ;"SYCHRONOUS DISCONNECT" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;SEND DISCONNECT INITIATE
|
||
JRST NDRXE1 ;CONVERT ERROR CODE
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;NTNAB -- NETWORK ABORT
|
||
;CALL IS:
|
||
;
|
||
; MOVE T1,<CDB>
|
||
; MOVX T3,<DAT>
|
||
; PUSHJ P,NTNAB
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O <CDB>; <RSN> is the NSP reason
|
||
;code for aborting the network link; and <DAT> is the address
|
||
;of any optional disconnect data to be sent as part of the disconnect
|
||
;and abort process (must be 0 if no optional data).
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On successful return the network channel has been aborted and
|
||
;released.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNAB
|
||
INTERN NTNAB0, NTNAB1
|
||
|
||
.NTNAB: PUSHJ P,.SACIO## ;SETUP I/O CDB ADDRESS
|
||
NTNAB0: PUSHJ P,.SAVE4## ;SAVE A FEW ACS
|
||
NTNAB1: SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNAB>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANAB1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNAB1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNAB>
|
||
;HERE FOR ANF ABORT
|
||
|
||
NANAB1: RESDV. P2, ;ZAPETH THE I/O CHANNEL DEAD
|
||
JFCL ;HUH?
|
||
PJRST NTFIN1 ;AND CLEAN OUT THE NETWORK DATABASE
|
||
|
||
|
||
|
||
;HERE FOR DECNET ABORT
|
||
|
||
NDNAB1: MOVE P3,T3 ;OPTIONAL USER DATA
|
||
MOVE P1,[.NSFAB,,.NSAA1+1] ;"ABORT" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;ABORT THE CHANNEL
|
||
PJRST NTNRL1 ;HUH?? BY DAMN, GET RID OF THE BLOODY THING
|
||
PJRST NTFIN1 ;MARK THE NETWORK CHANNEL DEFUNCT
|
||
;NTNRD -- READ DISCONNECT REASON AND OPTIONAL DATA
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T3,<ADR>
|
||
; PUSHJ P,NTNRD
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and <ADR> is the address
|
||
;to receive any optional user disconnect data (returned in 8-bit format).
|
||
;
|
||
;The error return is taken if ???
|
||
;
|
||
;On normal return, any "Optional User Data" has been read into the
|
||
;specified string block in normal 8-bit format. The disconnect reason
|
||
;(as supplied by the network services) is returned in T2.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNRD
|
||
INTERN NTNRD0, NTNRD1
|
||
|
||
.NTNRD: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNRD0: PUSHJ P,.SAVE4## ;SAVE A FEW ACS
|
||
NTNRD1: SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNRD>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANRD1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNRD1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNRD>
|
||
;HERE FOR ANF READ DISCONNECT REASON
|
||
|
||
NANRD1: JRST .POPJ1## ;SO MUCH FOR THAT
|
||
|
||
|
||
|
||
;HERE FOR DECNET READ DISCONNECT REASON
|
||
|
||
NDNRD1: MOVE P3,T3 ;ADDRESS OF "STRING" BLOCK
|
||
MOVE P1,[.NSFRD,,.NSAA2+1] ;READ DISCONNECT DATA
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;READ OPTIONAL DISCONNECT DATA
|
||
JRST NDRXE1 ;CONVERT ERROR CODE
|
||
MOVE T2,P3 ;RETURN DISCONNECT REASON
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;NTNRL -- RELEASE NETWORK CHANNEL
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,NTNRL
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;On error return the network died first.
|
||
;
|
||
;On normal return the network channel has been released.
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTNRL
|
||
INTERN NTNRL0, NTNRL1
|
||
|
||
.NTNRL: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTNRL0: PUSHJ P,.SAVE4 ;SAVE SOME ACS
|
||
NTNRL1: SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTNRL>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NANRL1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDNRL1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTNRL>
|
||
;HERE FOR ANF RELEASE
|
||
|
||
NANRL1: MOVS P1,P2 ;POSITION CHANNEL IN LH FOR FILOP.
|
||
HRRI P1,.FOREL ;FUNCTION: RELEASE
|
||
MOVE T1,[1,,P1] ;FILOP. ARG POINTER TO
|
||
FILOP. T1, ;RELEASE TSK CHANNEL
|
||
PJRST NTZAP1 ;*** HO HUM, JUST BLOW IT AWAY
|
||
PJRST NTFIN1 ;CLEAN OUT THE NETWORK DATABASE
|
||
|
||
|
||
|
||
;HERE FOR DECNET RELEASE
|
||
|
||
NDNRL1: MOVE P1,[.NSFRL,,.NSACH+1] ;"RELEASE CHANNEL" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;RELEASE THE CHANNEL
|
||
JRST NDRXE1 ;ERROR, CONVERT CODE
|
||
JRST NTFIN1 ;FINISH OFF THE NETWORK
|
||
;NTZAP -- ZAP A NETWORK CHANNEL
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,NTZAP
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB.
|
||
;
|
||
;NTZAP is used to unconditionally "ZAP" any network I/O in progress.
|
||
;If the CDB is not currently network-active, NTZAP simply returns. If
|
||
;any network activity is pending, it is thrown away, the network link
|
||
;(or channel if you prefer) is RELEASed/RESET, I/O buffers are de-al-
|
||
;located, and so on.
|
||
;
|
||
;NTZAP should be used as a unknown-state cleanup mechanism which doesn't
|
||
;care what happens, just as long as the CDB is cleaned up. Errors are
|
||
;suppressed.
|
||
;
|
||
;The error return is not utilized.
|
||
;
|
||
;On normal return, any network I/O has been RESET, buffers deallocated,
|
||
;and the CDB cleaned up (network-wise).
|
||
;
|
||
;Uses T1, T2, T3, T4.
|
||
|
||
ENTRY .NTZAP
|
||
INTERN NTZAP0, NTZAP1
|
||
|
||
.NTZAP: PUSHJ P,.SACIO## ;SWITCH TO I/O CONTEXT
|
||
NTZAP0: PUSHJ P,.SAVE4## ;PRESERVE THE PRESERVED REGISTERS
|
||
NTZAP1: ;FEEL FREE TO TRASH THE TEMPS
|
||
SKIPN P2,.IONCH(IO) ;GOT A NETWORK CHANNEL IN USE?
|
||
PJRST NTFIN6 ;NO, JUST BLAST SOME BITS ON G.P.'S
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NAZAP1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDZAP1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTZAP>
|
||
;HERE FOR ANF ZAP
|
||
|
||
NAZAP1: RESDV. P2, ;STOMPETH UPON WHATEVER IS THERE
|
||
JFCL ;WELL, I TRIED!
|
||
PJRST NTFIN1 ;CLEAN OUT THE NETWORK DATABASE
|
||
|
||
|
||
|
||
;HERE FOR DECNET ZAP
|
||
|
||
NDZAP1: MOVE P1,[.NSFRL,,.NSACH+1] ;"RELEASE CHANNEL" FUNCTION
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;RELEASE THE CHANNEL
|
||
JFCL ;WELL, I TRIED!
|
||
JRST NTFIN1 ;FINISH OFF THE NETWORK
|
||
SUBTTL Network Link Control - Support routines
|
||
|
||
;NTINI - COMMON ACTIVE/PASSIVE NETWORK COMMUNICATIONS INITIALIZATION
|
||
|
||
ENTRY .NTINI
|
||
INTERN NTINI0, NTINI1
|
||
|
||
.NTINI: PUSHJ P,.SACIO## ;SET UP I/O CDB INDEX
|
||
NTINI0: PUSHJ P,.SAVE4## ;SAVE THE P'S
|
||
NTINI1: PUSHJ P,TSAV14## ;SAVE THE T'S, ON G.P.S
|
||
SKIPN P2,.IONCH(IO) ;ASSURE NETWORK CHANNEL
|
||
STOPCD <No network channel in NTINI>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NAINI1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDINI1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTINI>
|
||
;HERE FOR ANF INITIALIZATION
|
||
|
||
NAINI1: TXNE T1,IO.NBA ;NETWORK BUFFERS ALLOCATED?
|
||
STOPCD <IO.NBA in NAINI1>
|
||
|
||
;ALLOCATE NETWORK INPUT AND OUTPUT BUFFERS
|
||
|
||
NAINI2: MOVEI P1,.TKFRX ;FUNCTION: READ STATUS AND MESSAGE SIZES
|
||
SETZB P3,P4 ;JUST TO MAKE SURE . . .
|
||
MOVE T1,[4,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;READ STATE OF TASK CHANNEL
|
||
JRST [MOVEI P1,.TKFRS ;FUNCTION: READ STATUS
|
||
MOVE T1,[3,,P1] ;TSK. ARG POINTER TO
|
||
TSK. T1, ;READ STATE OF TASK CHANNEL
|
||
STOPCD <TSK. (.TKFRS) failed in NAINI2>
|
||
MOVEI P4,$NABFS ;FAKE UP A DEFAULT SEGMENT SIZE
|
||
JRST .+1] ;CONTINUE ONWARDS
|
||
CAIE P3,.TKSOK ;IS THE LINK "UP AND RUNNING"?
|
||
JRST [CAIE P3,.TKSID ;"IDLE" (RECEIVED DISCONNECT)?
|
||
STOPCD <Network link status not "RUNNING" in NAINI>
|
||
JRST NARXS1] ;TRANSLATE DISCONNECT REASON
|
||
ANDI P4,-1 ;WANT JUST MESSAGE LENGTH (IGNORE RLN FIELD)
|
||
MOVEM P4,.IONLB(IO) ;SET NETWORK BUFFER SIZE (8-BIT BYTES)
|
||
MOVEM P4,.IONLM(IO) ;WHICH IS ALSO PRELIMINARY MAXIMUM MESSAGE SIZE
|
||
ADDI P4,3 ;ROUND UP, AND
|
||
LSH P4,-2 ;TRUNCATE TO -10 WORD COUNT
|
||
MOVEM P4,.IONLW(IO) ;SET NETWORK BUFFER SIZE (-10 WORDS)
|
||
MOVSI T2,$NAIBF ;NUMBER OF INPUT BUFFERS TO USE
|
||
HRRI T2,$NAIBX(P4) ;SIZE OF INDIVIDUAL INPUT BUFFER
|
||
XMOVEI T4,.IONIH(IO) ;ADDRESS OF INPUT BUFFER RING HEADER
|
||
PUSHJ P,IOBFA1## ;ALLOCATE INPUT BUFFERS
|
||
STOPCD <Can't allocate ANF input buffer(s)>
|
||
DMOVEM T2,.IONIB(IO) ;SAVE BUFFER ID FOR DEALLOCATION
|
||
MOVSI T2,1 ;ALWAYS USE ONE OUTPUT BUFFER (IT'S A LONG
|
||
; STORY, THAT'S JUST THE WAY TOPS10 WORKS)
|
||
HRR T2,P4 ;SIZE OF INDIVIDUAL OUTPUT BUFFER
|
||
XMOVEI T4,.IONOH(IO) ;ADDRESS OF OUTPUT BUFFER RING HEADER
|
||
PUSHJ P,IOBFA1## ;ALLOCATE OUTPUT BUFFERS
|
||
STOPCD <Can't allocate ANF output buffer(s)>
|
||
DMOVEM T2,.IONOB(IO) ;SAVE BUFFER ID FOR DEALLOCATION
|
||
MOVX T1,BF.IBC ;THE INHIBIT-BUFFER-CLEARING BIT
|
||
IORM T1,.IONOH(IO) ;LEAVE MY BUFFER ALONE!!!
|
||
MOVX T1,IO.NBA ;THE NETWORK-BUFFERS-ALLOCATED BIT
|
||
IORM T1,.IOCCF(IO) ;SET IN CDB
|
||
MOVX T1,NS.EOM ;THE END-OF-MESSAGE FLAG
|
||
MOVEM T1,.IONIS(IO) ;PRESET FOR RNMSG
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;DO A "DUMMY" IN TO TRICK MONITOR INTO SENDING DATA REQUESTS
|
||
|
||
NAINI6: MOVS T2,.IONCH(IO) ;NETWORK TSK CHANNEL NUMBER
|
||
HRRI T2,.FOINP ;FUNCTION: INPUT
|
||
MOVE T1,[1,,T2] ;FILOP. ARG POINTER TO
|
||
FILOP. T1, ;EXECUTE A "DUMMY" IN (IT MIGHT EVEN WORK!)
|
||
JFCL ;IGNORE ERRORS HERE, CATCH 'EM LATER
|
||
|
||
JRST .POPJ1## ;READY FOR ANF NETWORK I/O
|
||
;HERE FOR DECNET INITIALIZATION
|
||
|
||
NDINI1: TXNE T1,IO.NBA ;NETWORK BUFFERS ALLOCATED?
|
||
JRST NDINI6 ;YES, JUST RESET COUNTERS
|
||
|
||
;ALLOCATE NETWORK INPUT AND OUTPUT BUFFERS
|
||
|
||
NDINI2: MOVE P1,[.NSFRS,,.NSAA2+1] ;RETURN STATUS FUNCTION
|
||
SETZB P3,P4 ;ON G.P.'S
|
||
XMOVEI M0,P1 ;NSP. ARG POINTER TO
|
||
NSP. M0, ;READ NETWORK MESSAGE SEGMENT SIZE
|
||
JRST NDRXE1 ;OOPS
|
||
LDB T1,[POINTR P2,NS.STA] ;EXTRACT THE LINK STATE
|
||
CAIE T1,.NSSRN ;LINK HAD BETTER BE "RUNNING" AT THIS POINT
|
||
STOPCD <Network link status not "RUNNING" in NDINI>
|
||
MOVEM P3,.IONLB(IO) ;SET NETWORK BUFFER SIZE (8-BIT BYTES)
|
||
MOVEM P3,.IONLM(IO) ;WHICH IS ALSO PRELIMINARY MAXIMUM MESSAGE SIZE
|
||
ADDI P3,3 ;ROUND UP, AND
|
||
LSH P3,-2 ;TRUNCATE TO -10 WORD COUNT
|
||
MOVEM P3,.IONLW(IO) ;SET NETWORK BUFFER SIZE (-10 WORDS)
|
||
MOVE T1,P3 ;NETWORK BUFFER LENGTH (-10 WORDS)
|
||
LSH T1,1 ;ONE INPUT, AND ONE OUTPUT BUFFER
|
||
SKIPN T2,.IOXFF(IO) ;DOES THE CDB HAVE ANY EXTRA SPACE?
|
||
JRST NDINI3 ;NO, MUST ALLOCATE FROM MANAGED MEMORY
|
||
ADD T2,T1 ;YES, T2:=PROPOSED NEW .IOXFF
|
||
CAML T2,.IOXSZ(IO) ;WILL THE TWO BUFFERS FIT?
|
||
JRST NDINI3 ;NO, MUST ALLOCATE FROM MANAGED MEMORY
|
||
EXCH T2,.IOXFF(IO) ;YES, GLOM ONTO IT
|
||
ADD T2,IO ;RELOCATE INTO PHYSICAL (RELATIVELY) MEMORY
|
||
JRST NDINI4 ;SET ADDRESS(S)
|
||
|
||
;ALLOCATE BUFFERS FROM MANAGED MEMORY
|
||
|
||
NDINI3: PUSHJ P,.MMGWD## ;ALLOCATE SOME MANAGED MEMORY
|
||
STOPCD <Network buffer memory allocation failed in NDINI3>
|
||
|
||
NDINI4: SETZM (T2) ;CLEAR START OF BUFFER
|
||
HRLZ M0,T2 ;CONCOCT A
|
||
HRRI M0,1(T2) ; BLT POINTER TO
|
||
MOVE T1,.IONLW(IO) ;LENGTH OF ONE BUFFER (-10 WORDS)
|
||
LSH T1,1 ;ALLOW FOR TWO BUFFERS
|
||
ADD T1,T2 ;T1:=END (+1) OF NETWORK BUFFERS
|
||
BLT M0,-1(T1) ;CLEAR NETWORK BUFFERS
|
||
MOVEM T2,.IONIB(IO) ;SET ADDRESS OF NETWORK INPUT BUFFER
|
||
ADD T2,.IONLW(IO) ;OFFSET TO NEXT BUFFER
|
||
MOVEM T2,.IONOB(IO) ;WHICH BECOMES THE NETWORK OUTPUT BUFFER
|
||
MOVX T1,IO.NBA ;THE NETWORK-BUFFERS-ALLOCATED BIT
|
||
IORM T1,.IOCCF(IO) ;SET IN THE CDB
|
||
|
||
NDINI6: MOVX T1,NS.EOM ;END-OF-MESSAGE-SEEN FLAG
|
||
MOVEM T1,.IONIS(IO) ;PRESET TO KEEP RNMSG HAPPY
|
||
SETZM .IONIC(IO) ;CURRENTLY HAVE NO INPUT DATA BYTES
|
||
PJRST XDBUF6 ;SETUP OUTPUT BUFFER COUNTER/POINTER
|
||
;NTFIN - FINISH OFF THE NETWORK CHANNEL
|
||
|
||
ENTRY .NTFIN
|
||
INTERN NTFIN0, NTFIN1
|
||
|
||
.NTFIN: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
NTFIN0: PUSHJ P,.SAVE4## ;PROTECT THE P'S
|
||
NTFIN1: MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL FLAGS
|
||
SETZM .IONCH(IO) ;NOTE NO MORE CHANNEL
|
||
SETZM .ION6M(IO) ; . . .
|
||
TXNE T1,IO.ANF ;ANF NETWORK CHANNEL?
|
||
JRST NAFIN1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK CHANNEL?
|
||
JRST NDFIN1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in NTFIN>
|
||
;HERE FOR ANF CLEANUP
|
||
|
||
NAFIN1: TXNN T1,IO.NBA ;NETWORK BUFFERS ALLOCATED?
|
||
JRST NAFIN6 ;NO, NOTHING TO DEALLOCATE
|
||
DMOVE T2,.IONOB(IO) ;OUTPUT BUFFER ID
|
||
XMOVEI T4,.IONOH(IO) ;ADDRESS OF OUTPUT BUFFER RING HEADER
|
||
PUSHJ P,IOBFZ1## ;DEALLOCATE THE OUTPUT BUFFERS
|
||
STOPCD <Can't deallocate ANF output buffer(s)>
|
||
DMOVE T2,.IONIB(IO) ;INPUT BUFFER ID
|
||
XMOVEI T4,.IONIH(IO) ;ADDRESS OF INPUT BUFFER RING HEADER
|
||
PUSHJ P,IOBFZ1## ;DEALLOCATE THE INPUT BUFFERS
|
||
STOPCD <Can't deallocate ANF input buffer(s)>
|
||
NAFIN6: PJRST NTFIN6 ;FINAL CLEAN UP
|
||
;HERE FOR DECNET CLEANUP
|
||
|
||
NDFIN1: TXNN T1,IO.NBA ;NETWORK BUFFERS ALLOCATED?
|
||
JRST NDFIN6 ;NO, NOTHING TO DEALLOCATE
|
||
SKIPLE T2,.IONIB(IO) ;ADDRESS OF NETWORK INPUT BUFFER
|
||
CAIGE T2,.JBDA ;REASONABLE ADDRESS?
|
||
STOPCD <Network input buffer trashed in NDFIN1>
|
||
SKIPLE T3,.IONOB(IO) ;ADDRESS OF NETWORK OUTPUT BUFFER
|
||
CAIGE T2,.JBDA ;REASONABLE ADDRESS?
|
||
STOPCD <Network output buffer trashed in NDFIN1>
|
||
SUB T3,.IONLW(IO) ;BACK UP ONE BUFFERS' WORTH
|
||
CAMN T2,T3 ;ARE THE TWO BUFFERS ADJACENT?
|
||
JRST NDFIN3 ;YES
|
||
|
||
;RANDOM BUFFER ALLOCATION, MUST HAVE COME FROM MANAGED MEMORY AS SEPARATE HUNKS
|
||
|
||
MOVE T1,.IONLW(IO) ;SIZE OF ONE NETWORK BUFFER
|
||
PUSHJ P,.MMFWD## ;FREE UP NETWORK INPUT BUFFER
|
||
STOPCD <Network input buffer deallocation failed in NDFIN1>
|
||
MOVE T1,.IONLW(IO) ;SIZE OF ONE NETWORK BUFFER
|
||
MOVE T2,.IONOB(IO) ;ADDRESS OF OUTPUT BUFFER
|
||
PUSHJ P,.MMFWD## ;FREE UP NETWORK OUTPUT BUFFER
|
||
STOPCD <Network output buffer deallocation failed in NDFIN1>
|
||
JRST NDFIN6 ;NO MORE BUFFERS
|
||
|
||
;NETWORK BUFFERS CONTIGUOUS, MUST HAVE COME AS ONE HUNK
|
||
|
||
NDFIN3: MOVE T1,.IONLW(IO) ;SIZE OF SINGLE NETWORK BUFFER
|
||
LSH T1,1 ;SIZE OF BOTH NETWORK BUFFERS
|
||
ADD T3,T1 ;T3:=END ADDRESS OF BUFFER ALLOCATION
|
||
SUB T3,IO ;TURN INTO RELATIVE OFFSET INTO CDB
|
||
JUMPLE T3,NDFIN5 ;IF NOT WITHIN CDB THEN FROM MANAGED MEMORY
|
||
CAMLE T3,.IOXSZ(IO) ;WITHIN CDB EXTRA SPACE?
|
||
JRST NDFIN5 ;NO, MUST BE FROM MANAGED MEMORY
|
||
CAIGE T3,.IOMAX ;ENSURE NOT WITHIN FIXED PART OF CDB
|
||
STOPCD <Network buffers trashed in NDFIN3>
|
||
CAMN T3,.IOXFF(IO) ;NETWORK BUFFERS LAST THING ALLOCATED?
|
||
MOVEM T2,.IOXFF(IO) ;YES, RECLAIM "EXTRA" SPACE
|
||
JRST NDFIN6 ;MARK BUFFERS DEALLOCATED
|
||
|
||
NDFIN5: PUSHJ P,.MMFWD## ;FREE UP COMBINED NETWORK BUFFERS
|
||
STOPCD <Network buffers deallocation failed in NDFIN5>
|
||
NDFIN6:;PJRST NTFIN6 ;FINAL CLEANUP
|
||
|
||
|
||
;HERE FOR FINAL CLEANUP OF THE CDB
|
||
|
||
NTFIN6: SETZM .IONIB(IO) ;NO MORE INPUT BUFFERS
|
||
SETZM .IONOB(IO) ;NO MORE OUTPUT BUFFERS
|
||
MOVX T1,IO.CNR!IO.NBA;BITS TO CLEAR ON NETWORK RELEASE
|
||
ANDCAM T1,.IOCCF(IO) ;CLEAR UP THE CDB
|
||
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;N6TO8 - CONVERT 6-BIT FORMAT INTO 8-BIT FORMAT
|
||
;CALL IS:
|
||
;
|
||
; MOVX T2,<N6M>
|
||
; MOVX P3,<N8P>
|
||
; PUSHJ P,N6TO8
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <N6M> is the 6-bit name (implicit maximum of 6 characters); and
|
||
;<N8P> is the 8-bit storage pointer in the form count,,offset where
|
||
;"count" is the maximum byte count for the string, and "offset" is the
|
||
;offset in the I/O CDB for the 8-bit format string.
|
||
;
|
||
;The error return is taken if the 6-bit name is too big for the 8-bit
|
||
;string maximum length (with code $EFRSB in M0).
|
||
;
|
||
;On normal return, the name has been stored as an 8-bit byte string
|
||
;in standard format (first word assumed byte count but left untouched).
|
||
;The RH(P3) contains the actual byte count of the converted byte string.
|
||
;
|
||
;Uses P3, P4.
|
||
|
||
N6TO8: PUSHJ P,NP3P4 ;SETUP .IONP3/.IONP4 AS COUNTER/POINTER
|
||
POPJ P, ;OOPS, ERROR
|
||
N6TO80: PUSHJ P,TSAV12## ;SAVE T1 AND T2
|
||
XMOVEI T1,NTYPO ;OUR SPECIAL "TYPEOUT" ROUTINE
|
||
PUSHJ P,.XTYPO## ;SET IT UP
|
||
MOVE T1,T2 ;POSITION 6-BIT NAME
|
||
PUSHJ P,.TSIXN## ;AND "TYPE" THE NAME
|
||
DMOVE P3,.IONP3(IO) ;FETCH TERMINAL BYTE COUNTER/POINTER
|
||
JUMPL P3,.POPJ1## ;SUCCESSFUL IF NAME FIT
|
||
MOVEI M0,$EFRSB ;STRING TOO BIG
|
||
POPJ P, ;ERROR
|
||
;N6XO8 - CONVERT 6-BIT (DOUBLE-WORD) FORMAT INTO 8-BIT FORMAT
|
||
;CALL IS:
|
||
;
|
||
; MOVX T2,<N6X>
|
||
; MOVX P3,<N8P>
|
||
; PUSHJ P,N6XO8
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <N6X> is the 6-bit name (implicit maximum of 12 characters); and
|
||
;<N8P> is the 8-bit storage pointer in the form count,,offset where
|
||
;"count" is the maximum byte count for the string, and "offset" is the
|
||
;offset in the I/O CDB for the 8-bit format string.
|
||
;
|
||
;The error return is taken if the 6-bit name is too big for the 8-bit
|
||
;string maximum length (with code $EFRSB in M0).
|
||
;
|
||
;On normal return, the name has been stored as an 8-bit byte string
|
||
;in standard format (first word assumed byte count but left untouched).
|
||
;The RH(P3) contains the actual byte count of the converted byte string.
|
||
;
|
||
;Uses P3, P4.
|
||
|
||
ENTRY .N6XO8
|
||
|
||
.N6XO8:
|
||
N6XO8: PUSHJ P,NP3P4 ;SETUP .IONP3/.IONP4 AS COUNTER/POINTER
|
||
POPJ P, ;OOPS, ERROR
|
||
N6XO80: PUSHJ P,TSAV13## ;SAVE THE T'S
|
||
JUMPE T2,N6XO85 ;ENTER LOOP, SUPPRESSING NULL NAME
|
||
N6XO82: SETZ T1, ;CLEAR CHAR ACCUMULATOR
|
||
LSHC T1,6 ;NEXT NAME CHARACTER
|
||
ADDI T1,"0"-'0' ;ASCIIZE IT
|
||
PUSHJ P,NTYPO ;AND ADD IT TO THE STRING
|
||
LSH T2,-6 ;RE-POSITION NAME FRAGMENT
|
||
LSHC T2,6 ;AND POSITION WHOLE NAME
|
||
N6XO85: JUMPN T2,N6XO82 ;LOOP IF MORE TO DO
|
||
JUMPN T3,N6XO82 ;LOOP IF MORE TO DO
|
||
DMOVE P3,.IONP3(IO) ;FETCH TERMINAL BYTE COUNTER/POINTER
|
||
JUMPL P3,.POPJ1## ;SUCCESSFUL IF NAME FIT
|
||
MOVEI M0,$EFRSB ;STRING TOO BIG
|
||
POPJ P, ;ERROR
|
||
;N7TO8 - CONVERT 7-BIT FORMAT INTO 8-BIT FORMAT
|
||
;CALL IS:
|
||
;
|
||
; MOVX T2,<ADR>
|
||
; MOVX P3,<N8P>
|
||
; PUSHJ P,N6TO8
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <ADR> is the address of the 7-bit ASCIZ string; and
|
||
;<N8P> is the 8-bit storage pointer in the form count,,offset where
|
||
;"count" is the maximum byte count for the string, and "offset" is the
|
||
;offset in the I/O CDB for the 8-bit format string.
|
||
;
|
||
;The error return is taken if the 7-bit string is too big for the 8-bit
|
||
;string maximum length (with code $EFRSB in M0).
|
||
;
|
||
;On normal return, the string has been stored as an 8-bit byte string
|
||
;in standard format (first word assumed byte count but left untouched).
|
||
;The RH(P3) contains the actual byte count of the converted byte string.
|
||
;
|
||
;Uses P3, P4.
|
||
|
||
ENTRY .N7TO8
|
||
|
||
.N7TO8: PUSHJ P,NP3P4 ;SETUP .IONP3/.IONP4 AS COUNTER/POINTER
|
||
POPJ P, ;OOPS, ERROR
|
||
N7TO80: PUSHJ P,TSAV12## ;SAVE T1 AND T2
|
||
XMOVEI T1,NTYPO ;OUR SPECIAL "TYPEOUT" ROUTINE
|
||
PUSHJ P,.XTYPO## ;SET IT UP
|
||
MOVE T1,T2 ;POSITION 7-BIT STRING ADDRESS
|
||
PUSHJ P,.TSTRG## ;AND "TYPE" THE STRING
|
||
DMOVE P3,.IONP3(IO) ;FETCH TERMINAL BYTE COUNTER/POINTER
|
||
JUMPL P3,.POPJ1## ;SUCCESSFUL IF NAME FIT
|
||
MOVEI M0,$EFRSB ;STRING TOO BIG
|
||
POPJ P, ;ERROR
|
||
;N8TO6 - CONVERT 8-BIT FORMAT STRING INTO 6-BIT NAME
|
||
;CALL IS:
|
||
;
|
||
; MOVX P4,<NDX>
|
||
; PUSHJ P,N8TO6
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <NDX> is the index into the I/O CDB of the 8-bit format byte
|
||
;string.
|
||
;
|
||
;The error return is not utilized.
|
||
;
|
||
;On normal return T2 contains the 6-bit name (or at least the first
|
||
;6 characters' worth).
|
||
;
|
||
;Uses T1, T2, P2, P3, P4.
|
||
|
||
N8TO6: ADD P4,IO ;CONVERT TO WORD ADDRESS
|
||
HLRZ P3,@P4 ;GET BYTE COUNT
|
||
HRLI P4,(POINT 8,,32);CONCOCT A BYTE POINTER
|
||
N8TO60: MOVE P2,[POINT 6,T2] ;6-BIT NAMIFIER
|
||
SETZ T2, ;INITIALIZE NAME
|
||
JRST N8TO65 ;ENTER LOOP
|
||
|
||
N8TO62: TLNE P2,770000 ;ROOM IN WORD FOR ANOTHER CHARACTER?
|
||
IDPB T1,P2 ;YES, STUFF IN NEXT CHARACTER
|
||
N8TO65: ILDB T1,P4 ;NEXT 8-BIT BYTE
|
||
SUBI T1,"A"-'A' ;SIXBITIFY THE SEVEN-BIT ASCII CHARACTER
|
||
SOJGE P3,N8TO62 ;LOOP FOR REST OF STRING
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;NP3P4 - SETUP .IONP3/.IONP4 AS BYTE COUNT/BYTE POINTER
|
||
;CALL IS:
|
||
;
|
||
; MOVX P3,<8BP>
|
||
; PUSHJ P,NP3P4
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <8BP> is the prototype 8-bit format pointer in the form count,,offset
|
||
;where "count" is the maximum byte count of the string and "offset" is the
|
||
;byte string offset into the I/O CDB.
|
||
;
|
||
;On error return the specified index was outside of all possible CDB offsets
|
||
;
|
||
;On normal return .IONP3 will contain an AOBJN counter of the form -max,,0 and
|
||
;.IONP4 will contain the byte pointer for IDPBs.
|
||
;
|
||
;Uses P3 and P4.
|
||
|
||
NP3P4: HRRZ P4,P3 ;WORD OFFSET INTO THE CDB
|
||
ANDCMI P3,-1 ;MAXIMUM OFFSET,,0
|
||
CAILE P4,.IOMAX ;WITHIN RANGE?
|
||
STOPCD <8-bit format index outside of I/O CDB bounds in NP3P4>
|
||
HRLI P4,(POINT 8,(IO),32) ;CONVERT TO 8-BIT BYTE POINTER
|
||
TLC P3,-1 ;MAKE COUNT INTO AOBJN POINTER
|
||
DMOVEM P3,.IONP3(IO) ;SETUP COUNTER/POINTER
|
||
; (THIS WAY THE RH(.IONP3) IS AN UP-TO-DATE
|
||
; COUNT OF BYTES ACTUALLY STORED, WHILE
|
||
; LH IS NEGATIVE IF NOT YET OVERFLOWED)
|
||
JRST .POPJ1## ;READY FOR CALLS TO NTYPO
|
||
|
||
|
||
|
||
;NTYPO - HELPER FOR N6TO8, ETC.
|
||
|
||
NTYPO: EXCH P3,.IONP3(IO) ;GET CUMULATIVE COUNTER
|
||
AOBJP P3,.+2 ;ROOM FOR ANOTHER 8-BIT BYTE?
|
||
IDPB T1,.IONP4(IO) ;YES
|
||
EXCH P3,.IONP3(IO) ;RESTORE CALLER'S P3
|
||
POPJ P, ;RETURN
|
||
SUBTTL Network I/O Control
|
||
|
||
;RNEAT -- EAT [REST OF] NETWORK MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RNEAT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On normal return the network input message has been completely read, and
|
||
;is now ready for the next input message (i.e., RNBYT will return
|
||
;with no data available, RNMSG must be called to start the next input
|
||
;message processing).
|
||
;
|
||
;Uses ac T2.
|
||
|
||
RNEAT: SETZM .IONIC(IO) ;WE CAN CHEAT A BIT HERE
|
||
PUSHJ P,RNBYT1 ;READ A NETWORK BYTE
|
||
CAIA ;PROBABLY NONE LEFT
|
||
JRST RNEAT ;LOOP BACK FOR MORE DATA
|
||
JUMPE M0,.POPJ1## ;SUCCESSFUL RETURN
|
||
POPJ P, ;NETWORK DIED
|
||
;RNBYT -- READ ONE NETWORK BYTE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RNBYT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return either the network died (M0 has the error code) or there
|
||
;are no more bytes left in the current input message (M0 has 0).
|
||
;
|
||
;On normal return the next data byte from the network channel is in T2.
|
||
;
|
||
;Uses ac T2.
|
||
|
||
ENTRY .RNBYT
|
||
INTERN RNBYT0, RNBYT1
|
||
|
||
.RNBYT: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RNBYT0:
|
||
RNBYT1: SOSGE .IONIC(IO) ;ANY BYTES LEFT?
|
||
JRST RNBYT2 ;NO, AT LEAST NOT IN OUR BUFFER
|
||
ILDB T2,.IONIP(IO) ;YES, READ THE NEXT BYTE
|
||
AOS (P) ;SUCCESSFUL
|
||
POPJ P, ; RETURN
|
||
|
||
;HERE TO SEE IF NETWORK MESSAGE ENDED, OR MERELY SEGMENTED AND STILL MORE
|
||
;BYTES LEFT.
|
||
|
||
RNBYT2: MOVE T2,.IONIS(IO) ;GET INPUT STATE
|
||
TXNE T2,NS.EOM ;MORE INPUT COMING?
|
||
JRST RNBYT5 ;NO, END OF MESSAGE SEEN, NULL RETURN
|
||
|
||
;READ IN NEXT MESSAGE SEGMENT FROM MONITOR
|
||
|
||
PUSHJ P,RNBUF0 ;REFILL OUR BYTE BUFFER
|
||
POPJ P, ;NETWORK DIED
|
||
RCV < MOVE T2,.IODIM(IO) ;GET THE MESSAGE TYPE
|
||
CAIN T2,$DHDAT ;DATA MESSAGE ?
|
||
PUSHJ P,TRCRC0 > ;YES, TRACE RECEIVED DATA
|
||
JRST RNBYT1 ;TRY AGAIN
|
||
|
||
RNBYT5: SETZ M0, ;RETURN NULL TO INDICATE END OF MESSAGE
|
||
POPJ P, ;EMPTY RETURN
|
||
;RNMSG -- READ IN ONE NETWORK MESSAGE
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RNMSG
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died (M0 has error code).
|
||
;
|
||
;On successful return the first byte of the message is in T2.
|
||
;
|
||
;Uses T2.
|
||
|
||
ENTRY .RNMSG
|
||
INTERN RNMSG0, RNMSG1
|
||
|
||
.RNMSG: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RNMSG0:
|
||
RNMSG1: MOVE T2,.IONIS(IO) ;LAST INPUT STATE
|
||
TXNE T2,NS.EOM ;DOES THE MONITOR STILL HAVE DATA?
|
||
SKIPLE .IONIC(IO) ;NO, DO WE STILL HAVE DATA?
|
||
STOPCD <RNMSG called with network data still outstanding>
|
||
|
||
;HIGHER-UP'S ARE IN SYNC, START UP A NEW MESSAGE
|
||
|
||
RNMSG4: PUSHJ P,RNBUF0 ;FILL UP OUR INPUT BUFFER
|
||
POPJ P, ;NETWORK DIED
|
||
PUSHJ P,RNBYT0 ;GET FIRST BYTE OF NEW MESSAGE
|
||
CAIA ;OH YEAH?
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
JUMPN M0,.POPJ## ;ERROR RETURN IF ERROR
|
||
WARNCD <Null network message returned in RNMSG4>
|
||
JRST RNMSG4 ;HO HUM GO TRY AGAIN
|
||
;RNBUF -- READ BUFFER OF NETWORK DATA FROM MONITOR
|
||
;CALL IS:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,RNBUF
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died (error code is in M0).
|
||
;
|
||
;On normal return network bytes are available via RNMSG/RNBYT.
|
||
;
|
||
;Uses T1.
|
||
|
||
ENTRY .RNBUF
|
||
INTERN RNBUF0, RNBUF1
|
||
|
||
.RNBUF: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
RNBUF0:
|
||
RNBUF1: PUSHJ P,TSAV14## ;SAVE THE T'S AS ADVERTISED
|
||
RNBUF2: SKIPN T2,.IONCH(IO) ;GET NETWORK CHANNEL
|
||
STOPCD <No network channel in RNBUF>
|
||
MOVE T1,.IOCCF(IO) ;GET CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF CHANNEL?
|
||
JRST RABUF1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET CHANNEL?
|
||
JRST RDBUF1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in RNBUF>
|
||
;HERE FOR ANF NETWORK INPUT
|
||
|
||
RABUF1: MOVX T1,.TKFIN ;FUNCTION: INPUT
|
||
MOVE M0,[3,,T1] ;TSK. ARG POINTER TO
|
||
TSK. M0, ;READ NETWORK INPUT DATA
|
||
JRST RABUF4 ;ERROR
|
||
SKIPG .IONIC(IO) ;DID WE GET ANYTHING BACK?
|
||
WARNCD <Null network buffer returned in RABUF1>,,,RABUF1
|
||
CAIE T3,.TKTDR ;DATA WITH EOM?
|
||
TDZA T1,T1 ;NO
|
||
MOVX T1,NS.EOM ;YES
|
||
MOVEM T1,.IONIS(IO) ;SET EOM FLAG FOR RNMSG
|
||
JRST .POPJ1## ;RETURN WITH NETWORK INPUT DATA
|
||
|
||
;TSK. INPUT FAILED
|
||
|
||
RABUF4: CAIE M0,TKUDW% ;"IN UUO" DIDN'T WORK?
|
||
JRST RABUF6 ;NO, MORE SERIOUS
|
||
TXNE T3,IO.ERR ;ERROR OR NON-BLOCKING?
|
||
JRST NAIOE1 ;NETWORK I/O FAILURE
|
||
|
||
;NO DATA AVAILABLE, SEE IF THERE IS A SCHEDULER TO CALL.
|
||
|
||
SKIPN .IOSCH(IO) ;IS SCHEDULER SUPPLIED?
|
||
JRST RABUF5 ;NO, GO SLEEP FOR A WHILE
|
||
|
||
;NO DATA AVAILABLE, MUST "BLOCK" THIS PROCESS VIA THE I/O SCHEDULER
|
||
|
||
MOVX T1,$SCNTI ;NETWORK INPUT WAIT
|
||
PUSHJ P,@.IOSCH(IO) ;CALL THE SCHEDULER
|
||
POPJ P, ;BEING ABORTED?
|
||
JRST RABUF1 ;OK, GO TRY AGAIN
|
||
|
||
;DON'T WANT NON-BLOCKING, AND HAVE NO SCHEDULER. JUST SLEEP UNTIL WE
|
||
;GET OUR INPUT.
|
||
|
||
RABUF5: MOVE T1,[HB.RIO+^D10000] ;WAKE ON ASYNC I/O, TIMEOUT IN 10 SEC
|
||
HIBER T1, ;WAIT FOR ACTIVITY
|
||
STOPCD ;HIBER UUOS JUST SIMPLY DO NOT FAIL
|
||
JRST RABUF1 ;TRY AGAIN
|
||
|
||
;TSK. FAILED, NOT "I/O ERROR"
|
||
|
||
RABUF6: CAIE M0,TKILS% ;MAYBE FUNNY STATE (E.G., DISCONNECTED)?
|
||
JRST NARXE1 ;TSK. UUO FAILED
|
||
JRST NARXS1 ;BAD STATE - LOOK FOR DISCONNECT REASON
|
||
;HERE FOR DECNET NETWORK INPUT
|
||
|
||
RDBUF1: MOVE T1,[<.NSFDR,,.NSAA2+1>!NS.WAI] ;NETWORK READ FUNCTION
|
||
MOVE T3,.IOCCF(IO) ;CHANNEL CONTROL FLAGS
|
||
TXNN T3,IO.NBT ;WANT THIS READ NON-BLOCKING?
|
||
SKIPE .IOSCH(IO) ;OR IS THERE AN I/O SCHEDULER LURKING ABOUT?
|
||
TXZ T1,NS.WAI ;YES TO ONE OF THE ABOVE, NON-BLOCKING READ
|
||
MOVE T3,.IONLB(IO) ;NUMBER OF BYTES WE CAN HANDLE
|
||
SKIPN T4,.IONIB(IO) ;ADDRESS OF NETWORK INPUT BUFFER
|
||
STOPCD <No network input buffer in RNBUF>
|
||
HRLI T4,(POINT 8,) ;NICE BYTE POINTER
|
||
XMOVEI M0,T1 ;ARG BLOCK POINTER TO
|
||
NSP. M0, ;READ IN NETWORK DATA
|
||
JRST NDRXE1 ;NETWORK MUST HAVE DIED
|
||
TXNN T2,NS.IDA!NS.NDA;INPUT DATA AVAILABLE?
|
||
TDZA M0,M0 ;NO
|
||
HRRZ M0,P ;YES
|
||
MOVEM M0,.IONIA(IO) ;SET NETWORK DATA AVAILABLITY FLAG
|
||
CAIGE T3,0 ;DID DATA OVERFLOW THE BUFFER?
|
||
STOPCD <NSP. receive overflowed data buffer in RNBUF>
|
||
MOVN T3,T3 ;NEGATE COUNT NOT USED
|
||
ADD T3,.IONLB(IO) ;P3:=COUNT OF BYTES RETURNED
|
||
JUMPG T3,RNBUF4 ;PROCESS RETURNED DATA
|
||
|
||
;NO DATA AVAILABLE, SEE WHAT TO DO (CALL SCHEDULER OR RETURN NON-BLOCKING)
|
||
|
||
MOVEI M0,$EINTI ;NON-BLOCKING NETWORK INPUT
|
||
MOVX T2,IO.NBT ;THE NON-BLOCKING FLAG
|
||
TDNE T2,.IOCCF(IO) ;CALLER WANT NON-BLOCKING?
|
||
POPJ P, ;YES
|
||
SKIPN .IOSCH(IO) ;IS SCHEDULER SUPPLIED?
|
||
STOPCD <Non-blocking return in RNBUF>
|
||
|
||
;NO DATA AVAILABLE, MUST "BLOCK" THIS PROCESS VIA THE I/O SCHEDULER
|
||
|
||
MOVX T1,$SCNTI ;NETWORK INPUT WAIT
|
||
PUSHJ P,@.IOSCH(IO) ;CALL THE SCHEDULER
|
||
POPJ P, ;BEING ABORTED?
|
||
JRST RNBUF1 ;TRY TRY AGAIN
|
||
|
||
;GOT SOME DATA
|
||
|
||
RNBUF4: MOVEM T3,.IONIC(IO) ;SET NEW INPUT BYTE COUNT
|
||
MOVE T4,.IONIB(IO) ;START ADDRESS OF NETWORK INPUT BUFFER
|
||
HRLI T4,(POINT 8,) ;REGENERATE INPUT BUFFER BYTE POINTER
|
||
MOVEM T4,.IONIP(IO) ;AND BYTE POINTER TOO
|
||
MOVEM T1,.IONIS(IO) ;AND THE STATE (NS.EOM)
|
||
JRST .POPJ1## ;SUCCESSFUL RETURN
|
||
;XNBYT -- SEND OUT ONE NETWORK BYTE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; MOVX T2,<byte>
|
||
; PUSHJ P,XNBYT
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the I/O CDB; and <byte> is the 8-bit byte
|
||
;to be shipped verbatim over the network channel.
|
||
;
|
||
;On error return the network died. T1 and T2 are preserved such that the
|
||
;call to XNBYT may be re-executed.
|
||
;
|
||
;On normal return the data byte has been placed in the pending output
|
||
;buffer awaiting transmission.
|
||
;
|
||
;XNBYT will automatically send message segments (transmit sans EOM) if
|
||
;network buffer fills up.
|
||
;
|
||
;Preserves all acs.
|
||
|
||
ENTRY .XNBYT
|
||
INTERN XNBYT0, XNBYT1
|
||
|
||
.XNBYT: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XNBYT0:
|
||
XNBYT1: SOSGE .IONOC(IO) ;ROOM FOR MORE DATA?
|
||
JRST XNBYT2 ;NO
|
||
IDPB T2,.IONOP(IO) ;YES, STUFF AWAY THIS BYTE
|
||
AOS (P) ;SUCCESSFUL
|
||
POPJ P, ; RETURN
|
||
;BUFFER FULL, TRY TO OUTPUT IT AND MAKE ROOM FOR MORE DATA
|
||
|
||
XNBYT2: SKIPN .IONOP(IO) ;FIRST CALL?
|
||
JRST XNBYT6 ;YES
|
||
MOVE M0,.IOCCF(IO) ;CHANNEL CONTROL FLAGS
|
||
TXNN M0,IO.DAP ;THIS CHANNEL TALKING DAPESE?
|
||
JRST XNBYT6 ;NO, IMAGE BYTE STREAM
|
||
MOVE M0,.IODPF(IO) ;YES, GET DAP CONTROL FLAGS
|
||
TXNE M0,ID.SNM ;OK TO SEGMENT NETWORK MESSAGES
|
||
JRST XNBYT5 ;YES (BUT DOUBLE-CHECK POINTERS)
|
||
STOPCD <DAP logic overran network buffer in XNBYT>
|
||
|
||
;TRANSMIT OLD BUFFER, MAKE ROOM FOR NEW DATA
|
||
|
||
XNBYT5: SKIPN .IODO3(IO) ;GOT A "LENGTH" FIELD SAVED?
|
||
SKIPE .IODO5(IO) ;OR A "BITCNT" FIELD SAVED?
|
||
STOPCD <XNBYT5-segmented DAP message with length/bitcount fields>
|
||
XNBYT6: MOVX M0,IO.ENM ;THE END-NETWORK-MESSAGE BIT
|
||
ANDCAM M0,.IOCCF(IO) ;CLEAR IN THE CDB
|
||
PUSHJ P,XNBUF0 ;SEND WHAT WE HAVE, MAKE NEW BUFFER READY
|
||
POPJ P, ;BLETCH
|
||
SKIPG .IONOC(IO) ;BETTER BE ROOM!
|
||
STOPCD <XNBUF returned successfully with a 0-length buffer in XNBYT>
|
||
JRST XNBYT1 ;NOW GO TRY AGAIN
|
||
;XNFLS -- FLUSH OUT THE NETWORK BUFFER
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XNFLS
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On successful return the network output buffer is empty and ready
|
||
;to be filled via calls to XNBYT.
|
||
;
|
||
;Preserves all acs.
|
||
|
||
ENTRY .XNFLS
|
||
INTERN XNFLS0, XNFLS1
|
||
|
||
.XNFLS: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XNFLS0:
|
||
XNFLS1: MOVE M0,.IONOC(IO) ;CURRENT NETWORK BYTE COUNT
|
||
SKIPN .IONOX(IO) ;IF PARTIALLY-OUTPUT BUFFER PENDING
|
||
CAME M0,.IONLM(IO) ;OR IF CURRENT BUFFER IS NOT EMPTY
|
||
PJRST XNBUF0 ;THEN SHIP CURRENT NETWORK DATA
|
||
JRST .POPJ1## ;NO NETWORK DATA, SUCCESSFUL BY DEFINITION
|
||
;XNEOM -- SEND ONE NETWORK MESSAGE
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XNEOM
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On successful return the current network output message has been given
|
||
;to the monitor for transmission to the remote receiver.
|
||
;
|
||
;Preserves all acs.
|
||
|
||
ENTRY .XNEOM
|
||
INTERN XNEOM0, XNEOM1
|
||
|
||
.XNEOM: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XNEOM0:
|
||
XNEOM1: MOVX M0,ID.SNM ;THE OK-TO-SEGMENT BIT
|
||
ANDCAM M0,.IODPF(IO) ;ALERT THE CONSISTENCY CHECKER (XNBYT)
|
||
MOVX M0,IO.ENM ;THE END-NETWORK-MESSAGE BIT
|
||
IORM M0,.IOCCF(IO) ;SET IN THE CDB FOR XNBUF TO SEE
|
||
PJRST XNBUF0 ;AND OUTPUT WHAT IS THERE
|
||
;XNBUF -- SEND BUFFER OF NETWORK DATA
|
||
;Call is:
|
||
;
|
||
; MOVX T1,<CDB>
|
||
; PUSHJ P,XNBUF
|
||
; error return
|
||
; normal return
|
||
;
|
||
;Where <CDB> is the address of the associated I/O CDB.
|
||
;
|
||
;On error return the network died.
|
||
;
|
||
;On successful return the current output buffer has been given to the
|
||
;monitor for transmission to the remote receiver.
|
||
;
|
||
;If the flag IO.ENM in .IOCCF(IO) has been set non-zero then the message
|
||
;will be sent as complete, otherwise it will be sent as a partial message
|
||
;segment with end of message to come later.
|
||
;
|
||
;Preserves all acs.
|
||
|
||
ENTRY .XNBUF
|
||
INTERN XNBUF0, XNBUF1
|
||
|
||
.XNBUF: PUSHJ P,.SACIO## ;SETUP I/O CDB INDEX
|
||
XNBUF0:
|
||
XNBUF1: PUSHJ P,TSAV14## ;SAVE THE T'S AS ADVERTISED
|
||
SKIPN T2,.IONCH(IO) ;FETCH NETWORK CHANNEL NUMBER
|
||
STOPCD <No network channel in XNBUF>
|
||
MOVE T1,.IOCCF(IO) ;CHANNEL CONTROL
|
||
TXNE T1,IO.ANF ;ANF NETWORK?
|
||
JRST XABUF1 ;YES
|
||
TXNE T1,IO.DCN ;DECNET NETWORK?
|
||
JRST XDBUF1 ;YES
|
||
STOPCD <Neither ANF nor DECnet in XNBUF>
|
||
;HERE FOR ANF NETWORK OUTPUT
|
||
|
||
XABUF1: MOVX T3,.TKTDR ;ASSUME DATA WITH EOM
|
||
MOVE T4,.IOCCF(IO) ;CHANNEL CONTROL FLAGS
|
||
TXNN T4,IO.ENM ;WANT EOM SENT?
|
||
MOVX T3,.TKTDT ;NO, DATA WITHOUT EOM
|
||
MOVX T1,.TKFOT ;FUNCTION: OUTPUT
|
||
MOVE M0,[3,,T1] ;TSK. ARG POINTER TO
|
||
TSK. M0, ;OUTPUT NETWORK DATA
|
||
JRST XABUF4 ;ERROR
|
||
MOVX T4,IO.ENM ;THE EOM REQUEST FLAG
|
||
ANDCAM T4,.IOCCF(IO) ;CLEAR FOR NEXT TIME
|
||
JRST .POPJ1## ;SUCCESSFUL
|
||
|
||
XABUF4: CAIE M0,TKUDW% ;"OUT UUO" DIDN'T WORK?
|
||
JRST XABUF6 ;CHECK FOR DISCONNECTED
|
||
TXNE T3,IO.ERR ;ERROR OR NON-BLOCKING?
|
||
JRST NAIOE1 ;NETWORK I/O ERROR
|
||
SETOM .IONOC(IO) ;MAKE SURE NOONE GETS CONFUSED
|
||
|
||
;CALL THE SCHEDULER
|
||
|
||
SKIPN .IOSCH(IO) ;IS THERE A SCHEDULER?
|
||
JRST XABUF5 ;NO, GO TO SLEEP FOR A WHILE
|
||
|
||
MOVX T1,$SCNTO ;NETWORK OUTPUT WAIT
|
||
PUSHJ P,@.IOSCH(IO) ;WAIT FOR SOMETHING TO HAPPEN
|
||
POPJ P, ;MUST BE ABORT
|
||
JRST XABUF1 ;TRY OUTPUTTING AGAIN
|
||
|
||
;NO SCHEDULER TO CALL. SINCE WE ALWAYS DO NON-BLOCKING TO ANF, JUST SLEEP
|
||
;FOR A WHILE.
|
||
|
||
XABUF5: MOVE T1,[HB.RIO+^D10000] ;WAKE ON ASYNC I/O, TIMEOUT IN 10 SEC
|
||
HIBER T1, ;WAIT FOR ACTIVITY
|
||
STOPCD ;HIBER UUOS ALWAYS WORK THESE DAYS!
|
||
JRST XABUF1 ;TRY AGAIN
|
||
|
||
;TSK. FAILED, NOT "I/O ERROR"
|
||
|
||
XABUF6: CAIE M0,TKILS% ;MAYBE FUNNY STATE (E.G., DISCONNECTED)?
|
||
JRST NARXE1 ;TSK. UUO FAILED
|
||
JRST NARXS1 ;BAD STATE - LOOK FOR DISCONNECT REASON
|
||
;HERE FOR DECNET NETWORK OUTPUT
|
||
|
||
XDBUF1: SKIPE T3,.IONOX(IO) ;PARTIALLY-OUTPUT BUFFER?
|
||
JRST XDBUF3 ;YES
|
||
MOVE T3,.IONLM(IO) ;SIZE OF OUTPUT [MESSAGE-SIZE-LIMITED] BUFFER
|
||
SKIPLE T2,.IONOC(IO) ;OUTPUT BUFFER FULL?
|
||
SUB T3,T2 ;NO, CALCULATE AMOUNT OF DATA PRESENT
|
||
SETOM .IONOC(IO) ;IN CASE "INTERRUPTED"
|
||
SKIPN T4,.IONOB(IO) ;ADDRESS OF OUTPUT BUFFER
|
||
STOPCD <No network output buffer in XDBUF1>
|
||
TLOA T4,(POINT 8,) ;MAKE INTO BYTE POINTER
|
||
XDBUF3: MOVE T4,.IONOY(IO) ;PICK UP SAVED BYTE POINTER
|
||
CAIGE T3,0 ;BETTER HAVE A NON-NEGATIVE LENGTH
|
||
STOPCD <Byte count negative in XDBUF3> ;***
|
||
MOVE T2,.IONCH(IO) ;NO, HAVE DATA, GET NETWORK CHANNEL NUMBER
|
||
MOVE T1,[.NSFDS,,.NSAA2+1] ;SEND FUNCTION
|
||
SKIPN .IOSCH(IO) ;GOT AN I/O SCHEDULER?
|
||
TXO T1,NS.WAI ;NO, THEN BLOCKING SEND
|
||
MOVX M0,IO.ENM ;THE END-NETWORK-MESSAGE BIT
|
||
TDNE M0,.IOCCF(IO) ;IS IT SET IN THE CHANNEL CONTROL WORD?
|
||
TXO T1,NS.EOM ;YES
|
||
XMOVEI M0,T1 ;ARG POINTER TO
|
||
NSP. M0, ;SEND BUFFER OF DATA
|
||
JRST NDRXE1 ;NETWORK MUST HAVE DIED
|
||
MOVEM T1,.IONOS(IO) ;SAVE NETWORK OUTPUT STATUS (NS.EOM)
|
||
DMOVEM T3,.IONOX(IO) ;SET COMPLETION CODE
|
||
TXNN T2,NS.IDA!NS.NDA;IS THERE INPUT PENDING?
|
||
TDZA M0,M0 ;NO
|
||
HRRZ M0,P ;YES
|
||
MOVEM M0,.IONIA(IO) ;SET INPUT AVAILABILITY FLAG
|
||
|
||
;SETUP BYTE POINTER/COUNTER FOR XNBYT
|
||
|
||
XDBUF4: JUMPN T3,XDBUF8 ;WAIT FOR COMPLETION IF NEEDED
|
||
MOVX M0,IO.ENM ;THE END-NETWORK-MESSAGE BIT
|
||
ANDCAM M0,.IOCCF(IO) ;CLEAR END OF MESSAGE REQUEST
|
||
XDBUF6: MOVE T1,.IONLM(IO) ;NETWORK [MESSAGE-SIZE-LIMITED] BUFFER SIZE
|
||
MOVEM T1,.IONOC(IO) ;SET IN CDB
|
||
MOVE T2,.IONOB(IO) ;ADDRESS OF OUTPUT BUFFER
|
||
HRLI T2,(POINT 8,) ;MAKE INTO BYTE POINTER
|
||
MOVEM T2,.IONOP(IO) ;SET IN CDB
|
||
JRST .POPJ1## ;SUCCESS RETURN
|
||
|
||
;COULDN'T OUTPUT ENTIRE BUFFER, MUST WAIT
|
||
|
||
XDBUF8: MOVEI M0,$EINTO ;NON-BLOCKING NETWORK OUTPUT STATUS
|
||
SKIPN .IOSCH(IO) ;UNLESS AN I/O SCHEDULER IS SUPPLIED
|
||
STOPCD <Non-blocking return in XDBUF8>
|
||
|
||
;CALL THE SCHEDULER
|
||
|
||
MOVX T1,$SCNTO ;NETWORK OUTPUT WAIT
|
||
PUSHJ P,@.IOSCH(IO) ;WAIT FOR SOMETHING TO HAPPEN
|
||
POPJ P, ;MUST BE ABORT
|
||
JRST XDBUF1 ;TRY OUTPUTTING AGAIN
|
||
SUBTTL Network Error Handling
|
||
|
||
;NACIE - TSK. error cleanup.
|
||
|
||
NACIE1: MOVEM T1,P4 ;SAVE TSK. ERROR CODE
|
||
PUSHJ P,NTZAP0 ;BLAST AWAY THE TSK. CHANNEL (IF ANY)
|
||
STOPCD <NTZAP failed in NACIE1>
|
||
CAIL P4,0 ;NEGATIVE ERROR CODE ILLEGAL
|
||
CAILE P4,NAERRL ;KNOWN TSK. ERROR CODE?
|
||
SETO P4, ;NO
|
||
HLRZ M0,NAERRT(P4) ;FETCH CONNECT ERROR CODE
|
||
POPJ P, ;PROPAGATE ERROR TO CALLER
|
||
|
||
|
||
|
||
;NARXE - TSK. error cleanup (sending/receiving data)
|
||
|
||
NARXE1: PUSHJ P,.SAVE4## ;RABUF/XABUF DON'T SAVE THE PEAS
|
||
MOVEM M0,P4 ;SAVE TSK. ERROR CODE
|
||
MOVE P3,.IOCCF(IO) ;PRESERVE A COPY OF CCF FLAGS
|
||
NARXE3: PUSHJ P,NTZAP0 ;BLAST AWAY THE TSK. CHANNEL
|
||
STOPCD <NTZAP failed in NARXE1>
|
||
CAIL P4,0 ;NEGATIVE ERROR CODE ILLEGAL
|
||
CAILE P4,NAERRL ;KNOWN TSK. ERROR CODE?
|
||
SETO P4, ;NO
|
||
HRRZ M0,NAERRT(P4) ;FETCH I/O ERROR CODE
|
||
NARXE7: MOVEM M0,.IOER2(IO) ;SAVE "SUB-STATE" CODE
|
||
MOVEI M0,$EINLA ;GENERIC "NETWORK LINK ABORTED"
|
||
POPJ P, ;PASS ERROR TO CALLER
|
||
|
||
|
||
|
||
;TSK. error table
|
||
|
||
$EFXXX,,$EIXXX ;-- - UNKNOWN ERROR CODE
|
||
NAERRT: $EFXXX,,$EIXXX ;00 - UNKNOWN ERROR CODE
|
||
$EFNNS,,$EIXXX ;01 - NO NETWORK (TSKSER) SUPPORT
|
||
$EFABE,,$EIABE ;02 - ARGUMENT BLOCK ERROR (TOO SHORT)
|
||
$EFPRV,,$EIPRV ;03 - NO PRIVILEGES
|
||
$EFILF,,$EIILF ;04 - ILLEGAL FUNCTION
|
||
$EFBCN,,$EIBCN ;05 - ILLEGAL CHANNEL (NOT TSK:, ETC)
|
||
$EFPBL,,$EIXXX ;06 - ILLEGAL NPD (PROCESS DESCRIPTOR)
|
||
$EFPBL,,$EIXXX ;07 - ILLEGAL NPD (TOO SHORT)
|
||
$EFWRS,,$EIWRS ;10 - ILLEGAL CHANNEL STATE FOR FUNCTION
|
||
$EFALF,,$EIALF ;11 - ALLOCATION FAILURE
|
||
$EFALF,,$EIXXX ;12 - NO FREE LINKS (SHOULDN'T HAPPEN)
|
||
$EFNSN,,$EIXXX ;13 - NO SUCH NODE
|
||
$EFXXX,,$EINLK ;14 - I/O REQUEST FAILED (NO LINK?)
|
||
|
||
NAERRL==.-NAERRT ;LENGTH OF ERROR TABLE
|
||
;NARXS - TSK. error (sending/receiving data) -- wrong state
|
||
|
||
NARXS1: PUSHJ P,.SAVE4## ;RABUF/XABUF DON'T SAVE THE PEAS
|
||
MOVEM M0,P4 ;SAVE TSK. ERROR CODE
|
||
MOVE P3,.IOCCF(IO) ;PRESERVE A COPY OF CCF FLAGS
|
||
MOVEI T1,.TKFRS ;FUNCTION: READ STATE
|
||
MOVE T2,.IONCH(IO) ;SET TASK CHANNEL
|
||
SETOB T3,T4 ;JUST TO MAKE SURE SOMETHING RETURNED
|
||
MOVE M0,[3,,T1] ;TSK. ARG POINTER TO
|
||
TSK. M0, ;READ TASK CHANNEL STATE
|
||
JRST NARXE3 ;FORGET IT, BLOW IT AWAY
|
||
CAIE T3,.TKSID ;IS THE LINK NOW "IDLE" (I.E., DISCONNECTED)?
|
||
JRST NARXE3 ;NO, STRANGE STATE, BLOW IT AWAY
|
||
MOVE M0,[4,,T1] ;YES, CAN NOW SETUP TO SAFELY
|
||
TSK. M0, ;READ LINK STATE AND DISCONNECT CODE
|
||
JRST NARXE3 ;OH WELL, WE TRIED
|
||
MOVE T2,T4 ;POSITION ANF DISCONNECT CODE
|
||
MOVEI T4,NARXST ;ANF-TO-NFT DISCONNECT TRANSLATION TABLE
|
||
PUSHJ P,.CFIND## ;TRY TO TRANSLATE THE DISCONNECT REASON
|
||
MOVEI T1,$EIUXS ;HO HUM
|
||
MOVE P4,T1 ;POSITION NFT ERROR/EXCEPTION CODE
|
||
PUSHJ P,NTZAP0 ;BLOW AWAY THE TSK CHANNEL ON OUR SIDE
|
||
JFCL ;HAH!
|
||
MOVE M0,P4 ;POSITION OUR TRANSLATED ERROR/EXCEPTION CODE
|
||
JRST NARXE7 ;RETURN ERROR CODE
|
||
|
||
|
||
|
||
;TSK. disconnect reason translation table (I/O transfer level)
|
||
|
||
NARXST: $EIDBO,,^O00 ;"NORMAL" DISCONNECT (E.G., FILOP./RELEASE)
|
||
$EIURO,,^O01 ;NO SUCH OBJECT TYPE
|
||
$EIRES,,^O02 ;NO RESOURCES/TOO MANY CONNECTS
|
||
$EIOTB,,^O03 ;OBJECT BUSY
|
||
$EIURO,,^O04 ;OBJECT NOT AVAILABLE
|
||
$EILNS,,^D03 + 100 ;NODE SHUTTING DOWN
|
||
$EIABM,,^D09 + 100 ;ABORT BY DIALOG PROCESS
|
||
$EIUID,,^D34 + 100 ;INVALID USERID/PASSWORD
|
||
$EIUAC,,^D36 + 100 ;INVALID ACCOUNT STRING
|
||
$EIIMG,,^D43 + 100 ;ERROR IN IMAGE FIELD/STRING
|
||
0
|
||
;NAIOE - TSK. error cleanup (I/O errors)
|
||
|
||
NAIOE1: MOVEM T3,.IOER3(IO) ;REMEMBER TSK I/O STATUS AS TERTIARY STATUS
|
||
PUSHJ P,NTZAP0 ;BLOW AWAY WHATEVER'S LEFT
|
||
JFCL ;HOHUM
|
||
MOVE T3,.IOER3(IO) ;RETRIEVE TSK I/O STATUS WORD
|
||
TXCE T3,IO.IMP ;"IMPROPER MODE"
|
||
MOVEI M0,$EIIMP ;YUP
|
||
TXCE T3,IO.DER ;"DEVICE ERROR"
|
||
MOVEI M0,$EIDEV ;YUP
|
||
TXCE T3,IO.DTE ;"DATA ERROR"
|
||
MOVEI M0,$EIDAT ;YUP
|
||
TXCE T3,IO.BKT ;"BLOCK TOO LARGE"
|
||
MOVEI M0,$EIBKT ;YUP
|
||
TXCE T3,IO.ERR ;ALL ERROR BITS LIT?
|
||
JRST NAIOE4 ;NO, SET ERROR AS TRANSLATED
|
||
MOVEI M0,$EIUCM ;*** YEAH, CALL IT "NO COMMUNICATION"
|
||
;*** SHOULD DO DEVOP. AND TRANSLATE!
|
||
;*** BUT THIS IS ONLY MEANINGFUL NETWORK
|
||
;*** ERROR, SO . . .
|
||
NAIOE4: MOVEM M0,.IOER2(IO) ;SET "NLA" SUBSTATE AS SECONDARY STATUS
|
||
MOVEI M0,$EINLA ;RETURN A "LINK ABORTED" ERROR
|
||
POPJ P, ;TO WHOMEVER...
|
||
;NDCIE - NSP. error cleanup, call with P2/Channel number if any
|
||
|
||
NDCIE1: CAIE M0,P1 ;POSSIBLY THE "UNIMPLEMENTED" ERROR RETURN?
|
||
JRST NDCXE1 ;NO
|
||
MOVX T1,%CNST2 ;YES
|
||
GETTAB T1, ;GET MONITOR "CONFIG" FLAGS
|
||
STOPCD <GETTAB(%CNST2) failed in NDCIE1>
|
||
TXNE T1,ST%D36 ;IS DECNET-36 IMPLEMENTED?
|
||
JRST NDCXE1 ;YES
|
||
MOVEI M0,$EFNNS ;NO, THEN ERROR IS "NO NETWORK SOFTWARE"
|
||
POPJ P, ;AND THAT IS THAT
|
||
|
||
NDCXE1: MOVEM M0,P4 ;PRESERVE NSP. ERROR CODE
|
||
HRRZM P2,.IONCH(IO) ;STORE CHANNEL IF THE MONITOR GAVE US ONE
|
||
PUSHJ P,NTZAP0 ;AND BLAST IT TO SMITHEREENS
|
||
STOPCD <NTZAP failed in NDCIE1>
|
||
CAIL P4,0 ;NEGATIVE ERROR CODE UNKNOWN
|
||
CAILE P4,NDERRL ;KNOWN NSP ERROR CODE?
|
||
SETO P4, ;NO
|
||
HLRZ M0,NDERRT(P4) ;FETCH CONNECT ERROR CODE
|
||
POPJ P, ;PASS ERROR TO CALLER
|
||
|
||
|
||
|
||
;NDRXE - NSP. error cleanup (sending/receiving data)
|
||
|
||
NDRXE1: MOVEM M0,P4 ;PRESERVE NSP. ERROR CODE
|
||
MOVE P3,.IOCCF(IO) ;PRESERVE COPY OF CHANNEL CONTROL FLAGS
|
||
PUSHJ P,NTZAP0 ;BLAST NSP CHANNEL TO SMITHEREENS
|
||
STOPCD <NTZAP failed in NDRXE1>
|
||
CAIL P4,0 ;NEGATIVE ERROR CODE UNKNOWN
|
||
CAILE P4,NDERRL ;KNOWN NSP ERROR CODE?
|
||
SETO P4, ;NO
|
||
HRRZ M0,NDERRT(P4) ;FETCH ERROR CODE
|
||
MOVEM M0,.IOER2(IO) ;SAVE "SUB-STATE" CODE
|
||
MOVEI M0,$EINLA ;GENERIC "NETWORK LINK ABORTED"
|
||
POPJ P, ;PASS ERROR TO CALLER
|
||
;NSP. error table
|
||
|
||
$EFXXX,,$EIXXX ;-- - UNKNOWN ERROR CODE
|
||
NDERRT: $EFXXX,,$EIXXX ;00 - UNKNOWN ERROR CODE
|
||
$EFABE,,$EIABE ;01 - ARGUMENT BLOCK ERROR
|
||
$EFALF,,$EIALF ;02 - ALLOCATION FAILURE
|
||
$EFBCN,,$EIBCN ;03 - BAD CHANNEL NUMBER
|
||
$EFBFT,,$EIBFT ;04 - BAD FORMAT TYPE IN PROCESS BLOCK
|
||
$EFCFE,,$EICFE ;05 - CONNECT BLOCK FORMAT ERROR
|
||
$EFIDL,,$EIIDL ;06 - INTERRUPT DATA TOO LONG
|
||
$EFIFM,,$EIIFM ;07 - ILLEGAL FLOW CONTROL MODE
|
||
$EFILF,,$EIILF ;10 - ILLEGAL NSP. FUNCTION CODE
|
||
$EFJQX,,$EIJQX ;11 - JOB QUOTA EXHAUSTED
|
||
$EFLQX,,$EILQX ;12 - LINK QUOTA EXHAUSTED
|
||
$EFNCD,,$EINCD ;13 - NO CONNECT DATA TO READ
|
||
$EFPIO,,$EIPIO ;14 - PERCENTAGE INPUT OUT OF BOUNDS
|
||
$EFPRV,,$EIPRV ;15 - NO PRIVILEGES
|
||
$EFSTB,,$EISTB ;16 - SEGMENT SIZE TOO BIG
|
||
$EFNSN,,$EINSN ;17 - UNKNOWN NODE NAME
|
||
$EFUXS,,$EIUXS ;20 - UNEXPECTED STATE: UNSPECIFIED
|
||
$EFWNA,,$EIWNA ;21 - WRONG NUMBER OF ARGUMENTS
|
||
$EFWRS,,$EIWRS ;22 - LINK IN WRONG STATE
|
||
$EFCBL,,$EICBL ;23 - CONNECT BLOCK LENGTH ERROR
|
||
$EFPBL,,$EIPBL ;24 - PROCESS BLOCK LENGTH ERROR
|
||
$EFSBL,,$EISBL ;25 - STRING BLOCK LENGTH ERROR
|
||
$EFUDS,,$EIUDS ;26 - UNEXPECTED STATE: DISCONNECT SENT
|
||
$EFUDC,,$EIUDC ;27 - UNEXPECTED STATE: DISCONNECT CONFIRMED
|
||
$EFUCF,,$EIUCF ;30 - UNEXPECTED STATE: NO CONFIDENCE
|
||
$EFULK,,$EIULK ;31 - UNEXPECTED STATE: NO LINK
|
||
$EFUCM,,$EIUCM ;32 - UNEXPECTED STATE: NO COMMUNICATION
|
||
$EFUNR,,$EIUNR ;33 - UNEXPECTED STATE: NO RESOURCES
|
||
$EFRBO,,$EIRBO ;34 - CONNECT REJECTED: REJECTED BY OBJECT
|
||
$EFDBO,,$EIDBO ;35 - DISCONNECTED BY OBJECT
|
||
$EFRES,,$EIRES ;36 - CONNECT REJECTED: NO RESOURCES
|
||
$EFUXN,,$EIUXN ;37 - CONNECT REJECTED: UNKNOWN NAME
|
||
$EFRNS,,$EIRNS ;40 - CONNECT REJECTED: NODE SHUT DOWN
|
||
$EFURO,,$EIURO ;41 - CONNECT REJECTED: UNRECOGNIZED OBJECT
|
||
$EFIOF,,$EIIOF ;42 - CONNECT REJECTED: BAD OBJECT NAME FORMAT
|
||
$EFOTB,,$EIOTB ;43 - CONNECT REJECTED: OBJECT FULL/BUSY
|
||
$EFABM,,$EIABM ;44 - CONNECT REJECTED: ABORTED BY MANAGEMENT
|
||
$EFABO,,$EIABO ;45 - CONNECT REJECTED: ABORTED BY OBJECT
|
||
$EFINF,,$EIINF ;46 - CONNECT REJECTED: INVALID NODE NAME FORMAT
|
||
$EFLNS,,$EILNS ;47 - CONNECT REJECTED: LOCAL NODE SHUT DOWN
|
||
$EFUID,,$EIUID ;50 - CONNECT REJECTED: INVALID USERID
|
||
$EFNRO,,$EINRO ;51 - CONNECT REJECTED: NO RESPONSE FROM OBJECT
|
||
$EFNUR,,$EINUR ;52 - NODE UNREACHABLE
|
||
$EFNLK,,$EINLK ;53 - NO LINK
|
||
$EFDSC,,$EIDSC ;54 - DISCONNECT COMPLETE
|
||
$EFIMG,,$EIIMG ;55 - IMAGE FIELD TOO LONG
|
||
$EFUAC,,$EIUAC ;56 - CONNECT REJECTED: INVALID ACCOUNT DATA
|
||
$EFBCF,,$EIBCF ;57 - BAD COMBINATION OF FLAGS
|
||
$EFADE,,$EIADE ;60 - ADDRESS CHECK
|
||
|
||
NDERRL==.-NDERRT ;LENGTH OF ERROR TRANSLATION TABLE
|
||
SUBTTL Routine to type out descriptive messages for DAP msg flags.
|
||
|
||
;.TFLAG -- TYPE OUT ALL MESSAGES DESCRIBING DAP FLAGS IN A DAP MSG FIELD
|
||
;CALL IS:
|
||
;
|
||
; MOVE P1,<IDX>
|
||
; MOVE P2,<FLG1>
|
||
; MOVE P3,<FLG2>
|
||
; PUSHJ P,.TFLAG
|
||
;
|
||
;Where <IDX> is the current RDDAP (for rcv) or XDDAP (for xmt) execution index.
|
||
; <FLG1> is the first word of flag bits (i.e. 0 to 34)
|
||
; <FLG2> is the second word of flag bits (i.e. 35 to 70)
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
|
||
.TFLAG: PUSHJ P,TSAV14## ;SAVE T1 - T4
|
||
PUSHJ P,.SAVE4## ;SAVE P1 - P4
|
||
MOVE T2,P2 ;GET FIRST WORD OF FLAG BITS
|
||
MOVEI P4,^D0 ;
|
||
PUSHJ P,.TFLG0 ;INDEX INTO DFVIDX AND TYPE MESSAGES
|
||
MOVE T2,P3 ;GET SECOND WORD OF FLAG BITS
|
||
MOVEI P4,^D35 ;
|
||
PUSHJ P,.TFLG0 ;INDEX INTO DFVIDX AND TYPE MESSAGES
|
||
POPJ P, ;RETURN
|
||
|
||
.TFLG0: JFFO T2,.+2 ;PUT BIT POSITION OF FLAG IN T2 INTO T3
|
||
POPJ P, ;NO MORE FLAGS, SO RETURN
|
||
MOVSI T4,400000 ;LIGHT BIT AT BIT POSITION ZERO IN T4
|
||
MOVN T3,T3 ;MOVE BIT IN T4 TO SAME POSITION AS FLAG IN T2
|
||
LSH T4,(T3) ; . . .
|
||
TDZ T2,T4 ;ZERO FLAG BIT IN T2 SO WE IGNORE NEXT TIME
|
||
|
||
MOVN T3,T3 ;MAKE T3 POSITIVE AGAIN
|
||
|
||
> ;END $TRACE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
;THE NEXT PIECE OF MATHEMATICS TRANSLATES THE -10 BIT TO THE CORRESPONDING
|
||
;DAP BIT. SEE THE DEFINITION OF THE XF MACRO IN SWIL FOR THE EQUATION. IT IS
|
||
;INVARIANT SO THAT IT TRANSLATES A -10 BIT TO A DAP BIT AND VICE VERSA.
|
||
|
||
$TRACE <
|
||
IDIVI T3,^D7 ;MAKE T3 AN OFFSET WITHIN PART OF DFVMSG WANTED
|
||
IMULI T3,^D7 ; . . .
|
||
ADDI T3,^D6 ; . . .
|
||
SUBI T3,(T4) ; . . .
|
||
ADD T3,P4 ; . . .
|
||
HLRE T1,DFVIDX(P1) ;GET MAX BIT DEFINED FOR THIS FLAG
|
||
JUMPL T1,.TFLG1 ;OUR MAXIMUM MUST BE .GE. 0 TO MAKE SENSE
|
||
CAMLE T3,T1 ;WITHIN LIMIT OF SPEC. DEFINED BY DAP MACRO ?
|
||
JRST .TFLG2 ;NO, COMPLAIN TO USER
|
||
PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TTABC## ;TAB ACROSS AGAIN
|
||
HRRZ T1,DFVIDX(P1) ;GET ADR. OF ADR. OF MSG TABLE FOR FLAG FIELD
|
||
ADDI T3,(T1) ;GET ADR. OF ADR. OF MSG FOR THIS FLAG
|
||
MOVE T1,(T3) ;GET MSG ADR. IN T1
|
||
PUSHJ P,.TSTRG## ;TYPE THE MESSAGE FOR THIS FLAG
|
||
PUSHJ P,.TCRLF## ;MAKE IT NEAT
|
||
JRST .TFLG0 ;RETURN FOR ANY REMAINING FLAG BITS
|
||
|
||
.TFLG1: PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TTABC## ;TAB AGAIN
|
||
MOVEI T1,[ASCIZ \?? Error in SWINET - found neg. maximum flag value ??\]
|
||
JRST .TFLG3 ;GO TELL USER
|
||
|
||
.TFLG2: PUSHJ P,.TTABC## ;TAB ACROSS
|
||
PUSHJ P,.TTABC## ;TAB AGAIN
|
||
MOVEI T1,[ASCIZ \?? Flag value \]
|
||
PUSHJ P,.TSTRG## ;TYPE FIRST PART OF ERROR MESSAGE
|
||
MOVE T1,T3 ;GET THE ERRONEOUS VALUE IN T1
|
||
PUSHJ P,.TDECW## ;TELL USER THE ERRONEOUS VALUE
|
||
PUSHJ P,.TDOT## ;TYPE A DECIMAL POINT
|
||
MOVEI T1,[ASCIZ \ not within DAP spec. for this field ??\]
|
||
.TFLG3: PUSHJ P,.TSTRG## ;TYPE END OF ERROR MESSAGE
|
||
PUSHJ P,.TCRLF## ;MAKE LINE NEAT
|
||
POPJ P, ;RETURN NOW AND ABANDON REST OF FLAGS
|
||
|
||
> ;END $TRACE
|
||
SUBTTL Routine to type out message describing value field
|
||
|
||
;.TVALU -- TYPE OUT DESCRIPTION OF VALUE FIELD
|
||
;CALL IS:
|
||
;
|
||
; DMOVE T3,<VAL>
|
||
; PUSHJ P,.TVALU
|
||
;
|
||
;Where <VAL> is a positive integer in T3 and T4
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
|
||
.TVALU: JUMPN T3,.POPJ## ;JUMP IF NUMBER MUCH TOO BIG FOR US
|
||
PUSHJ P,TSAV13 ;SAVE T1 - T3
|
||
MOVE T2,DFVIDX(P1) ;PICK UP POSSIBLE AOBJN POINTER INTO DFVMSG
|
||
HLRE T3,T2 ;GET EXPECTED NEGATIVE PART OF AOBJN POINTER
|
||
JUMPGE T3,.POPJ## ;THIS VALUE HAS NO DESCRIPTIVE MESSAGE
|
||
PUSHJ P,.TSPAC## ;SPACE ACROSS
|
||
HLRZ T1,(T2) ;GET A LEGAL VALUE FOR THIS FIELD
|
||
CAMN T1,T4 ;SAME AS THE VALUE FOUND IN DAP PACKET ?
|
||
JRST .TVAL0 ;YES, GO TYPE OUT DESCRIPTIVE MESSAGE
|
||
AOBJN T2,.-3 ;NO, LOOP THROUGH ALL POSSIBLE VALUES FOR FIELD
|
||
MOVEI T1,[ASCIZ \?? Value not legal for this field ??\]
|
||
SKIPA ;TELL BAD NEWS TO USER
|
||
.TVAL0: HRRZ T1,(T2) ;FOUND VALUE, PUT ADDRESS OF MESSAGE IN T1
|
||
PUSHJ P,.TSTRG## ;TYPE THE MESSAGE
|
||
POPJ P, ;RETURN
|
||
|
||
> ;END $TRACE
|
||
SUBTTL Routine to type out one 8 bit byte in hex.
|
||
|
||
;.THEXB -- TYPE OUT ONE HEX BYTE
|
||
;CALL IS:
|
||
;
|
||
; LDB T2,<PTR>
|
||
; PUSHJ P,.THEXB
|
||
;
|
||
;Where <PTR> is a pointer to an 8 bit byte.
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
|
||
.THEXB: PUSHJ P,TSAV14 ;SAVE T1 - T4
|
||
MOVEM T2,T4 ;SAVE T2 IN A SAFE PLACE
|
||
LDB T1,[POINT 4,T4,31] ;GET LEFT HALF OF BYTE
|
||
MOVEI T3,^D16 ;SET RADIX ^D16 FOR CALL TO .TRDXW
|
||
PUSHJ P,.TRDXW## ;OUTPUT THAT IN HEX
|
||
LDB T1,[POINT 4,T4,35] ;GET RIGHT HALF OF BYTE
|
||
MOVEI T3,^D16 ;SET RADIX ^D16 FOR CALL TO .TRDXW
|
||
PUSHJ P,.TRDXW## ;OUTPUT THAT IN HEX
|
||
POPJ P, ;RETURN
|
||
|
||
> ;END $TRACE
|
||
SUBTTL TRCFIL - Examine .JBOPC and determine DAP trace type-out rtne.
|
||
|
||
;TRCFIL -- DETERMINE DAP TRACE OUTPUT ROUTINE
|
||
;CALL IS:
|
||
;
|
||
; PUSHJ P,TRCFIL
|
||
; always return here
|
||
;
|
||
;On return T1 contains address of DAP trace type-out routine.
|
||
;
|
||
;Location .JBOPC is examined and the type-out routine determined thus:
|
||
; .JBOPC/ 0 type-out rtne is .POPJ## i.e. type-out is discarded
|
||
; .JBOPC/ 1 type-out rtne is 0 i.e. type-out goes to attached TTY:
|
||
; .JBOPC/ 2 type-out rtne is DAPTRC i.e. type-out goes to DSK:DAPTRC.LST
|
||
;
|
||
;Preserves all AC's
|
||
|
||
$TRACE <
|
||
|
||
TRCFIL: PUSHJ P,TSAV14## ;SAVE T1 - T4
|
||
MOVEI T1,.POPJ## ;ASSUME ZERO IN .JBOPC MEANING NO TRACE WANTED
|
||
MOVEM T1,-T1(P) ; . . .
|
||
SKIPN T2,.JBOPC ;IS .JBOPC ZERO ?
|
||
POPJ P, ;YES, NO TRACE WANTED SO .POPJ## IS TRACE RTNE
|
||
|
||
CLEARM -T1(P) ;NO, ASSUME 1 IN .JBOPC MEANING TRACE TO TTY
|
||
CAIN T2,1 ;IS .JBOPC 1 ?
|
||
POPJ P, ;YES, TRACE TO TTY WANTED SO 0 IS TRACE RTNE
|
||
CAIE T2,2 ;NO, IS .JBOPC 2 FOR TRACE TO 'DAPTRC.LST' ?
|
||
WARNCD <.JBOPC should be 0=no trace, 1=TTY trace, 2=DAPTRC.LST>
|
||
|
||
SKIPL TRCOPN ;IS DAPTRC.LST OPEN ALREADY ?
|
||
JRST TRCFL1 ;NO, GO ENTER DAPTRC.LST FOR OUTPUT
|
||
MOVEI T1,DAPTRC ;YES, GET THE OUTPUT TRACE ROUTINE
|
||
MOVEM T1,-T1(P) ;RETURN OUTPUT TRACE RTNE IN T1
|
||
POPJ P, ;RETURN
|
||
|
||
TRCFL1: MOVE T1,[.FOPAT+1,,TRCFLP] ;[LENGTH,,ADDR] OF FILOP. BLOCK
|
||
FILOP. T1, ;ENTER 'DAPTRC.LST' FOR WRITING
|
||
STOPCD <FILOP. failed in TRCFIL, tracing to TTY>,,,.POPJ##
|
||
|
||
CLEAR T1, ;REQUIRE MANAGED MEMORY ALLOCATION
|
||
MOVE T2,[3,,200] ;REQUIRE 3 BUFFERS EACH 200 WORDS
|
||
MOVEI T4,TRCBHD ;ADDRESS BUFFER RING HEADER BLOCK
|
||
PUSHJ P,IOBFA1 ;ALLOCATE BUFFERS AND LINK TOGETHER
|
||
STOPCD <Call to IOBFA1 failed in TRCFIL, tracing to TTY>,,,.POPJ##
|
||
|
||
MOVEI T1,DAPTRC ;GET THE OUTPUT TRACE ROUTINE
|
||
MOVEM T1,-T1(P) ;PLACE OUTPUT TRACE RTNE IN T1
|
||
SETOM TRCOPN ;FLAG TRACE FILE OPEN FOR OUTPUT
|
||
POPJ P, ;RETURN
|
||
|
||
> ;END $TRACE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
$TRACE <
|
||
|
||
DAPTRC: SOSGE TRCBHD+.BFCTR ;ROOM LEFT IN OUTPUT BUFFER ?
|
||
JRST DAPTR1 ;NO, EMPTY A BUFFER
|
||
IDPB T1,TRCBHD+.BFPTR ;YES, DEPOSIT CHAR IN OUTPUT BUFFER
|
||
POPJ P, ;RETURN
|
||
|
||
DAPTR1: PUSHJ P,TSAV13## ;SAVE T1 - T3
|
||
LDB T3,[POINTR TRCFLP+.FOFNC,FO.CHN] ;GET CHANNEL FROM ENTER
|
||
LSH T3,^D18 ;POSITION IN CORRECT PLACE
|
||
HRRI T3,.FOOUT ;NEED THE OUTPUT FILOP. FUNCTION
|
||
MOVE T2,[XWD 1,T3] ;OUTPUT THE BUFFER TO 'DAPTRC.LST'
|
||
FILOP. T2, ; . . .
|
||
STOPCD <FILOP. failed to write buffer to DAPTRC.LST in DAPTRC>
|
||
JRST DAPTRC ;TRY AGAIN
|
||
|
||
> ;END $TRACE
|
||
|
||
;CONTINUED ON NEXT PAGE
|
||
;CONTINUED FROM PREVIOUS PAGE
|
||
|
||
$TRACE < XLIST ;LITERALS
|
||
LIT
|
||
LIST
|
||
RELOC ;SWITCH TO LOSEG
|
||
|
||
TRCFLP: FO.PRV+FO.ASC+.FOWRT ;WANT MONITOR ASSIGNED CHAN TO WRITE FILE
|
||
.IOASC ;WANT ASCII MODE
|
||
'DSK ' ;WANT GENERIC DISK
|
||
TRCBHD,,0 ;ADDR OF ^D3 WORD BUFFER RING HEADER BLOCK
|
||
0 ;NO BUFFERS TO BE ALLOCATED YET
|
||
TRCENT ;ADDR OF ENTER BLOCK
|
||
0 ;PATH (DEFAULT)
|
||
|
||
TRCBHD: BLOCK 3 ;BUFFER RING HEADER BLOCK
|
||
|
||
TRCENT: .RBEXT ;NO. OF ARGUMENTS FOLLOWING
|
||
0 ;ENTER BLOCK PPN/PATH (DEFAULT)
|
||
'DAPTRC' ;FILE NAME
|
||
'LST ' ;EXTENSION
|
||
|
||
TRCOPN: BLOCK 1 ;FLAG -1 IF TRACE FILE IS OPEN
|
||
|
||
> ;END $TRACE
|
||
|
||
END
|
||
|