Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-01 - decus/20-0003/paspty.mac
There are 4 other files named paspty.mac in the archive. Click here to see a list.
	title PASPTY - routine for openning a PTY in Pascal-20

	twoseg

	search monsym,pasunv

	reloc 400000

	entry ptyopn,ptyget

;ptyopn(input,output,name,openf bits,flags)
;  This routine is designed to solve a problem in the design of
;	the pascal language:  Because buffer variables are
;	associated with a pascal file, you cannot do input and
;	output over the same file.  When you did output, you
;	would lose what was left in the buffer from the last
;	input.  This is important because Pascal uses one-
;	character lookahead.  So this routine opens two files
;	with the same jfn, one for input and the
;	other for output.  Openf bits and flags are the
;	last two arguments from a standard RESET or REWRITE.
;	They should usually be zero.  The bit is automatically
;	set that suppresses the implicit GET after the open.
;	The following example program shows how to use it.
;	However any realistic program would have to handle
;	synchronization, probably by using interrupts
;   You should check EOF(input) to see if it worked.  If a null name is
;	given, the current jfn from input will be used.

repeat 0,<

procedure ptyopn(var i:file;var out:file; name:string; open,buffer:integer); extern;
function ptyget(var i:file):integer;extern;

begin
{If this program must be restartable, a short wait should be put here.
  It takes some time for the close of the pty: to take effect after
  the reset is done at the beginning of the program.  If we proceed
  to try and reopen the pty before that time, we get 'already in use
  by another job'.  It works the first time, however.}

if ptyget(input) = 0
  then writeln(tty,'error');
ptyopn(input,output,'',0,0);
write(output,chr(3));	{control C to give the greeting}
repeat
  get(input);
  ttyoutput^ := input^;
  put(ttyoutput)
  until input^ = '@';
writeln(output,'systat');  {We must wait for the prompt before this. }
repeat
  get(input);
  ttyoutput^ := input^;
  put(ttyoutput)
  until false
end.
>

ptyopn:	push p,c	;output file
	push p,d	;name
	push p,e
	push p,f	;openf bits
	push p,g	;flags
;since we are going to copy the jfn from the input to the output, we had
;  better release any existing output jfn, unless it happens to be the
;  same as the input jfn.  In that case, need to be able to close input,
;  too, so we just close it rather than releasing it.
	hrrz t,filjfn(c) ;get output jfn
	jumpe t,noojfn	;if none, nothing to do
	hrrz a,filjfn(b) ;get input jfn
	movei c,relf.##	;assume we are going to release the file
	camn a,b	;if they are the same
	movei c,clofil## ;just close it
	exch b,-4(p)	;get output file, save input
	pushj p,(c)	;close/release it
	exch b,-4(p)	;now back to input
;now we take care of the input jfn.  We want to release it unless we are
;  to reuse it, in which case we just close it.
noojfn:	hrrz t,filjfn(b) ;get input jfn
	jumpe t,noijfn	;if none, nothin to do
	movei c,relf.##	;assume we are going to release it
	cain e,0	;except that is null file name, only close it
	movei c,clofil##
	pushj p,(c)	;close/release it
;now we have to copy the input jfn to the output.  The output has to be
;  openned first, since the final openf must be in update mode (to allow
;  both directions), and obviously the input most be the one shown as update
	move t,filjfn(b) ;get input jfn again.  (now zero if released)
noijfn:	exch b,-4(p)	;now swap jfn's back to output
	movem t,filjfn(b) ;put jfn in output
;first open output
nojfn:	move c,d	;c,d _ name
	move d,e
	move h,g	;h _ flags
	move g,f	;g _ openf bits
	setzb e,f	;no gtjfn bits or interactive mode
	pushj p,rewrite## ;open output side
	skipn fileof(b)	;if error
	jrst [adjsp p,-4 ;prune stack
	      pop p,b	;get input file
	      movei t,1	;put error indicator in input
	      movem t,fileof(b)
	      jrst return]
;now open input
	pop p,h		;h _ flags
	pop p,g		;g _ openf bits
	setz f,		;no gtjfn bits
	seto e,		;interactive
	pop p,d		;c,d _ name
	pop p,c
	move t,filjfn(b) ;t _ new jfn
	pop p,b		;b _ input file
	movem t,filjfn(b) ;now put new jfn into input file
	pushj p,update## ;finally open input (update so it is read/write)
return:	pop p,a		;return address
	adjsp p,-1	;last arg was also pushed
	jrst (a)


;ptyget(file):integer
;  Tries to get a free pty.  If so, puts the jfn in file and returns
;	a tty designator for the corresponding tty.  If none avaiable,
;	returns zero.

ptyget:	move e,b		;save file in e
	pushj p,relf.##		;close any old file
	MOVE A,[SIXBIT/PTYPAR/]	;GET # OF PTYS IN SYSTEM
	SYSGT			;...
	HRRZM A,FIRPTY#		;STORE TTY CORRESPONDENCE FOR PTY'S
	HLRZM A,NUMPTY#		;STORE # OF PTY'S IN SYSTEM
	MOVN D,NUMPTY#		;GET # OF PTYS IN SYSTEM
	HRLZS D
	adjsp p,3		;get space for the file name
GETPT1:	MOVSI A,600013		;GET PTY DESIGNATOR
	HRRI A,(D)		;TRY TO GET NEXT PTY
	DVCHR			;GET CHARACTERISTICS OF THIS PTY
	TLNN B,(1B5)		;IS IT AVAILABLE?
	  JRST GETPT2			;NO
	MOVE B,A
	HRROI A,-2(p)		;TURN IT INTO AN ASCII STRING
	DEVST
	  jrst getpt2
	MOVEI B,":"		;TERMINATED BY A COLON
	IDPB B,A
	MOVEI B,0
	IDPB B,A		;ENDED WITH A 0 BYTE
	MOVSI A,1		;SHORT FORM GTJFN
	HRROI B,-2(p)
	GTJFN
	  JRST GETPT2			;NOT AVAILABLE
	adjsp p,-3		;success - restore stack
	ADD D,FIRPTY		;TRUN PTY UNIT # INTO TTY #
	TRO D,(1B0)		;MAKE LEGAL TERMINAL DESIGNATOR
	hrrzm d,1(p)		;STORE TTY DESIGNATOR
	movem a,filjfn(e)	;STORE JFN ALSO
	POPJ P,

GETPT2:	AOBJN D,GETPT1		;TRY FOR ANOTHER PTY
	adjsp p,-3		;none left - restore stack
	setzm 1(p)		;say we failed
	POPJ P,			;NONE LEFT

	end