Google
 

Trailing-Edge - PDP-10 Archives - tops10_tools_bb-fp64b-sb - 10,7/cisnup/citatl.mac
There are no other files named citatl.mac in the archive.
TITLE	CITATL - Report CI Traffic
SUBTTL	Joseph A. Dziedzic /JAD	3-Aug-88


	SEARCH	JOBDAT, MACTEN, UUOSYM, SCAPRM, MSCPAR
	.REQUE	REL:SCAN
	TWOSEG	400000
	SALL

	LOC	.JBVER		;GET TO .JBVER
	EXP	1		;STORE A VERSION NUMBER
	RELOC
	SUBTTL	Definitions

;ACs (compatible with .SCAN)

	T1=1			;4 TEMPORARY ACS
	T2=2
	T3=3
	T4=4
	P1=5			;4 PRESERVED ACS
	P2=6
	P3=7
	P4=10
	P=17			;PUSHDOWN LIST POINTER

;I/O channels

	DAT==1			;DATA FILE CHANNEL
	LOG==2			;LOG FILE CHANNEL

;KLIPA CI operation codes

	OP.SDG==1		;SEND DATAGRAM
	OP.SMS==2		;SEND MESSAGE
	OP.RCF==3		;CONFIRM RECEIVED
	OP.MCR==4		;MAINTENANCE CONFIRM RECEIVED
	OP.RID==5		;REQUEST ID
	OP.RRS==6		;RESET REMOTE SYSTEM
	OP.SRS==7		;START REMOTE SYSTEM
	OP.RD0==10		;REQUEST DATA ON QUEUE 0
	OP.RD1==11		;REQUEST DATA 1
	OP.RD2==12		;REQUEST DATA 2
	OP.IDR==13		;ID RECEIVED
	OP.LPB==15		;SEND/RECEIVE LOOPBACK
	OP.RMD==16		;REQUEST MAINTENANCE DATA
	OP.SDT==20		;SEND DATA
	OP.RDT==21		;RETURN DATA (DATREC)
	OP.SMD==22		;SEND MAINTENANCE DATA
	OP.MDR==23		;MAINTENANCE DATA RECEIVED
	OP.CKT==200		;SET VIRTUAL CIRCUIT
	OP.SPT==201		;SET STATISTICS COUNTER
	OP.RCT==202		;READ STATISTICS COUNTER
	OP.RRG==203		;READ REGISTER
	OP.WRG==204		;WRITE REGISTER
	OP.CLB==205		;CLOSE BUFFER
	OP.RMT==40		;ON IN REMOTELY GENERATED RESPONSES

DEFINE	PRINT(TXT),<
	SKIPA	T1,[[ASCIZ ^TXT^]]
	SKIPA
	PUSHJ	P,.TSTRG##
>; END DEFINE
	SUBTTL	Tracking Log File Format

;The log file has two sections.  The first contains a number of
;blocks which contain information needed to convert a Connect ID
;to a Process Name string.  The second contains copies of all CI
;messages sent/received by the KLIPA software in the -10 (note
;that the KLIPA sends/receives some messages without the knowledge
;of the -10).
;*** These definitions should match CISNUP ***

;CID info block format

	.ORG	0

.CILNK:!BLOCK	1		;LINK WORD (ONLY USED BY CITATL)
.CINOD:!BLOCK	1		;CI NODE NUMBER
.CICID:!BLOCK	1		;CONNECT ID
.CIPNS:!BLOCK	C%PNLW		;PROCESS NAME STRING
.CILEN:!			;LENGTH OF INFO BLOCK

	.ORG


;Track record format

	.ORG	0
.TKLEN:!BLOCK	1		;<R/X FLAG>B0 + <CPU>B3 + <OUR NODE>B11 +
				; <LENGTH OF ENTRY>B35
.TKDTM:!BLOCK	1		;SYSTEM DATE IN INTERNAL FORMAT
.TKPKT:!			;START OF PACKET
				;MAX OF C%DGSZ/C%MGSZ WORDS HERE
	.ORG
	SUBTTL	Data Storage

	RELOC	0		;TO IMPURE SEGMENT

ALPHA:!				;FIRST LOCATION TO ZERO ON RESTART
PDLIST:	BLOCK	100		;PUSHDOWN LIST

IBUF:	BLOCK	3		;BUFFER CONTROL BLOCK FOR DATA FILE
OBUF:	BLOCK	3		;BUFFER CONTROL BLOCK FOR LOG FILE

CIDBUF:	BLOCK	.CILEN		;BUFFER FOR A CID ENTRY
CIDLST:	BLOCK	1		;ADDRESS OF CID ENTRY LIST

PACKET:	BLOCK	1000		;SPACE TO STORE WORKING PACKET
OMEGA==.-1			;LAST LOCATION TO ZERO ON RESTART

	RELOC
	SUBTTL	Initialization

START:	JFCL			;NO CCL ENTRY
	RESET			;RESET THE WORLD
	MOVE	P,[IOWD 100,PDLIST] ;SET UP A STACK
	MOVE	T1,[XWD ALPHA, ALPHA+1]
	SETZM	ALPHA		;CLEAR OUT IMPURE STORAGE
	BLT	T1,OMEGA	;BLIT!

	HLRZ	T1,.JBSA	;GET ORIGINAL CORE SIZE
	MOVEM	T1,.JBFF	;RESET IN CASE OF RESTART

	MOVEI	T1,TYPOUT	;GET OUTPUT ROUTINE ADDRESS
	PUSHJ	P,.TYOCH##	;INITIALIZE .TOUTS

	OPEN	DAT,[EXP .IOIMG, SIXBIT /DSK/, EXP <XWD 0,IBUF>] ;OPEN A CHANNEL
	  HALT	.		;ERROR
	MOVE	T1,['CISNUP']	;FILE
	MOVSI	T2,'DAT'	;EXTENSION
	SETZB	T3,T4		;ZEROES
	LOOKUP	DAT,T1		;FIND THE FILE
	  JRST	FNFERR		;ERROR?

	PUSHJ	P,BLDCID	;BUILD LIST OF CONNECTION IDS FROM LOG FILE

	OPEN	LOG,[EXP .IOASC, SIXBIT /DSK/, EXP <XWD OBUF,0>] ;OPEN A CHANNEL
	  HALT	.		;ERROR
	MOVE	T1,['CITATL']	;FILE
	MOVSI	T2,'LOG'	;EXTENSION
	SETZB	T3,T4		;ZEROES
	ENTER	LOG,T1		;CREATE THE FILE
	  JRST	FNFERR		;ERROR?
;	Fall into main loop

	MOVEI	P1,PACKET+.TKPKT ;LOAD HANDY REFERENCE AC
LOOP:	PUSHJ	P,REDPKT	;READ A PACKET FROM THE LOG FILE
	  JRST	DONE		;ALL DONE
	PRINT	<
Node >
	LDB	T1,PKYNOD	;EXTRACT FROM PACKET
	PUSHJ	P,.TDECW##	;PRINT IT
	MOVE	P2,PACKET+.TKLEN ;GET MISC INFO FIELD
	TXNN	P2,1B0		;RECEIVED?
	PRINT	<, received on CPU>
	TXNE	P2,1B0		;TRANSMITTED?
	PRINT	<, transmitted by CPU>
	LDB	T1,[POINT 3,P2,3] ;GET CPU NUMBER
	ADDI	T1,"0"		;CONVERT TO A DIGIT
	PUSHJ	P,.TCHAR##	;TYPE IT
	PRINT	< at >
	MOVE	T1,PACKET+.TKDTM ;GET SYSTEM DATE/TIME
	PUSHJ	P,.TDTTM##	;TYPE DATE AND TIME
	PUSHJ	P,.TCRLF##	;END LINE
	LDB	P2,PKYOP	;GET OPCODE
	PRINT	<  PPD byte: >
	LDB	T1,[POINT 8,4(P1),7] ;GET PPD BYTE
	MOVEI	T3,3		;FIELD WIDTH
	PUSHJ	P,.TOCTJ##	;TYPE IT
	PRINT	<  Status: >
	LDB	T1,PKYSTS	;GET THE BYTE
	MOVEI	T3,3		;FIELD WIDTH
	PUSHJ	P,.TOCTJ##	;TYPE IT
	PRINT	<  Opcode: >
	MOVE	T1,P2		;GET OPCODE
	TRZ	T1,OP.RMT	;CLEAR REMOTE FLAG
	MOVEI	T3,3		;FIELD WIDTH
	PUSHJ	P,.TOCTJ##	;TYPE IT
	PRINT	< (>
	MOVE	T1,P2		;GET A COPY OF OPCODE
	TRZ	T1,OP.RMT	;CLEAR REMOTE FLAG
	MOVE	T1,OPNAME(T1)	;GET TEXT FOR OPCODE
	PUSHJ	P,.TSTRG##	;TYPE IT
	MOVEI	T1,")"
	PUSHJ	P,.TCHAR##
	TRNE	P2,OP.RMT	;REMOTE FLAG ON?
	PRINT	< (remotely generated)>
	PUSHJ	P,.TCRLF##	;END LINE
	MOVE	T1,P2		;GET A COPY OF OPCODE
	TRZ	T1,OP.RMT	;STRIP REMOTE BIT
	CAIE	T1,OP.SMS	;MESSAGE?
	CAIN	T1,OP.SDG	;OR DATAGRAM?
	SKIPA			;YES
	JRST	LOOP		;NO, NOTHING FURTHER WE CAN ADD
	PRINT	<    SCA message type: >
	LDB	P3,[POINT 8,.MHTYP(P1),7] ;GET LSB OF MESSAGE TYPE
	MOVE	T1,P3		;GET A COPY
	PUSHJ	P,.TOCTW##	;PRINT IT
	PRINT	< (>
	MOVE	T1,MSGTYP(P3)	;GET STRING FOR MESSAGE TYPE
	PUSHJ	P,.TSTRG##	;TYPE IT
	MOVEI	T1,")"
	PUSHJ	P,.TCHAR##
	PUSHJ	P,.TCRLF##	;END WITH LINE
	LDB	P3,PKYNOD	;GET DESTINATION NODE FROM PACKET
	PRINT	<    Source: >
	MOVE	T1,.MHSCI(P1)	;GET SOURCE CONNECT ID
	TRNE	P2,OP.RMT	;REMOTELY GENERATED?
	SKIPA	T2,P3		;YES, USE NODE NUMBER FROM PACKET
	LDB	T2,[POINT 8,PACKET+.TKLEN,11] ;NO, GET LOCAL NODE NUMBER
	PUSHJ	P,TYPCID	;TYPE IT
	JUMPE	T1,LOOP1	;JUMP IF NO MATCHING CID FOUND
	MOVE	T1,.CIPNS(T1)	;GET FIRST WORD OF STRING
	CAMN	T1,[BYTE (8)"M","S","C","P"] ;IS IT MSCP-RELATED?
	TLO	P2,400000	;YES, REMEMBER
LOOP1:	PRINT	<   Destination: >
	MOVE	T1,.MHDCI(P1)	;GET DESTINATION CONNECT ID
	TRNN	P2,OP.RMT	;REMOTELY GENERATED?
	SKIPA	T2,P3		;NO, USE NODE NUMBER FROM PACKET
	LDB	T2,[POINT 8,PACKET+.TKLEN,11] ;YES, GET LOCAL NODE NUMBER
	PUSHJ	P,TYPCID	;TYPE IT
	JUMPE	T1,LOOP2	;JUMP IF NO MATCHING CID FOUND
	MOVE	T1,.CIPNS(T1)	;GET FIRST WORD OF STRING
	CAMN	T1,[BYTE (8)"M","S","C","P"] ;IS IT MSCP-RELATED?
	TLO	P2,400000	;YES, REMEMBER
LOOP2:	PUSHJ	P,.TCRLF##	;END LINE
	LDB	T1,[POINT 8,.MHTYP(P1),7] ;GET LSB OF MESSAGE TYPE
	CAIE	T1,.STAMG	;APPLICATION MESSAGE
	CAIN	T1,.STADG	; OR DATAGRAM?
	TLZN	P2,400000	;YES, WAS THIS SOME SORT OF MSCP PACKET?
	JRST	LOOP5		;NO, NOTHING ELSE TO DECODE
	MOVE	T1,P.UNIT(P1)	;GET UNIT NUMBER FIELD
	PUSHJ	P,REVFUL	;REVERSE THE BYTES
	MOVEM	T1,P.UNIT(P1)	;SAVE IN PACKET
	MOVE	T1,P.OPCD(P1)	;GET OPCODE
	PUSHJ	P,REVFUL	;REVERSE THE BYTES
	MOVEM	T1,P.OPCD(P1)	;SAVE IN PACKET
	LSH	T1,-4		;RIGHT JUSTIFY IT
	ANDI	T1,377		;MASK TO ONE 8-BIT BYTE
	MOVE	P4,T1		;SAVE OPCODE W/END FLAG HERE
	MOVSI	P3,-OPCTBL	;SET UP AOBJN POINTER
	TRZ	T1,OP%END	;CLEAR END PACKET FLAG
LOOP3:	LDB	T2,[POINT 8,OPCTAB(P3),31] ;GET AN OPCODE FROM TABLE
	CAIE	T1,(T2)		;OPCODE FOUND?
	AOBJN	P3,LOOP3	;NO, LOOP FOR REMAINDER
	HRRZS	P3		;KEEP JUST INDEX (OR INDEX+1 IF NO MATCH)
	PRINT	<      MSCP opcode: >
	MOVE	T1,P.OPCD(P1)	;GET OPCODE
	LSH	T1,-4		;RIGHT JUSTIFY IT
	ANDI	T1,377		;MASK TO 8 BITS
	PUSHJ	P,.TOCTW##	;TYPE IT
	PRINT	< (>
	HRRZ	T1,OPCTXT(P3)	;GET THE TEXT STRING
	PUSHJ	P,.TSTRG##	;TYPE IT
	MOVE	T1,P.OPCD(P1)	;GET OPCODE BACK
	TRNE	T1,OP.END	;IF END FLAG IS SET,
	PRINT	<+END>
	MOVEI	T1,")"		;ENCLOSE
	PUSHJ	P,.TCHAR##
	MOVEI	T1,400000	;GET THE BIT WHICH SAYS "NO UNIT"
	TDNE	T1,OPCTAB(P3)	;IS IT SET?
	JRST	LOOP4		;YES, SKIP UNIT NUMBER
	PRINT	<   Unit: >
	MOVE	T1,P.UNIT(P1)	;GET (REVERSED) UNIT NUMBER
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TDECW##	;TYPE IT
LOOP4:	PRINT	<   Cmd ref nbr: >
	LDB	T1,[POINT 16,P.CRF(P1),31] ;GET COMMAND REFERENCE NUMBER
	PUSHJ	P,.TDECW##	;TYPE IT
	PUSHJ	P,.TCRLF##	;END LINE
	SKIPE	OPCSPC(P3)	;ANYTHING THERE?
	PUSHJ	P,@OPCSPC(P3)	;DO OPCODE-SPECIFIC THINGS
	JRST	LOOP		;KEEP LOOPING UNTIL ALL PACKETS PROCESSED

LOOP5:	CAIE	T1,.STCRQ	;CREDIT REQUEST
	CAIN	T1,.STCRS	;OR CREDIT RESPONSE?
	SKIPA			;YES
	JRST	LOOP		;NO
	PRINT	<      Credit: >
	MOVE	T1,.MHTYP(P1)	;GET MESSAGE TYPE FIELD
	PUSHJ	P,REVFUL	;REVERSE THE BYTES
	LDB	T2,[POINT 1,.MHTYP(P1),24] ;GET SIGN BIT OF CREDIT FIELD
	SKIPE	T2		;SIGN BIT SET?
	TXO	T1,3B1		;YES, SIGN EXTEND IT HERE
	HLRES	T1		;MOVE TO RH
	PUSHJ	P,.TDECW##	;TYPE IT
	PUSHJ	P,.TCRLF##	;END THE LINE
	JRST	LOOP		;NEXT PACKET

FNFERR:	PUSH	P,T2		;SAVE ERROR CODE
	PRINT	<?LOOKUP error >
	POP	P,T1		;GET ERROR CODE
	HRRZS	T1		;ISOLATE IT
	PUSHJ	P,.TOCTW##	;PRINT IT
	PRINT	< for data file CISNUP.DAT>
	PUSHJ	P,.TCRLF##	;END LINE
DONE:	EXIT
;Special output for Get Command Status command

GCSSP:	PRINT	<        >
	TRNN	P4,OP%END	;END PACKET?
	JRST	GCSSP1		;NO
	PUSHJ	P,ENDSTS	;PRINT END STATUS
	PRINT	<  >
GCSSP1:	PRINT	<Outstanding cmd ref nbr: >
	MOVE	T1,P.OTRF(P1)	;GET OUTSTANDING CRF
	PUSHJ	P,REVFUL	;REVERSE IT
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TDECW##	;PRINT IT
;	TRNN	P4,OP%END	;END FLAG SET?
;Should check for end packet flag and decode command status, but
;since TOPS-10 never asks about a specific command, don't bother.
	PJRST	.TCRLF##	;END LINE AND RETURN


;Special output for Get Unit Status command

GUSSP:	TRNN	P4,OP%END	;END PACKET?
	POPJ	P,		;NO, NOTHING ADDITIONAL IN THE COMMAND
	PUSHJ	P,.SAVE2##	;FREE UP P2
	PRINT	<        >	;START OFF
	PUSHJ	P,ENDSTS	;PRINT STATUS
	PRINT	<  >
	PUSHJ	P,UNTFLG	;PRINT UNIT FLAGS
	PUSHJ	P,.TCRLF##	;END LINE
	PRINT	<        Unit ID: >
	MOVE	T1,P.UNTI(P1)	;GET FIRST WORD
	PUSHJ	P,REVFUL	;REVERSE
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TOCTW##	;TYPE IN OCTAL
	PUSHJ	P,.TSPAC##	;SPACE OVER
	MOVE	T1,P.UNTI+1(P1)	;GET SECOND WORD
	PUSHJ	P,REVFUL	;REVERSE
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TOCTW##	;TYPE IN OCTAL
	PRINT	<  Media type: >
	MOVE	T1,P.MEDI(P1)	;GET IT
	PUSHJ	P,REVFUL	;REVERSE
	MOVE	P2,T1		;SAVE IT
	LDB	T1,[POINT 16,P2,31] ;GET LOW ORDER WORD HERE
	LSH	P2,-2		;RIGHT JUSTIFY HIGH ORDER WORD IN HALFWORD
	HLL	T1,P2		;COMBINE IN T1
	PUSHJ	P,.TXWDW##	;TYPE IN OCTAL
	PUSHJ	P,.TCRLF##	;END LINE
	PRINT	<        Group size: >
	MOVE	T1,P.TRCK(P1)	;GET TRACK/GROUP SIZE WORD
	PUSHJ	P,REVFUL	;REVERSE
	MOVE	P2,T1		;SAVE HERE
	LDB	T1,[POINT 16,P2,15] ;GET HIGH ORDER WORD
	PUSHJ	P,.TDECW##	;TYPE IT
	PRINT	<  Track size: >
	LDB	T1,[POINT 16,P2,31] ;GET LOW ORDER WORD
	PUSHJ	P,.TDECW##	;TYPE IT
	PRINT	<  Cylinder size: >
	MOVE	T1,P.CYL(P1)	;GET CYLINDER INFO WORD
	PUSHJ	P,REVFUL	;REVERSE
	LDB	T1,[POINT 16,T1,31] ;GET LOW ORDER WORD
	PUSHJ	P,.TDECW##	;TYPE IT
	PJRST	.TCRLF##	;END LINE AND RETURN


;Special output for Set Online command

ONLSP:	PRINT	<        >	;START OFF
	TRNN	P4,OP%END	;END PACKET?
	JRST	ONLSP1		;NO
	PUSHJ	P,ENDSTS	;PRINT STATUS
	PRINT	<  >
ONLSP1:	PUSHJ	P,UNTFLG	;PRINT UNIT FLAGS
	PUSHJ	P,.TCRLF##	;END LINE
	TRNN	P4,OP%END	;END PACKET?
	POPJ	P,		;NO, THAT'S ALL
	PRINT	<        Unit size: >
	MOVE	T1,P.UNSZ(P1)	;GET UNIT SIZE
	PUSHJ	P,REVFUL	;REVERSE
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TDECW##	;PRINT
	PRINT	<  Volume S/N: >
	MOVE	T1,P.VSER(P1)	;GET IT
	PUSHJ	P,REVFUL	;REVERSE
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TDECW##	;PRINT
	PJRST	.TCRLF##	;END LINE AND RETURN


;Special output for Set Controller Characteristics

SCCSP:	PRINT	<        Controller flags: >
	MOVE	T1,P.CNTF(P1)	;GET FLAGS
	PUSHJ	P,REVFUL
	MOVE	P2,T1		;COPY
	TXNE	P2,CF.576	;576-BYTE SECTOR MODE?
	PRINT	<576-byte buffers  >
	TXNE	P2,CF.ATN	;ENABLE ATTNS?
	PRINT	<Enable attentions  >
	TXNE	P2,CF.MSC	;ENABLE MISC?
	PRINT	<Enable misc error log  >
	TXNE	P2,CF.OTH	;ENABLE OTHER?
	PRINT	<Enable other error log  >
	TXNE	P2,CF.THS	;ENABLE THIS?
	PRINT	<Enable this error log  >
	TXNE	P2,CF.RPL	;BAD BLOCK REPLACEMENT?
	PRINT	<Controller-initiated bad block replacement>
	PUSHJ	P,.TCRLF##	;END THE LINE
	MOVE	T1,P.HTMO(P1)	;GET HOST (AND CONTROLLER) TIMEOUT WORD
	PUSHJ	P,REVFUL	;REVERSE
	LDB	T1,[POINT 8,T1,31] ;GET LOW ORDER BYTE
	PUSHJ	P,.TDECW##	;PRINT IT
	TXNN	P4,OP%END	;END PACKET?
	PJRST	.TCRLF##	;END LINE AND RETURN
;controller ID seem useful?
	PJRST	.TCRLF##	;END LINE AND RETURN


;Special output for Read/Write commands

RDWRSP:	TRNE	P4,OP%END	;END PACKET?
	JRST	RDWRS1		;YES
	PRINT	<        Byte count: >
	MOVE	T1,P.BCNT(P1)	;GET BYTE COUNT
	PUSHJ	P,REVFUL	;REVERSE IT
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSH	P,T1		;SAVE IT
	PUSHJ	P,.TDECW##	;PRINT IT
	PRINT	< (>
	POP	P,T1		;GET BYTE COUNT
	ADDI	T1,^D575	;ROUND UP
	IDIVI	T1,^D576	; TO NUMBER OF BLOCKS
	PUSH	P,T1		;SAVE FOR PLURALS
	PUSHJ	P,.TDECW##	;TYPE IT
	PRINT	< block>
	MOVEI	T1,"s"		;PLURALIZE IF NEEDED
	SOSE	(P)		;UNLESS JUST ONE,
	PUSHJ	P,.TCHAR##
	ADJSP	P,-1		;TOSS JUNK
	PRINT	<)   LBN: >
	MOVE	T1,P.LBN(P1)	;GET LBN
	PUSHJ	P,REVFUL	;REVERSE IT
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TDECW##	;PRINT IT
	PJRST	.TCRLF##	;END LINE AND RETURN

RDWRS1:	PRINT	<        >	;PREFACE THIS
	PUSHJ	P,ENDSTS	;PRINT END STATUS
	LDB	T1,PKYFCD	;GET END MESSAGE FLAGS
	TRNN	T1,EF%BBR!EF%BBU ;BAD BLOCK REPORTED/UNREPORTED?
	JRST	RDWRS2		;NO, SKIP OUTPUT OF BLOCK NUMBER
	PRINT	<  First bad block: >
	MOVE	T1,P.FBBK(P1)	;GET FIRST BAD BLOCK
	PUSHJ	P,REVFUL	;REVERSE IT
	LSH	T1,-4		;RIGHT JUSTIFY IT
	PUSHJ	P,.TDECW##	;PRINT IT
RDWRS2:	PJRST	.TCRLF##	;END LINE AND RETURN

ENDSTS:	PUSHJ	P,.SAVE2##	;FREE UP P2
	PRINT	<End status: >
	LDB	P2,PKZEST	;GET END STATUS
	HRRZ	T1,STSTXT(P2)	;GET TEXT ADDRESS
	JUMPE	T1,ENDST1	;GO IF NO TEXT
	PUSHJ	P,.TSTRG##	;PRINT IT
	CAXE	P2,ST%OFL	;OFFLINE?
	POPJ	P,		;NO
	LDB	P2,PKZESB	;GET END SUB-CODE
	JUMPE	P2,.POPJ##	;RETURN IF NONE
	PRINT	<  End sub-code: >
	CAXE	P2,SB%NVM	;NO VOLUME MOUNTED?
	JRST	ENDST1		;NO, JUST PRINT IT
	PRINT	<No volume mounted>
	POPJ	P,		;RETURN

ENDST1:	MOVE	T1,P2		;GET STATUS CODE
	PJRST	.TDECW##	;PRINT AND RETURN

UNTFLG:	MOVE	T1,P.UNFL(P1)	;GET UNIT STATUS FLAG
	PUSHJ	P,REVFUL	;REVERSE IT
	MOVE	P2,T1		;COPY STATUS FLAGS HERE
	PRINT	<Unit flags: >
	TXNE	P2,UF.576	;576-BYTE SECTORS?
	PRINT	<576 byte sectors  >
	TXNE	P2,UF.RMV	;REMOVABLE MEDIA?
	PRINT	<Removable media  >
	TXNE	P2,UF.WPH	;HARDWARE WRITE PROTECT?
	PRINT	<Hardware write protect  >
	TXNE	P2,UF.WPS	;SOFTWARE WRITE PROTECT?
	PRINT	<Software write protect  >
	POPJ	P,		;RETURN
	SUBTTL	Miscellaney

TYPCID:	PUSHJ	P,.SAVE3##	;FREE UP A PRESERVED AC OR THREE
	DMOVE	P1,T1		;COPY CID TO P1, NODE NUMBER TO P2
	SKIPN	T1,CIDLST	;SEARCH CID LIST
	JRST	TYPCIN		;NO MATCH, JUST TYPE OCTAL
TYPCI1:	CAMN	P1,.CICID(T1)	;CID MATCH?
	CAME	P2,.CINOD(T1)	;NODE MATCH?
	JRST	TYPCI3		;NOPE
	MOVE	P3,T1		;SAVE ADDRESS OF BLOCK
	MOVEI	P1,.CIPNS(T1)	;POINT AT NAME STRING
	HRLI	P1,(POINT 8)	;THEY'RE 8-BIT ASCII
	MOVEI	P2,C%PNMN	;NUMBER OF BYTES TO TYPE
TYPCI2:	ILDB	T1,P1		;GET A BYTE
	PUSHJ	P,.TCHAR##	;TYPE IT
	SOJG	P2,TYPCI2	;LOOP FOR REMAINDER
	MOVE	T1,P3		;RETURN FIRST WORD OF STRING
	POPJ	P,		;RETURN

TYPCI3:	SKIPE	T1,.CILNK(T1)	;GET LINK TO NEXT BLOCK
	JRST	TYPCI1		;KEEP LOOKING
;FALL INTO TYPCIN
TYPCIN:	MOVE	T1,P1		;GET CID
	PUSHJ	P,.TXWDW##	;TYPE AS OCTAL HALF-WORD
	SETZ	T1,		;NO MATCHING CID BLOCK
	POPJ	P,		;RETURN

REVFUL:	PUSHJ	P,.SAVE3##	;SAVE P1-P3
	LDB	P1,PBYTE1	;PICK UP THE BYTES
	LDB	P2,PBYTE2	;...
	LDB	P3,PBYTE3	;...
	LSH	T1,^D24		;POSITION LEFT OVER BYTE
	DPB	P3,PBYTE2	;PUT THEM IN BACKWARDS
	DPB	P2,PBYTE3	;...
	DPB	P1,PBYTE4	;...
	POPJ	P,		;RETURN


;BYTE POINTERS USED BY REVFUL

PBYTE1:	POINT	8,T1,7
PBYTE3:	POINT	8,T1,23
PBYTE2:	POINT	8,T1,15
PBYTE4:	POINT	8,T1,31
	SUBTTL	OPCODE Text Strings

DEFINE	OPS<
OP	SDG,<Datagram>
OP	SMS,<Message>
OP	RID,<Request-ID>
OP	IDR,<ID Received>
OP	LPB,<Loopback>
>

DEFINE	OP(NAM,TXT),<
	.ORG	OPNAME+OP.'NAM
	[ASCIZ	@TXT@]
	.ORG
>

OPNAME:	REPEAT	400,<[ASCIZ ||]>	;SPACE FOR TEXT STRINGS (OVERLAID)

	OPS			;NOW GENERATE TEXT STRINGS

MSGTYP:	[ASCIZ	/Connect request/]
	[ASCIZ	/Connect response/]
	[ASCIZ	/Accept request/]
	[ASCIZ	/Accept response/]
	[ASCIZ	/Reject request/]
	[ASCIZ	/Reject reponse/]
	[ASCIZ	/Disconnect request/]
	[ASCIZ	/Disconnect response/]
	[ASCIZ	/Credit request/]
	[ASCIZ	/Credit response/]
	[ASCIZ	/Application message/]
	[ASCIZ	/Application datagram/]

DEFINE	OPS,<
OP	OP.ABO,,<Abort>
OP	OP.AVL,,<Unit available>
OP	OP.GCS,GCSSP,<Get command status>
OP	OP.GUS,GUSSP,<Get unit status>
OP	OP.ONL,ONLSP,<Set unit online>
OP	OP.RD,RDWRSP,<Read>
OP	OP.SCC+400000,SCCSP,<Set controller characteristics>
OP	OP.SUC,,<Set unit characteristics>
OP	OP.WR,RDWRSP,<Write>
OP	OP.AVA,,<Unit available attention>
>; END OPS

DEFINE	OP(COD,RTN,TXT),<
	EXP	COD
>

OPCTAB:	OPS
OPCTBL==.-OPCTAB		;LENGTH OF TABLE
	EXP	400000		;DUMMY

DEFINE	OP(COD,RTN,TXT),<
	[ASCIZ	@TXT@]
>

OPCTXT:	OPS
	[ASCIZ /Unknown opcode/]	;DUMMY

DEFINE	OP(COD,RTN,TXT),<
	EXP	RTN
>

OPCSPC:	OPS

DEFINE	STX,<
STS	ONL,<Already online>
STS	EOT,<End of tape>
STS	SUC,<Success>
STS	CMD,<Invalid command>
STS	ABO,<Command aborted>
STS	AVL,<Unit available>
STS	MFE,<Media format error>
STS	WPR,<Write protected>
STS	DAT,<Data error>
>

DEFINE	STS(COD,TXT),<
	.ORG	STSTXT+<ST.'COD'_-<^D18+2>>
	[ASCIZ	|TXT|]
	.ORG
>

STSTXT:	BLOCK	<ST%MSK+1>	;SPACE FOR ALL STATUS STRINGS

	STX			;GENERATE TEXT STRINGS
	SUBTTL	Byte Pointers into Packet

PKYSTS:	POINT	PKSSTS,.PKSTS(P1),PKPSTS	;STATUS BYTE
PKYOP:	POINT	PKSOP,.PKSTS(P1),PKPOP		;OPCODE
PKYNOD:	POINT	PKSNOD,.PKSTS(P1),PKPNOD	;NODE NUMBER
PKYLEN:	POINT	PKSLEN,.PKLEN(P1),PKPLEN	;PACKET LENGTH (BYTES)
PKYFCD:	POINT	PKSFCD,P.FLGS(P1),PKPFCD	;END MESSAGE FLAGS
PKZEST:	POINT	PKSEST,P.STS(P1),PKPEST		;END-PACKET STATUS
PKZESB:	POINT	PKSESB,P.STS(P1),PKPESB		;END-PACKET STATUS SUB-CODE
PKZECD:	POINT	PKSECD,P.STS(P1),PKPECD		;END-CODE
	SUBTTL	Build CID List

BLDCID:	PUSHJ	P,REDWRD	;READ A WORD
	  HALT	.		;EOF OR ERROR
	CAMN	T1,[-1]		;HIT END MARKER?
	POPJ	P,		;YES, RETURN
	MOVEM	T1,CIDBUF+0	;SAVE FIRST WORD AWAY
	MOVSI	T4,-<.CILEN-1>	;SET UP AOBJN TO COPY ENTRY
BLDCI1:	PUSHJ	P,REDWRD	;READ A WORD
	  HALT	.		;EOF OR ERROR
	MOVEM	T1,CIDBUF+1(T4)	;STORE IT AWAY
	AOBJN	T4,BLDCI1	;LOOP

;Check for duplicates

	SKIPN	T1,CIDLST	;ANYTHING THERE?
	JRST	BLDCI3		;NO, FIRST ENTRY, BUILD A NEW ENTRY
BLDCI2:	MOVE	T2,.CINOD(T1)	;GET NODE NUMBER
	MOVE	T3,.CICID(T1)	; AND CONNECT ID
	CAMN	T2,CIDBUF+.CINOD ;CHECK FOR MATCHING NODE NUMBER
	CAME	T3,CIDBUF+.CICID ; AND CONNECT ID
	SKIPA	T1,.CILNK(T1)	;NO MATCH, GET LINK TO NEXT BLOCK AND SKIP
	JRST	BLDCID		;MATCH, SKIP THIS ONE
	JUMPN	T1,BLDCI2	;CHECK NEXT BLOCK (IF ONE)

;Need to add a new entry

BLDCI3:	MOVEI	T1,.CILEN	;LENGTH OF AN ENTRY
	EXCH	T1,.JBFF	;T1 GETS ADDRESS OF NEW ENTRY, .JBFF GETS LENGTH
	ADDM	T1,.JBFF	;UPDATE NEW FIRST FREE
	MOVEI	T2,.CILEN-1(T1)	;LAST ADDRESS NEEDED IN NEW ENTRY
	CAMG	T2,.JBREL	;NEED EXTRA CORE?
	  JRST	.+3		;NO
	CORE	T2,		;YES, ASK FOR IT
	  HALT	.		;ERROR
	MOVE	T2,T1		;COPY ENTRY ADDRESS
	HRLI	T2,CIDBUF	;SOURCE OF BLT
	MOVEI	T3,.CILEN-1(T1)	;LAST ADDRESS
	BLT	T2,(T3)		;COPY THE ENTRY
	SKIPN	T2,CIDLST	;FIRST ENTRY?
	JRST	[MOVEM T1,CIDLST ;YES, SET LIST HEADER
		 JRST  BLDCID]	;AND CONTINUE
	MOVEM	T2,.CILNK(T1)	;LINK OLD LIST TO NEW ENTRY
	MOVEM	T1,CIDLST	;INSERT NEW ENTRY AT HEAD OF LIST
	JRST	BLDCID		;KEEP LOOPING
	SUBTTL	Type Out Routine

TYPOUT:	JUMPE	T1,.POPJ##	;SKIP NULLS ON OUTPUT
	SKIPE	OBUF+.BFPTR	;LOG FILE BEEN OPENED?
	JRST	TYPLOG		;YEP
	OUTCHR	T1		;OUTPUT THE CHARACTER
	POPJ	P,		;RETURN

TYPLOG:	SOSGE	OBUF+.BFCTR	;ROOM?
	JRST	TYPLG1		;NO
	IDPB	T1,OBUF+.BFPTR	;DUMP BYTE
	POPJ	P,		;RETURN

TYPLG1:	OUT	LOG,		;DUMP THE BUFFER
	  JRST	TYPLOG		;SUCCESS, CONTINUE
	HALT	.		;OUTPUT ERROR
	SUBTTL	Read a Packet into Buffer

;Routine to read a packet from the log file into the packet buffer

REDPKT:	PUSHJ	P,REDWRD	;READ A WORD FROM THE FILE
	  POPJ	P,		;EOF OR ERROR
	LDB	T4,[POINT 20,T1,35] ;GET LENGTH OF PACKET
	MOVNS	T4		;SET UP AN AOBJN COUNTER
	HRLZS	T4		;...
	MOVEM	T1,PACKET(T4)	;STORE IT AWAY
	AOBJP	T4,.POPJ##	;RETURN IF ONE WORD PACKET

	PUSHJ	P,REDWRD	;READ NEXT WORD
	  POPJ	P,		;EOF OR ERROR
	MOVEM	T1,PACKET(T4)	;STORE IT AWAY
	AOBJN	T4,.-3		;LOOP
	JRST	.POPJ1##	;SKIP RETURN

;Read one word from the log file

REDWRD:	SOSGE	IBUF+.BFCTR	;MORE TO READ?
	JRST	REDWR1		;NO
	ILDB	T1,IBUF+.BFPTR	;YES, FETCH IT
	JRST	.POPJ1##	;SKIP RETURN

REDWR1:	IN	DAT,		;READ ANOTHER BUFFER LOAD
	JRST	REDWRD		;NO ERRORS, TRY AGAIN
	POPJ	P,		;EOF OR ERROR, DON'T CARE WHICH
	SUBTTL	The End

	END	START