|
|
1.1 root 1: #
2: # Copyright (c) 1979 Regents of the University of California
3: #
4: # char sccsid[] = "@(#)35iosubs.s 4.2 10/16/80";
5: #
6: # IO SUBROUTINES
7: #
8: .globl _getname #activate a file
9: .globl _unit #establish active file
10: .globl _iosync #syncronize a file window
11: .globl _unsync #push backed synced record for formatted read
12: .globl _pflush #flush all active files
13: .globl _pclose #close selected files
14: .globl _pmflush #flush pxp buffer
15: #
16: # system I/O routines
17: #
18: .globl _fclose
19: .globl _fflush
20: .globl _fopen
21: .globl _fprintf
22: .globl _fputc
23: .globl _fread
24: .globl _fscanf
25: .globl _fwrite
26: .globl _mktemp
27: .globl _rewind
28: .globl _setbuf
29: .globl _ungetc
30: .globl _unlink
31: #
32: # standard files
33: #
34: # file records
35: #
36: .set fnamesze,76 #maximum size of file name
37: .set recsze,30+fnamesze #file record size
38: .set FNAME,-recsze #name of associated UNIX file
39: .set LCOUNT,-30 #number of lines of output
40: .set LLIMIT,-26 #maximum number of text lines
41: .set FBUF,-22 #FILE pointer
42: .set FCHAIN,-18 #chain to next file
43: .set FLEV,-14 #ptr to associated file variable
44: .set PFNAME,-10 #ptr to name of error msg file
45: .set FUNIT,-6 #file status flags
46: .set FSIZE,-4 #size of elements in the file
47: .set WINDOW,0 #file window element
48: #
49: # unit flags
50: #
51: .set FDEF,0x8000 #1 => reserved file name
52: .set FTEXT,0x4000 #1 => text file, process EOLN
53: .set FWRITE,0x2000 #1 => open for writing
54: .set FREAD,0x1000 #1 => open for reading
55: .set TEMP,0x0800 #1 => temporary file
56: .set SYNC,0x0400 #1 => window is out of sync
57: .set EOLN,0x0200 #1 => at end of line
58: .set EOF,0x0100 #1 => at end of file
59: #
60: # bit positions of unit flags
61: #
62: .set fDEF,15
63: .set fTEXT,14
64: .set fWRITE,13
65: .set fREAD,12
66: .set fTEMP,11
67: .set fSYNC,10
68: .set fEOLN,9
69: .set fEOF,8
70: #
71: # standard file buffers
72: #
73: .set ioEOF,4 #bit position flagging EOF
74: .set ioERR,5 #bit position flagging I/O error
75: .set FLAG,12 #record offset of error flag
76: #
77: # standard input file
78: #
79: .data
80: .space fnamesze #name of associated UNIX file
81: .long 0 #line count
82: .long 0 #line limit
83: .long __iob #FILE pointer
84: .long stdout #chain to next file
85: .long 0 #ptr to associated file variable
86: .long sinnam #ptr to name of error msg file
87: .word FTEXT+FREAD+SYNC #file status flags
88: .long 1 #size of elements in the file
89: stdin:
90: .word 0 #file window element
91: #
92: # standard output file
93: #
94: .space fnamesze #name of associated UNIX file
95: .long 0 #line count
96: .long 0 #line limit
97: .long __iob+16 #FILE pointer
98: .long stderr #chain to next file
99: .long 0 #ptr to associated file variable
100: .long soutnam #ptr to name of error msg file
101: .word FTEXT+FWRITE+EOF #file status flags
102: .long 1 #size of elements in the file
103: stdout:
104: .word 0 #file window element
105: #
106: # standard error file
107: #
108: .space fnamesze #name of associated UNIX file
109: .long 0 #line count
110: .long 0 #line limit
111: .long __iob+32 #FILE pointer
112: .long 0 #chain to next file
113: .long 0 #ptr to associated file variable
114: .long msgnam #ptr to name of error msg file
115: .word FTEXT+FWRITE #file status flags
116: .long 1 #size of elements in the file
117: stderr:
118: .word 0 #file window element
119:
120: tmpname:.byte 't,'m,'p,'.,'X,'X,'X,'X,'X,'X, 0
121: .text
122: sinnam: .byte 's,'t,'a,'n,'d,'a,'r,'d,' ,'i,'n,'p,'u,'t, 0
123: soutnam:.byte 's,'t,'a,'n,'d,'a,'r,'d,' ,'o,'u,'t,'p,'u,'t, 0
124: msgnam: .byte 'M,'e,'s,'s,'a,'g,'e,' ,'f,'i,'l,'e, 0
125: monout: .byte 'p,'m,'o,'n,'.,'o,'u,'t, 0
126: rdopen: .byte 'r, 0
127: wtopen: .byte 'w, 0
128: .set formfeed,12
129: .set linefeed,10
130: .set blank,'
131: #
132: # getname
133: #
134: # takes the width of a string in the subopcode and
135: # returns a pointer to a file structure in r0
136: #
137: # there should be a string on the stack
138: # of length the contents of subopcode on top of
139: # a pointer to the file variable
140: #
141: # a new file structure is allocated if needed
142: # temporary names are generated, and given
143: # names are blank trimmed
144: #
145: # if a new file buffer is allocated, the address
146: # is stored in the file variable.
147: #
148: #
149: _getname: #(datasze, maxnamlen, name, fileptr)
150: #int datasze;
151: #int maxnamlen;
152: #char *name;
153: #struct file **fileptr;
154:
155: .word R6|R7|R8|R9
156: movl 4(ap),r6 #r6 has data size
157: movl 12(ap), r8 # r8 points to file name
158: movl 16(ap), r9 # r9 pts to file variable
159: tstl ( r9) #check for existing file record
160: bneq gotone
161: #
162: # allocate and initialize a new file record
163: #
164: clrl r7 # r7 has status flags
165: tstl r6 #check for size
166: bneq l3502
167: movw $FTEXT, r7 #default to text file
168: movl $1,r6 #default size
169: l3502:
170: addl3 $recsze,r6,-(sp)#size of record
171: calls $1,_palloc #r0 points to allocated buffer
172: addl2 $recsze,r0 #adjust to base of record
173: clrl LCOUNT(r0) #set default line limits
174: movl _llimit,LLIMIT(r0)
175: movw r7,FUNIT(r0) #set flags
176: movl r6,FSIZE(r0) #set size
177: movl r9,FLEV(r0) #set ptr to file variable
178: movl r0,( r9) #set file var ptr
179: #
180: # link the new record into the file chain
181: #
182: movl $_fchain-FCHAIN,r6 #r6 pts to "previous" record
183: movl _fchain,r1 #r1 pts to "next" record
184: brb l3505
185: l3504:
186: movl r1,r6 #advance previous
187: movl FCHAIN(r1),r1 #get next
188: l3505:
189: cmpl FLEV(r1), r9 #check level
190: blssu l3504 #continue until greater
191:
192: movl r1,FCHAIN(r0) #link in new record
193: movl r0,FCHAIN(r6)
194:
195: movl r0, r9 # r9 points to file record
196: jbr setname
197: #
198: # have a previous buffer, dispose of associated file
199: #
200: gotone:
201: movl ( r9), r9 # r9 points to file record
202: bicw2 $~(FDEF+TEMP+FTEXT),FUNIT( r9) #clear status flags
203: bbc $fDEF,FUNIT( r9),l3506 #check for predefined file
204: bicw2 $FDEF,FUNIT( r9) #clear predefined flag
205: jbr setname
206: l3506:
207: pushl FBUF( r9) #flush and close previous file
208: calls $1,_fclose
209: movl FBUF( r9),r0
210: bbs $ioERR,FLAG(r0),eclose
211: bbc $fTEMP,FUNIT( r9),setname #check for temp file
212: tstl r8 #remove renamed temp files
213: beql setname
214: pushl PFNAME( r9)
215: calls $1,_unlink
216: tstl r0 #check for remove error
217: beql setname
218: eunlink:
219: movl PFNAME( r9),_file
220: movw $EREMOVE,_perrno
221: moval error,PC(fp) #error return
222: ret
223: eclose:
224: movl PFNAME( r9),_file
225: movw $ECLOSE,_perrno
226: moval error,PC(fp) #error return
227: ret
228: #
229: # get the filename associated with the buffer
230: #
231: setname:
232: tstl r8 #check for a given name
233: bneq l3508 #br => has a name
234: tstb FNAME( r9) #check for no current name
235: bneq l3513 #br => had a previous name so use it
236: #
237: # no name given and no previous name, so generate
238: # a new one of the form tmp.xxxxxx
239: #
240: bisw2 $TEMP,FUNIT( r9)#set status to temporary
241: pushal tmpname #get a unique temp name
242: calls $1,_mktemp
243: movl r0, r8 #ptr to new temp name
244: movl $16,r2 #maximum name length
245: brb l3512
246: #
247: # put the new name into the structure
248: #
249: l3508:
250: bicw2 $TEMP,FUNIT( r9) #set permanent status
251: locc $blank,8(ap),( r8) #check for trailing blanks
252: subl3 r0,8(ap),r2 #deduct length of blanks
253: cmpl r2,$fnamesze #check for name too long
254: bgeq enamsze
255: l3512:
256: movc3 r2,( r8),FNAME( r9) #move name into record
257: clrb (r3) #place zero after name
258: moval FNAME( r9),PFNAME( r9) #set pointer to name
259: l3513:
260: movl r9,r0 #return ptr to file record
261: ret
262: enamsze:
263: movw $ENAMESIZE,_perrno
264: moval error,PC(fp) #error return
265: ret
266: #
267: # unit establishes a new active file
268: #
269: _unit:
270: .word 0
271: movl 4(ap),r7
272: beql erefinaf
273: bbs $fDEF,FUNIT(r7),erefinaf
274: movl PFNAME(r7),_file
275: ret
276: erefinaf:
277: movw $EREFINAF,_perrno
278: moval error,PC(fp) #error return
279: ret
280: #
281: # iosync insures that a useable image is in the buffer window
282: #
283: _iosync:
284: .word R6
285: cvtwl FUNIT(r7),r6 #r6 has FUNIT flags
286: bbc $fREAD,r6,eread #error if not open for reading
287: bbc $fSYNC,r6,l3515 #check for already synced
288: bbs $fEOF,r6,epeof #error if past EOF
289: bicw2 $SYNC,r6 #clear unsynced flag
290: pushl FBUF(r7) #stream
291: pushl $1 #number of items to read
292: pushl FSIZE(r7) #data size
293: pushl r7 #ptr to input window
294: calls $4,_fread
295: movl FBUF(r7),r0 #check for EOF
296: bbs $ioERR,FLAG(r0),epeof
297: bbs $ioEOF,FLAG(r0),eof
298: bbc $fTEXT,r6,l3514 #check for text processing
299: bicw2 $EOLN,r6 #check for EOLN
300: cmpb (r7),$linefeed
301: bneq l3514
302: movb $blank,(r7) #blank out linefeed
303: bisw2 $EOLN,r6
304: l3514:
305: movw r6,FUNIT(r7) #update status flags
306: l3515:
307: ret
308: eof:
309: bisw2 $EOF,r6 #set EOF
310: movw r6,FUNIT(r7) #update status flags
311: pushr $R2|R3|R4|R5 #save registers
312: movc5 $0,(r0),$0,FSIZE(r7),(r7) #clear buffer to undefined
313: popr $R2|R3|R4|R5 #restore registers
314: ret
315: eread:
316: movw $EREADIT,_perrno
317: moval error,PC(fp) #error return
318: ret
319: epeof:
320: movw $EPASTEOF,_perrno
321: moval error,PC(fp) #error return
322: ret
323: #
324: # push back last char read to prepare for formatted read
325: #
326: _unsync:
327: .word 0
328: bbc $fREAD,FUNIT(r7),eread #error if not open for reading
329: bbs $fSYNC,FUNIT(r7),l3526 #push back window char
330: pushl FBUF(r7)
331: cvtbl (r7),-(sp)
332: calls $2,_ungetc
333: l3526:
334: ret
335: #
336: # flush all active output files
337: #
338: _pflush:
339: .word R6
340: movl _fchain,r6
341: beql l3518
342: l3516:
343: bbc $fWRITE,FUNIT(r6),l3517
344: pushl FBUF(r6)
345: calls $1,_fflush
346: l3517:
347: movl FCHAIN(r6),r6
348: bneq l3516
349: l3518:
350: ret
351: #
352: # close all active files down to the specified FLEV
353: #
354: _pclose:
355: .word R6|R9
356: movl _fchain, r9
357: beql l3520
358: l3519:
359: cmpl FLEV( r9),4(ap)
360: bgtru l3520
361: bbs $fDEF,FUNIT( r9),l3525
362: movl FBUF( r9),r6
363: beql l3525
364: pushl r6
365: calls $1,_fclose
366: jbs $ioERR,FLAG(r6),eclose
367: bbc $fTEMP,FUNIT( r9),l3525
368: pushl PFNAME( r9) #remove TEMP files
369: calls $1,_unlink
370: tstl r0
371: jneq eunlink
372: l3525:
373: subl3 $recsze, r9,-(sp)
374: movl FCHAIN( r9), r9
375: calls $1,_pfree
376: tstl r9
377: bneq l3519
378: l3520:
379: movl r9,_fchain
380: ret
381: #
382: # write out the pxp data
383: #
384: _pmflush:
385: .word R6
386: tstl _pxpbuf
387: beql l3521
388: pushal wtopen
389: pushal monout
390: calls $2,_fopen
391: tstl r0
392: beql l3522
393: movl r0,r6
394: pushl r6
395: pushl $1
396: pushl _pxpsize
397: pushl _pxpbuf
398: calls $4,_fwrite
399: bbs $ioERR,FLAG(r6),l3522
400: pushl r6
401: calls $1,_fclose
402: bbs $ioERR,FLAG(r6),l3522
403: l3521:
404: ret
405: l3522:
406: pushal monout
407: calls $1,_perror
408: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.