Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-11 - 43,50530/paspty.mac
There are 4 other files named paspty.mac in the archive. Click here to see a list.
	title PASPTY - a routine to open a PTY on Tops-10

	twoseg

	search uuosym,pasunv

	reloc 400000

	entry ptyopn
	extern rewrite,resetf

	t==0
	a==1
	b==2
	c==3
	d==4
	e==5
	f==6
	g==7
	h==10
	i==11
	p==17

;ptyopn(infile,outfile,name,open bits, buffer bits)
;  Warning: I am not clear whether this routine will work if
;	someone opens a file at interrupt level, interrupting
;	execution of this routine in the middle, whether it
;	will work if Pascal
;	is getting its channels from someone else (e.g. Fortran)
;  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
;	on the same monitor channel, one for input and the
;	other for output.  Open bits and buffer bits 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 non-blocking I/O
;	and interrupts, though easier ways are possible.

repeat 0,<
procedure ptyopn(var i:file;var out:file; name:string; open,buffer:integer); extern;

begin
ptyopn(input,output,'pty:',40000B,0);
writeln(output,chr(3),'systat');  {put out systat command}
break(output);			  {force output the buffer}
while true do			  {now copy everything you see from pty}
  begin
  get(input);
  ttyoutput^ := input^;
  put(ttyoutput)
  end
end.				  {assume the user will end this with ^C}
>

ptyopn:	push p,b	;infile
	push p,d	;name - addr
	push p,e	;name - length
	push p,f	;open bits
	push p,g	;buffer bits
;first make sure the file control blocks have been initialized
	move t,filtst(b)
	caie t,314157	;magic word will be there if it is legal
	pushj p,initb.##
	exch b,c
	move t,filtst(b)
	caie t,314157	;magic word will be there if it is legal
	pushj p,initb.##
	exch b,c
;first open the output side
	move b,c	;b _ outfile
	move c,d	;c,d _ name
	move d,e
	move h,g	;h _ buffer bits
	move g,f	;g _ open bits
	setzb e,f	;clear protection, lookup block
	setz a,		;text
	pushj p,rewrite	;open output side
	skipn fileof(b)	;be sure it worked
	jrst [sub p,[xwd 4,4] ;clean up stack - top is now infile
	      pop p,b	;infile
	      movei t,1	;set eof, so get fail return for both files
	      movem t,fileof(b)
	      jrst return]
;this was a dummy open - return the channel
	ldb a,[point 4,filchn(b),12]
	pushj p,lo.chn##
;now do the real open
	pop p,h		;h _ buffer bits
	pop p,g		;g _ open bits
	pop p,d		;c,d _ name
	pop p,c
	seto e,		;suppress initial get
	setz f,		;no lookup block
	exch b,(p)	;b _ input file
	setz a,		;text
	pushj p,resetf	;now open the input side
;now join the channels
;this is the questionable part of this code.  Normally we will
;end up with the same channel here as for the output side, because
;of the way the channel allocator works.  If this doesn't happen,
;I don't know what the result will be.  I don't know what will
;happen if we open it on a different channel.
	move a,filchn(b);get latest channel
	pop p,c		;get back old (output) fcb
	movem a,filchn(c);put this channel into output
	move a,filbfp(b);merge the buffer headers
	ior a,filbfp(c)
	ldb t,[point 4,filchn(b),12]
	calli t,131	;mvhdr.
	  0		;error
return:	pop p,a		;return address
	subi p,1	;last argument was pushed onto the stack, too
	jrst (a)

	end