perm filename LOITER.FAI[HAK,ROB] blob sn#461585 filedate 1979-07-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	TITLE LOITER	-- WAIT FOR EITHER TTY INPUT, TIMEOUT, <OR SIX MESSAGE>
C00004 00003	ENTRY	LOITER
C00009 ENDMK
C⊗;
TITLE LOITER	-- WAIT FOR EITHER TTY INPUT, TIMEOUT, <OR SIX MESSAGE>
SUBTTL	Ken Shoemake (KS)	9-Sep-77

;EXTERNAL INTEGER PROCEDURE Loiter(REAL Seconds; BOOLEAN NoTTY(FALSE));
COMMENT	⊗
Loiter was intended primarily for use with the TEN program.  It takes
one REAL argument, which is interpreted as the time in seconds to wait
for something to happen.  If it is zero (0), it means wait forever.
A happening is either receipt of a message from the SIX or a character
(line?) from the TTY.  In the event that neither of those happens
during the allotted time, Loiter will return 0 (BOOLEAN FALSE),
otherwise it will return 1 for a SIX message and -1 for TTY input.
However, if NoTTY is TRUE, then TTY input is not a happening.
⊗

IFNDEF FTSIX,<FTSIX ←← 0>; Set to non-0 to include the SIX

; AC'S
F←←0		; FLAGS
DEFINE ACDEF(NAMES,FIRST)
    <
    AC←FIRST
    FOR NAME IN (NAMES)
      <NAME←←AC ↔ AC←←AC+1 ↔>
    >
ACDEF(<T,U,V,W,X>,1)	; TEMPORARY - ANYONE CAN CLOBBER
ACDEF(<A,B,C,D,E>,6)	; PERMANENT - ONLY CLOBBER LOCALLY
ACDEF(<L,M,N,O,P>,=11)	; SACRED - CLOBBER AT YOUR OWN RISK


; INTERRUPT BITS
INTTTY←←1B4		; TTY INPUT
INTCLK←←1B10		; CLOCK INTERRUPT
IFN FTSIX,<
  INTSIX←←1B21		; SIX MESSAGE
>;IFN FTSIX
ENTRY	LOITER
INTERNAL LOITER

DEFINE SECS <-2(P)>
DEFINE NOTTY <-1(P)>
DEFINE SUBRET
<
	ADJSP P,-3	; TWO ARGUMENTS, PLUS RETURN ADDRESS
	JRST @3(P)	; USE RETURN ADDRESS
>

LOITER:	MOVE T,SECS		; CONVERT SECS TO TICKS
	FMPRI T,(<60.0>)	; 60 TICKS/SEC
	FADRI T,(<67108864.0>)	; CONVERT TICKS TO INTEGER
	HRRZM T,TICKS
	SETOM OLDMSK		; NOW MASK OFF ALL INTERRUPTS
	IMSKCR OLDMSK		; SAVING OLD MASK
	INTDMP OLDINT		; SAVE ALL OTHER OLD STUFF (CAN'T GET INTERRUPT NOW)
	 JFCL			; ERROR RETURN - SHOULD NEVER HAPPEN
	MOVEI F,LOINT		; AND SET UP TO CATCH INTERRUPTS OURSELVES
	EXCH F,JOBAPR↑
	MOVEM F,OLDAPR		; SAVE PREVIOUS INTERRUPT ROUTINE'S ADDRESS
IFN FTSIX,<
	MOVE U,[INTSIX]		; ENABLE THIS (STILL MASKED)
	SKIPN NOTTY		; MAYBE THIS
	 OR U,[INTTTY]
	INTORM U,
>;IFN FTSIX
IFE FTSIX,<
	MOVE U,[INTTTY]		; ENABLE THIS (STILL MASKED)
	SKIPN NOTTY		; MAYBE THIS
	INTORM U,
>;IFE FTSIX
	SETOM T			; ASSUME TTY INPUT
	SKIPN NOTTY
	 INSKIP 1		; HAS A LINE BEEN TYPED?
	  CAIA
	   JRST LODN1		; DON'T LINGER
IFN FTSIX,<
	PUSHJ P,MESLEN↑
	JUMPN T,LODONE		; IF LENGTH IS NON-ZERO, WE DON'T NEED TO WAIT
>;IFN FTSIX
	CLKINT @TICKS		; ENABLE CLOCK INTERRUPTS
IFN FTSIX,<
	IWKMSK [INTTTY!INTCLK!INTSIX]	; STOP WAITING FOR THESE REASONS ONLY
	IMSTW [INTTTY!INTCLK!INTSIX]	; UNMASK, AND WAIT FOR AN INTERRUPT
>;IFN FTSIX
IFE FTSIX,<
	IWKMSK [INTTTY!INTCLK]	; STOP WAITING FOR THESE REASONS ONLY
	IMSTW [INTTTY!INTCLK]	; UNMASK, AND WAIT FOR AN INTERRUPT
>;IFE FTSIX
	SKIPA T,POKER		; RETURN WHATEVER POKED US (SET BY LOINT)
LODONE:	 MOVEI T,1		; JUMPED HERE IF MESSAGE WAS ALREADY WAITING
LODN1:	MOVE F,OLDAPR		; RESTORE CALLER'S INTERRUPT HANDLER
	MOVEM F,JOBAPR
	MOVE F,OLDENB		; RESTORE CALLER'S INTERRUPT ENABLINGS
	INTENB F,
	IWKMSK OLDWAK		; RESTORE CALLER'S WAKE-UP MASK
	INTMSK OLDMSK		; RESTORE CALLER'S INTERRUPT MASK
	SUBRET			; AND RETURN

LOINT:	MOVE F,JOBCNI↑		; FIND OUT WHAT WAS CAUSE OF INTERRUPT
	SETOB T,POKER		; REMEMBER FINDINGS
	TDZE F,[INTCLK]		; WAS IT THE CLOCK?
	 SETZM POKER		; YES, MARK IT
IFN FTSIX,<
	TDZE F,[INTSIX]		; WAS IT THE SIX?
	 MOVNM T,POKER		; YES, MARK IT
>;IFN FTSIX
	TDZE F,[INTTTY]		; OR WAS IT THE TTY?
	 SETOM POKER		; AH, THAT WAS IT!
	INTMSK [0]		; NOW MASK OFF ALL INTERRUPTS
	DISMIS			; AND WE'RE DONE

TICKS:	0			; NUMBER OF TICKS TO WAIT, 0 MEANS FOREVER
POKER:	0			; STASH CAUSE OF INTERRUPTS HERE
OLDMSK:	0			; SAVE OLD INTERRUPT MASK
OLDAPR:	0			; SAVE ADDRESS OF OLD INTERRUPT HANDLER

OLDINT:	0			; BEGINNING OF OLD SAVE AREA. ZERO MEANS OUR JOB
OLDENB:	0			; SAVE OLD INTERRUPT ENABLINGS
	0			; MASK - BUT ALREADY CLOBBERED
	0			; ZERO
OLDWAK:	0			; WAKE UP MASK
	0			; QUEUE NUMBER

	END