Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-04 - decus/20-0110/ptypkg.sai
There are 2 other files named ptypkg.sai in the archive. Click here to see a list.
Entry;
COMMENT
.SEC(PTYPKG.SAI - pseudo teletype package)
.index(PTYPKG.SAI - pseudo teletype package)
.;
Begin "PTYPKG.SAI"

Define # = "Comment";

Comment	


	Pseudo Teletype package for use with NIH SAIL
	---------------------------------------------


	Ron Black and Peter Lemkin*
	DCRT
	National Institutes of Health
	Bethesda, Md. 20014

	*Image Processing Unit
	Division of Cancer Biology and Diagnosis
	National Cancer Institute
	National Institutes of Health
	Bethesda, Md. 20014

	Purpose
	-------
	This package consists of all the  procedures  necessary
to  acquire  and  use a pseudo teletype channel called PTY from
SAIL.
To use this package, include a

	REQUIRE "PTYPKG.REQ" SOURCE!FILE

in your program.

	Procedure calls
	---------------
	This file contains four procedures for  using  a  PTY  from  a  sail
program.  The  four  procedures require several global variables and
macro definitions Defined in ptydec.Sai.

[1]	Integer Procedure GETPTY -  gets a PTY and I/O channel
		this procedure tries to open a PTY
		and returns the following values

			-2 if no PTY's are available
			-1 if no channels are available
			otherwise it returns the channel number
			for the PTY

[2]	Integer Procedure PTYSTS -  gets the status of the PTY.
		this procedure should be called before every
		Input or output to a PTY, since a single call
		To INPPTY may not get all the input from the
		PTY.  this procedure returns true if it's ok to
		do  an output to PTY false if program should do
		an input on PTY.

[3]	String Procedure INPPTY -  inputs a string from the PTY
		where the maximum length of the string is ptycnt.

[4]	Procedure  OUTPTY(String  str)  -  will output a string
		'str' to the PTY.

The calling conventions for each procedure is described
in the code

;
Integer ptychn, popblk, ptobuf, ptibuf, i;

COMMENT
.NEXT PAGE
.SS(PTYPKG MACRO DEFINITIONS)
.INDEX(PTYPKG MACRO DEFINITIONS)
.;
Internal Integer PSTATUS;

Comment some useful macros;

"PTYINP is true when program can do a INPPTY"
Define	PTYINP="PSTATUS land '40000000000 neq 0";

"PTYOUT is true when program can do a OUTPTY"
Define PTYOUT="PSTATUS land '20000000000 neq 0";

Define CALLI="'47000000000";
Define P='17;
Define Crlf="'15&'12";


Comment  ptybuf  is  where we store characters when reading the
PTY.  Ptycnt is the number of characters that can be read by  a
single  call  to  OUTPTY.   To change this merely change ptycnt
which is an assembly conditional;

Define ptycnt=200;
Integer Array ptybuf[1:ptycnt/5];
COMMENT
.next page
.ss(Procedure INPPTY)
.index(Procedure INPPTY)
.;
Internal String Procedure INPPTY;
Comment
-------------------------------------
this  proceTdure  gets a string from the PTY and returns it. It
will return either (1) when the buffer is filled  or  when  the
PTY msg is completed;

Begin "INPPTY"

Label error, chk, all!done, loop, getbuf, inins, stsins;
String s;

Comment characters from the PTY will be put into 
ptybuf (5 characters per word);

"	zero buffers"
ARRCLR(ptybuf);
s_null;

Start!Code;
Comment set up String pointer to ptybuf;
	HRLI	1,'440700;
	HRR	1,ptybuf;

Comment register 2 points to input buffer ring;

	MOVE 	2,ptibuf;

Comment register  6  is  a  counter,  we  can  only  input  200
characters at a time (due to ptycnt);

	SETZM	6;
loop:
	SOSGE	2(2); Comment any characters there?;
	JRST getbuf; Comment no, get a buffer;
	ILDB 	3,1(2); Comment load a char from buffer;
	JUMPE	3,loop; Comment ignore nulls;
	IDPB	3,1; Comment put it into ptybuf;
	AOS	6; Comment  increment our count;
	CAIG	6,ptycnt; Comment have we reached ptycnt?;
	JRST 	Loop; Comment no get another char;
	JRST 	all!done; Comment yes, all finished;

Comment get a buffer from the monitor;

getbuf:
	SKIPA	4,ptychn;
inins:	IN 0,;
	LSH	4,23;
	ADD 	4,inins;
	XCT 	4; Comment do an input UUO;
	JRST 	Chk; Comment check to make sure buffer isn't empty;

Comment enter here when we get an error on input UUO;

	JRST error;

Comment if count of buffer is 0, all finished;
chk: SKIPE	2(2);
	JRST loop; Comment buffer has something;
	JRST all!done; Comment buffer is empty, all finished;
End;

error:
outstr("Error while inputting to PTY STATUS bits -- "&
	cvos(GETSTS(ptychn))&crlf);
Return(null);

Comment now take characters in ptybuf and make them into a real
string. Convert the 7-bit buffer to SAIL string.;
all!done:
For i_1 Step 1 Until ptycnt/5 Do
	s_s&cvstr(ptybuf[i]);
Return(s);
End "INPPTY";
COMMENT
.next page
.ss(Procedure OUTPTY)
.index(Procedure OUTPTY)
.;
Internal Procedure OUTPTY(String str);

Comment
------------------------------------------------
this procedure outputs the string str to the pty;

Begin "PTYOUT"

Label  all!done, loop, put, putbuf, outins, otfail;
String mystr;
Integer len;

"	Get the string length and copy the string to be sent"
len_length((mystr_str));

"	Set up the pointers"
Start!Code;
	MOVE 1,len;
	MOVE 2,mystr;
	MOVE	4,ptobuf;

Comment register 1 has length of String, 2 has byte pointer
	And 4 has address of output buffer ring
	Register 3 will be used to store chars as
	We get them from the string;

loop: ILDB	3,2; Comment get a charcter from the string;
	PUSHJ	P,put;	Comment now output it;
	SOSLE	1; Comment subtract one from length;
	JRST 	Loop; Comment get another;
	PUSHJ	P,putbuf; Comment all finished, output buffer;
	JRST 	all!done;

Comment routine to output a character to pty;
put:
	Sosg	2(4); Comment check count;
	PUSHJ	P,putbuf; Comment no room in buffer, output buf first;
	IDPB	3,1(4); Comment put char in buffer;
	POPJ	P,; Comment Return;

Comment Do an output UUO to flush buffer;
putbuf:
	SKIPA 	5,ptychn;
outins:	OUT	0,;
	LSH 	5,23;
	ADD	5,outins;
	XCT	5; Comment output UUO instruction;
	POPJ	P,; Comment Return;

Comment fall through here on error on output;
	JRST	otfail;

"	Successful output"
	End;
all!done:
Return;

"	output error"
otfail:
outstr ("Error while outputting to PTY STATUS bits -- "&
	cvos(GETSTS(ptychn))&crlf);
End "PTYOUT";
COMMENT
.next page
.ss(Procedure PTYSTS)
.index(Procedure PTYSTS)
.;
Internal Integer Procedure PTYSTS;

Comment 
------------------------
this procedure returns 
true  if it's ok to Do an output to pty
false if program should Do an input on pty
note:
	The PTY may not be ready For input, 
	And may have nothing to output.  In 
	This case, loop using hibernate UUO to wake every
	Five seconds or when PTY STATUS
	Changes;

Begin "PTYSTS"
Label hiber;

While true Do 
	Begin "loop"

Comment this code Does  a  JOBSTS  UUO  which  we  can  use  to
	determine the state of the pty;

	Quick!Code;
	PUSH	P,1;
	MOVE	1,ptychn;
	CALLI 1,'61;
	JRST 4,0;
	MOVEM	1,PSTATUS;
	POP	P,1;
	End;

Comment PSTATUS now has JOBSTS ;

	If PTYINP 
		Then Return(false)
		Else If PTYOUT 
			Then Return(true)
			Else Quick!Code;
Comment hibernate For 5 seconds or Until PTY changes PSTATUS;
			PUSH	P,1;
			MOVSI 1,'40;
			HRRI 	1,5000;
hiber:			CALLI	1,'72;
			JRST 4,0;
			POP	P,1;
			End;
End "loop";
End "PTYSTS";
COMMENT
.next page
.ss(Procedure GETSTS)
.index(Procedure GETSTS)
.;
Internal Integer Procedure GETPTY; 

Comment
-------------------------

This  procedure  tries  to open a pty and returns the following
values:

	-2 if no PTY's are available
	-1 if no channels are available
	otherwise it returns the channel number for the pty;

Begin "GETPTY"
Integer j;
Label foo;

If (ptychn_GETCHAN) < 0 Then Return(-1);

"	open ASCII PTY"
j_-1;
OPEN(ptychn,"PTY",0,1,1,100,0,j);
If j neq 0  Then Return(-2);

popblk_CHNCDB(ptychn); Comment get open block;

Comment  we  have opened a PTY successfully, now get open block
using sail call CHNCDB. From the open block we have the address
of  the  input  and output buffer ring, save these addresses in
ptibuf, and ptobuf respectively;

Start!Code;
foo:	MOVE 1,popblk;
	MOVE 2,2(1);
	HRRM 2,ptibuf;
	HLRM 2,ptobuf;
End;

OUTPTY('15&'12); Comment prime pty;

Return (ptychn);
End "GETPTY";

End "PTYPKG.SAI";