Commit | Line | Data |
---|---|---|
3f14b03d CH |
1 | #\f |
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 |