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