.globl _getname #activate a file
.globl _unit #establish active file
.globl _iosync #syncronize a file window
.globl _unsync #push backed synced record for formatted read
.globl _pflush #flush all active files
.globl _pclose #close selected files
.globl _pmflush #flush pxp buffer
.set fnamesze,76 #maximum size of file name
.set recsze,30+fnamesze #file record size
.set FNAME,-recsze #name of associated UNIX file
.set LCOUNT,-30 #number of lines of output
.set LLIMIT,-26 #maximum number of text lines
.set FBUF,-22 #FILE pointer
.set FCHAIN,-18 #chain to next file
.set FLEV,-14 #ptr to associated file variable
.set PFNAME,-10 #ptr to name of error msg file
.set FUNIT,-6 #file status flags
.set FSIZE,-4 #size of elements in the file
.set WINDOW,0 #file window element
.set FDEF,0x8000 #1 => reserved file name
.set FTEXT,0x4000 #1 => text file, process EOLN
.set FWRITE,0x2000 #1 => open for writing
.set FREAD,0x1000 #1 => open for reading
.set TEMP,0x0800 #1 => temporary file
.set SYNC,0x0400 #1 => window is out of sync
.set EOLN,0x0200 #1 => at end of line
.set EOF,0x0100 #1 => at end of file
# bit positions of unit flags
.set ioEOF,4 #bit position flagging EOF
.set ioERR,5 #bit position flagging I/O error
.set FLAG,12 #record offset of error flag
.space fnamesze #name of associated UNIX file
.long __iob #FILE pointer
.long stdout #chain to next file
.long 0 #ptr to associated file variable
.long sinnam #ptr to name of error msg file
.word FTEXT+FREAD+SYNC #file status flags
.long 1 #size of elements in the file
.word 0 #file window element
.space fnamesze #name of associated UNIX file
.long __iob+16 #FILE pointer
.long stderr #chain to next file
.long 0 #ptr to associated file variable
.long soutnam #ptr to name of error msg file
.word FTEXT+FWRITE+EOF #file status flags
.long 1 #size of elements in the file
.word 0 #file window element
.space fnamesze #name of associated UNIX file
.long __iob+32 #FILE pointer
.long 0 #chain to next file
.long 0 #ptr to associated file variable
.long msgnam #ptr to name of error msg file
.word FTEXT+FWRITE #file status flags
.long 1 #size of elements in the file
.word 0 #file window element
tmpname:.byte 't,'m,'p,'.,'X,'X,'X,'X,'X,'X, 0
sinnam: .byte 's,'t,'a,'n,'d,'a,'r,'d,' ,'i,'n,'p,'u,'t, 0
soutnam:.byte 's,'t,'a,'n,'d,'a,'r,'d,' ,'o,'u,'t,'p,'u,'t, 0
msgnam: .byte 'M,'e,'s,'s,'a,'g,'e,' ,'f,'i,'l,'e, 0
monout: .byte 'p,'m,'o,'n,'.,'o,'u,'t, 0
# takes the width of a string in the subopcode and
# returns a pointer to a file structure in r0
# there should be a string on the stack
# of length the contents of subopcode on top of
# a pointer to the file variable
# a new file structure is allocated if needed
# temporary names are generated, and given
# names are blank trimmed
# if a new file buffer is allocated, the address
# is stored in the file variable.
cvtbl (r10)+, r8 # r8 has file name length
moval 4(ap), r9 # r9 will point to cleared stack
movl ( r9)+, r11 # r11 pts to file variable
tstl ( r11) #check for existing file record
# allocate and initialize a new file record
clrl r7 # r7 has status flags
cvtwl (r10)+,r6 #r6 has data size
movw $FTEXT, r7 #default to text file
addl3 $recsze,r6,-(sp)#size of record
calls $1,_palloc #r0 points to allocated buffer
addl2 $recsze,r0 #adjust to base of record
clrl LCOUNT(r0) #set default line limits
movw r7,FUNIT(r0) #set flags
movl r6,FSIZE(r0) #set size
movl r11,FLEV(r0) #set ptr to file variable
movl r0,( r11) #set file var ptr
# link the new record into the file chain
movl $_fchain-FCHAIN,r6 #r6 pts to "previous" record
movl _fchain,r1 #r1 pts to "next" record
movl r1,r6 #advance previous
movl FCHAIN(r1),r1 #get next
cmpl FLEV(r1), r11 #check level
blssu l3504 #continue until greater
movl r1,FCHAIN(r0) #link in new record
movl r0, r11 # r11 points to file record
# have a previous buffer, dispose of associated file
addl2 $2,r10 #discard data size
movl ( r11), r11 # r11 points to file record
bicw2 $~(FDEF+TEMP+FTEXT),FUNIT( r11) #clear status flags
bbc $fDEF,FUNIT( r11),l3506 #check for predefined file
bicw2 $FDEF,FUNIT( r11) #clear predefined flag
pushl FBUF( r11) #flush and close previous file
bbs $ioERR,FLAG(r0),eclose
bbc $fTEMP,FUNIT( r11),setname #check for temp file
tstl r8 #remove renamed temp files
tstl r0 #check for remove error
moval error,PC(fp) #error return
moval error,PC(fp) #error return
# get the filename associated with the buffer
tstl r8 #check for a given name
bneq l3508 #br => has a name
tstb FNAME( r11) #check for no current name
bneq l3513 #br => had a previous name so use it
# no name given and no previous name, so generate
# a new one of the form tmp.xxxxxx
bisw2 $TEMP,FUNIT( r11)#set status to temporary
pushal tmpname #get a unique temp name
movl $13, r8 #max length of temp name
# name is given, strip trailing blanks
bicw2 $TEMP,FUNIT( r11)#set permanent status
moval 4(ap),r0 #r0 pts to end of file name
addl3 r8,r0,r1 #r1 pts to end of name
cmpb -(r1),$blank #delete trailing blanks
bneq l3511 #(note: could use "scanc" with source
clrb (r1) # and table reversed)
# put the new name into the structure
cmpl r8,$fnamesze #check for name too long
moval error,PC(fp) #error return
movc3 r8,(r0),FNAME( r11) #move name into record
clrb FNAME( r11)[ r8] #place null char after name
moval FNAME( r11),PFNAME( r11) #set pointer to name
movl r9,r1 #return ptr to updated stack
movl r11,r0 #return ptr to file record
# unit establishes a new active file
bbs $fDEF,FUNIT(r7),erefinaf
cmpl r7,$stdin #flush stdout if activating stdin
cmpw _bufopt,$1 # and stdout is line buffered
moval error,PC(fp) #error return
# iosync insures that a useable image is in the buffer window
cvtwl FUNIT(r7),r6 #r6 has FUNIT flags
bbc $fREAD,r6,eread #error if not open for reading
bbc $fSYNC,r6,l3515 #check for already synced
bbs $fEOF,r6,epeof #error if past EOF
bicw2 $SYNC,r6 #clear unsynced flag
pushl $1 #number of items to read
pushl FSIZE(r7) #data size
pushl r7 #ptr to input window
movl FBUF(r7),r0 #check for EOF
bbs $ioERR,FLAG(r0),epeof
bbc $fTEXT,r6,l3514 #check for text processing
bicw2 $EOLN,r6 #check for EOLN
movb $blank,(r7) #blank out linefeed
movw r6,FUNIT(r7) #update status flags
movw r6,FUNIT(r7) #update status flags
pushr $R2|R3|R4|R5 #save registers
movc5 $0,(r0),$0,FSIZE(r7),(r7) #clear buffer to undefined
popr $R2|R3|R4|R5 #restore registers
moval error,PC(fp) #error return
moval error,PC(fp) #error return
# push back last char read to prepare for formatted read
bbc $fREAD,FUNIT(r7),eread #error if not open for reading
bbs $fSYNC,FUNIT(r7),l3526 #push back window char
# flush all active output files
bbc $fWRITE,FUNIT(r6),l3517
# close all active files down to the specified FLEV
bbs $fDEF,FUNIT( r7),l3525
jbs $ioERR,FLAG(r6),eclose
bbs $ioERR,FLAG(r6),l3522
bbs $ioERR,FLAG(r6),l3522