BSD 3 development
[unix-history] / usr / src / cmd / px / 35iosubs.s
CommitLineData
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
87stdin:
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
101stdout:
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
115stderr:
116 .word 0 #file window element
117
118tmpname:.byte 't,'m,'p,'.,'X,'X,'X,'X,'X,'X, 0
119 .text
120sinnam: .byte 's,'t,'a,'n,'d,'a,'r,'d,' ,'i,'n,'p,'u,'t, 0
121soutnam:.byte 's,'t,'a,'n,'d,'a,'r,'d,' ,'o,'u,'t,'p,'u,'t, 0
122msgnam: .byte 'M,'e,'s,'s,'a,'g,'e,' ,'f,'i,'l,'e, 0
123monout: .byte 'p,'m,'o,'n,'.,'o,'u,'t, 0
124rdopen: .byte 'r, 0
125wtopen: .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
154l3501:
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
166l3502:
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
170l3503:
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
183l3504:
184 movl r1,r6 #advance previous
185 movl FCHAIN(r1),r1 #get next
186l3505:
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#
198gotone:
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
205l3506:
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
221eclose:
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#
229setname:
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#
246l3508:
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
250l3509:
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#
258l3511:
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
264l3512:
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
268l3513:
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
287l3523:
288 ret
289erefinaf:
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
317l3514:
318 movw r6,FUNIT(r7) #update status flags
319l3515:
320 ret
321eof:
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
328eread:
329 movw $EREADIT,_perrno
330 moval error,PC(fp) #error return
331 ret
332epeof:
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
346l3526:
347 ret
348#
349# flush all active output files
350#
351_pflush:
352 .word R6
353 movl _fchain,r6
354 beql l3518
355l3516:
356 bbc $fWRITE,FUNIT(r6),l3517
357 pushl FBUF(r6)
358 calls $1,_fflush
359l3517:
360 movl FCHAIN(r6),r6
361 bneq l3516
362l3518:
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
371l3519:
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
379l3525:
380 subl3 $recsze, r7,-(sp)
381 movl FCHAIN( r7), r7
382 calls $1,_pfree
383 tstl r7
384 bneq l3519
385l3520:
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
410l3521:
411 ret
412l3522:
413 pushal monout
414 calls $1,_perror
415 ret