;<DIAGNOSTICS>IMPBBN.A;3    22-NOV-72 13:58:08	EDIT BY CHIPMAN
	TITLE IMPTST
	SUBTTL SENDS MESSAGES TO SELF VIA IMPSYS
	BARE==0
	DEC==1
	TENEX==2
;INSTALLATION-SPECIFIC ASSEMBLY PARAMETERS **********************
;WHAT KIND OF SYSTEM AM I RUNNING UNDER?                        *
	SYSTEM==TENEX      ;                                    *
;IMP DEVICE CODE                                                *
	IMP=^O550          ;                                    *
;ECU BETTEN HERE AND THE IMP					*
	ECU==1		   ;					*
;MY NETWORK ADDRESS                                             *
	ADRES==^O263       ;                                    *
;****************************************************************
;SYSTEM CALL DEFINITIONS
IFE SYSTEM-TENEX,<
SEARCH STENEX
>
;LINK NUMBER TO BE USED
	LINK==^O340
	LINK2==LINK+1
;INPUT BUFFER SIZE
	INSIZ==^D225
	STKSIZ==^D50	;PUSH DOWN LIST SIZE
	QUESIZ==^D10	;SIZE OF OUTGOING MESSAGE QUEUE
	CP=17	;STACK POINTER
;OTHER AC'S
	BLOCKI=<BLOCKO=<INAC=<OUTAC=CP-1>-1>-1>-1
	WHICH=<FLAGS=<TIME=<CONDS=<QP=<OFFQ=BLOCKI-1>-1>-1>-1>-1>-1
;CONO BITS
	CLRERR==200000
	MAK10D==100000
	STPOUT==40000
	ENDOUT==20000
	GOTEND==10000
	ENBEND==4000
	ENBOUT==200
	ENBIN==10
;CONI BITS
	PWRUP==200000
	DOWN10==100000
	ERR==40000
	IMPDWN==20000
	ENDIN==14000
	EMPTY==200
	FULL==10
	IFE SYSTEM-BARE, <LOC 4000
	RIM10B>
;DEFINE TTY OUTPUT MACROS IN CASE NOT 10-50
	IFE SYSTEM-BARE, <DEFINE OUTSTR (ADDRES)
	<HRRZI 1, ADDRES
	PUSHJ CP, TTYOUT>
	DEFINE OUTCHR
	<PUSHJ CP, TTYCHR>
>
	IFE SYSTEM-TENEX, <DEFINE OUTSTR (ADDRES)
	<HRROI 1, ADDRES
	PSOUT>
	DEFINE OUTCHR
	<PUSHJ CP, TTYCHR>
>
;MACRO TO PUT A MESSAGE ON THE OUTGOING QUEUE
	DEFINE POQ (WORD)
	<MOVE 0, WORD
	PUSHJ CP, PUTONQ>
	DEFINE EROR (STRING)
	<[PUSH CP, 0
	PUSH CP, 1
	OUTSTR <[ASCIZ/
STRING
/]>
	PUSHJ CP, PHEADR
	POP CP, 1
	POP CP, 0
	JRST .+1]>
;IF RUNNING UNDER 10-50, CALL TRPSET
START:	IFE SYSTEM-TENEX,<USRIO
	JRST [OUTSTR<[ASCIZ*
USER I/O PRIVELEGE NOT AVAILABLE- ARE YOU ENABLED?
*]>
	HALTF]>
	IFE SYSTEM-DEC, <CALLI 0,0
	MOVEI 1, 0
	CALLI 1, 25
	JRST [OUTSTR<[ASCIZ*
USER I/O PRIVELEGE NOT AVAILABLE
*]>
	EXIT]>
	IFE SYSTEM-BARE, <CONO TTY, 3410>
	MOVE CP, [IOWD STKSIZ, STACK]
	OUTSTR<[ASCIZ/
IMP TESTER
/]>
	CONO IMP, MAK10D+ENBEND+ENBOUT+ENBIN
;NOW WAIT FOR THE IMP TO SEE THAT YOU ARE DOWN
	IFN SYSTEM-DEC, <MOVSI 0, -4
	AOJL .>
	IFE SYSTEM-DEC, <MOVEI 0, 1
	SLEEP>
;INITIALIZE QUEUE POINTERS
	MOVE QP, [IOWD QUESIZ, QUEUE]
	MOVE OFFQ, QP
;INITIALIZE THE INTERFACE
	IFN ECU, <
	CONO IMP,		;F2 with ECU needs this!
	IFN SYSTEM-DEC, <MOVSI 0, -4
	AOJL .>
	IFE SYSTEM-DEC, <MOVEI 0, 1
	SLEEP>>
	DATAI IMP, 0
	CONO IMP, CLRERR+ENDOUT+GOTEND
;PUT 4 NOPS ON THE OUTGOING MESSAGE QUEUE
	MOVEI 1, 4
NOPLOP:	POQ <[IOWD 1, NOPMES]>
	SOJG 1, NOPLOP
;CLEAR BOTH SEQUENCE COUNTERS
	SETZM MESC1
	SETZM MESC2
;QUEUE BOTH MAIN MESSAGES
	POQ IOWD1
	POQ IOWD2
;SET UP RETURN POINTERS TO POINT TO THE BEGINNING OF THE
;INPUT AND OUTPUT ROUTINES
	MOVEI INAC, STRTIN
	MOVEI OUTAC, STARTO
	MOVSI TIME, 40
BCKGND:	CONI IMP, CONDS	;BACKGROUND LOOP TESTS WHETHER
	TRNE CONDS, FULL	;INPUT WANTS SERVICE
	JRST (INAC)
	TRNE CONDS, EMPTY	;OR OUTPUT WANTS SERVICE
	JRST (OUTAC)
TIMCNT:	MOVE 1, MESC1	;NOW TEST WHETHER SEQUENCE COUNTS
	SUB 1, MESC2	;DIFFER BY MORE THAN 1, TO CHECK
	JUMPL 1, STEP	;FOR DROPPED RFNMS
	SOJG 1, STEP
;NOW TEST VARIOUS INTERFACE ERROR CONDITIONS
	TRNN CONDS, PWRUP
	JRST [OUTSTR <[ASCIZ/
NO POWER ON INTERFACE/]>
	JRST START]
	TRNE CONDS, IMPDWN
	JRST [OUTSTR <[ASCIZ/
IMP IS DOWN/]>
	JRST START]
	TRNE CONDS, ERR
	JRST [OUTSTR <[ASCIZ/
IMP WAS DOWN ERROR
/]>
	CONO IMP, CLRERR
	HRRZI TIME, 100000	;TIME OUT QUICKLY AFTER "IMP WAS DOWN"
	JRST BCKGND]
	SOJG TIME, BCKGND	;TOO LONG SINCE THE LAST MESSAGE?
	JRST EROR <TIME OUT, RESTARTING>
	JRST START
STEP:	OUTSTR <[ASCIZ/
LINKS OUT OF STEP, RFNM DROP?
RESTARTING
/]>
	JRST START
;INPUT ROUTINE
STRTIN:	MOVE BLOCKI, [IOWD INSIZ, IBUF]	;SET UP BLKI POINTER
INLOP:	JSP INAC, BCKGND	;WAIT FOR A WORD
	CONI IMP, CONDS	;SAVE STATUS FOR ENDIN TEST
	BLKI IMP, BLOCKI	;GET THE WORD
	JRST EROR <MESSAGE FROM IMP TOO BIG>	;IF BUFFER OVERFLOWS
	TRNN CONDS, ENDIN;WAS IT THE LAST ONE?
	JRST INLOP	;NO
	CONO IMP, GOTEND	;YES. RELEASE INTERFACE
;HAVE WHOLE MESSAGE IN CORE, CHECK IT
	LDB 1, [POINT 4, IBUF, 7]	;MESS TYPE
	CAIE 1, 5	;RFNM?
	JUMPN 1, CONTRL	;IF UNUSUAL MESSAGE TYPE
	LDB 0, [POINT 4, IBUF, 3]
	JUMPN WEIRDO	;IF IT IS FROM IMP, ETC
	LDB 0, [POINT 8, IBUF, 15]
	CAIE ADRES
	JRST WEIRDO	;IF IT IS NOT FROM ME
	LDB WHICH, [POINT 8, IBUF, 23]	;LINK #
	SUBI WHICH, LINK2
	JUMPG WHICH, EROR <LINK # TOO LARGE>
	AOJL WHICH, EROR <LINK # TOO SMALL>
	ANDI WHICH, 1
	JUMPE 1, NORMAL
RFNM:	AOS 1,@CNTADR(WHICH)	;INCREMENT MESSAGE COUNT
	POQ <IOWD1(WHICH)>	;PUT MESSAGE ON OUTGOING QUEUE
	TRNE 1, 7777	;TIME TO PRINT "0000TH MESSAGE" ?
	JRST STRTIN	;NO
	MOVE 0,1
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/TH MESSAGE ON LINK /]>
	MOVEI LINK(WHICH)
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/
/]>
	JRST STRTIN
WEIRDO:	OUTSTR <[ASCIZ/
MESSAGE FROM SITE /]>
	LDB [POINT 8,IBUF,15]
	PUSHJ CP, PRNUM
	PUSHJ CP, PHEADR
	JRST STRTIN
;IS THE RECEIVED MESSAGE THE RIGHT SIZE?
NORMAL:
	IFN ECU,<
	HRRZ 2,BLOCKI		;ECU invents extra LAST BITS, remove them
	MOVSI 0,042000		;... in a kludgy fashion
	ANDCAM 0,(2)
	>;IFN ECU
	HLRE 0, BLOCKI
	CAME 0, SIZTAB(WHICH)
	JRST EROR<RIGHT MESSAGE, WRONG LENGTH>
;NOW CHECK THE DATA
	MOVE 2, IOWD1(WHICH)
	ADD 2, [XWD -1,1]
	MOVEI 3, IBUF
COMPAR:	MOVE 0, (3)
	CAME 0, (2)
	JRST MISMAT
MATCH:	ADD 3, [XWD 1,1]
	AOBJN 2, COMPAR
	MOVSI TIME, 20	;RESET TIME COUNTER
	SKIPN LOOPED	;Are we looped between here and  the IMP?
	  JRST STRTIN	;  No
	JRST RFNM	;Yes, invent a RFNM
STRANG:	OUTSTR @TYPTAB-1(1)
	PUSHJ CP, PHEADR
	POPJ CP,
CONTRL:	LDB 1, [POINT 4, IBUF, 7]
	PUSHJ CP, STRANG
	JRST STRTIN
;NAMES OF MESSAGE TYPES
	DEFINE CONCAT(A,B) <A'B>
	DEFINE NXTYPE (NAME)
<CONCAT(TYP,\N):	ASCIZ/NAME/
	N=N+1>
	N=1
	NXTYPE ERROR WITHOUT ID
	NXTYPE IMP GOING DOWN
	NXTYPE BLOCKED LINK
	NXTYPE NOP
	NXTYPE RFNM
	NXTYPE LINK TABLE FULL
	NXTYPE DESTINATION DEAD
	NXTYPE ERROR WITH ID
	NXTYPE INCOMPLETE TRANSMISSION
	NXTYPE CEASE ON LINK
	NXTYPE CEASE TIMEOUT
	NXTYPE CEASE SENT
	NXTYPE TYPE 13
	NXTYPE TYPE 14
	NXTYPE TYPE 15
	I=1
TYPTAB:	REPEAT N-1,<
	Z CONCAT(TYP,\I)
	I=I+1>
MISMAT:	OUTSTR <[ASCIZ/DATA MISMATCH ON THE /]>
	HLRZ 3
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/TH WORD OF THE /]>
	MOVE @CNTADR (WHICH)
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/TH MESSAGE ON LINK /]>
	MOVEI LINK(WHICH)
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/
SENT    /]>
	MOVE (2)
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/
RECEIVD /]>
	MOVE (3)
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/
XOR     /]>
	MOVE (2)
	XOR (3)
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/
/]>
	JRST MATCH
;OUTPUT ROUTINE
STARTO:	JSP OUTAC, BCKGND	;WAIT FOR THE BUFFER TO BE EMPTY
OUT:	CAMN OFFQ, QP	;ANYTHING WAITING TO BE SENT?
	JRST TIMCNT	;NO
	AOBJN OFFQ, .+2	;YES. GET IT
	MOVE OFFQ, [<IOWD QUESIZ, QUEUE>+<1,,1>]
	MOVE BLOCKO, (OFFQ)
OUTLOP:	JSP OUTAC, BCKGND	;WAIT FOR BUFFER TO BE EMPTY
	BLKO IMP, BLOCKO	;SEND A WORD
	JRST FINALO	;IF THAT WAS THE LAST WORD
	JRST OUTLOP
FINALO:	JSP OUTAC, BCKGND	;WAIT FOR THE BUFFER TO EMPTY
	CONO IMP, ENDOUT	;TELL THE INTERFACE THAT'S ALL
	JRST STARTO
;ROUTINE TO TYPE A CHARACTER
	IFE SYSTEM-BARE,
<TTYCHR:MOVEM 0, CHAR
	DATAI APR, 0
	TRNN 0, 3
	JRST DOCHAR
	TRNE 0, 2
	CONSO TTY, 10
	POPJ CP,
	DATAO TTY, [7]
	POPJ CP,
DOCHAR:	CONSO TTY, 10
	JRST .-1
	DATAO TTY, CHAR
	POPJ CP,
CHAR:	Z
TTYOUT:	HRLI 1, (POINT 7,0)
	JRST TTYNTR
TTYLOP:	OUTCHR
TTYNTR:	ILDB 1
	JUMPN  TTYLOP
	POPJ CP,>
	IFE SYSTEM-TENEX,
<TTYCHR:	EXCH 0,1
	PBOUT
	EXCH 0,1
	POPJ CP,>
;ROUTINE TO ADD AN ENTRY TO THE OUTGOING QUEUE
PUTONQ:	AOBJN QP, .+2
	MOVE QP, [<IOWD QUESIZ, QUEUE>+<1,,1>]
	MOVEM (QP)
	POPJ CP,
;ROUTINE TO PRINT OCTAL NUMBER
PRNUM:	LSHC 0, -3
	JUMPE  PREM
	PUSH CP, 1
	PUSHJ CP, PRNUM
	POP CP, 1
PREM:	SETZ
	LSHC 0, 3
	IORI 0, ^O60
	OUTCHR
	POPJ CP,
;ROUTINE TO PRINT MESSAGE HEADER
PHEADR:	OUTSTR <[ASCIZ/
HEADER /]>
	LDB [POINT 4, IBUF, 3]
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/,  /]>
	LDB [POINT 4, IBUF, 7]
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/,  /]>
	LDB [POINT 8, IBUF, 15]
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/,  /]>
	LDB [POINT 8, IBUF, 23]
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/,  /]>
	LDB [POINT 8, IBUF, 31]
	PUSHJ CP, PRNUM
	OUTSTR <[ASCIZ/
/]>
	POPJ CP,
LOOPED:	0		;-1 if line is looped between use and the IMP
QUEUE:	BLOCK QUESIZ
STACK:	BLOCK STKSIZ
IOWD1:	IOWD <END1-MES1>+1,MES1
IOWD2:	IOWD <END2-MES2>+1, MES2
SIZTAB:	<END1-MES1+2>-INSIZ
	<END2-MES2+2>-INSIZ
CNTADR:	Z MESC1
	Z MESC2

;THE MESSAGES
MES1:	<ADRES>B15 + <LINK>B23	;HEADER
MESC1:	0	;MESSAGE SEQUENCE NUMBER
;DATA
	-1
	0
	525252525252
	252525252525
	123456765432
	45636,,737134
	757726,,666035
	375714,,446357
	773350,,432653
	262347,,513752
	61563,,733470
	724527,,757030
	535532,,647141
	736710,,671303
	172317,,221743
END1:	770070,,630100	;Extra word to make the two have different lengths
	400000,,0
MES2:	<ADRES>B15 + <LINK2>B23	;HEADER
MESC2:	0	;MESSAGE SEQUENCE NUMBER
;DATA
	1
	2
	4
	10
	20
	40
	400000,,0
	200000,,0
	100000,,0
	40000,,0
	20000,,0
	10000,,0
	-1,,-2
	-1,,-3
END2:	377777,,-1
	400000,,0
NOPMES:	BYTE (4) 0,4,0,11,17
IBUF:	BLOCK INSIZ
	END START
