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