xref: /csrg-svn/old/as.vax/asio.c (revision 16070)
1 /*
2  *	Copyright (c) 1982 Regents of the University of California
3  */
4 #ifndef lint
5 static char sccsid[] = "@(#)asio.c 4.5 02/17/84";
6 #endif not lint
7 
8 #include <stdio.h>
9 #include "as.h"
10 /*
11  *	Block I/O routines for logical I/O concurrently in
12  *	more than one place in the same file.
13  */
14 int	biofd;			/* file descriptor for block I/O file */
15 int	biobufsize;		/* optimal block size for I/O */
16 off_t	boffset;		/* physical position in logical file */
17 BFILE	*biobufs;		/* the block I/O buffers */
18 
19 #define	error(severity, message) \
20 	{yyerror(message); if (severity) delexit();}
21 
22 Flushfield(n)
23 	register int n;
24 {
25 	while (n>0) {
26 		outb(bitfield);
27 		bitfield >>= 8;
28 		n -= 8;
29 	}
30 	bitoff=0;
31 	bitfield=0;
32 }
33 
34 /*
35  *	Block I/O Routines
36  */
37 bopen(bp, off)
38 	struct biobuf *bp;
39 	off_t	off;
40 {
41 
42 	bp->b_ptr = bp->b_buf = Calloc(1, biobufsize);
43 	bp->b_nleft = biobufsize - (off % biobufsize);
44 	bp->b_off = off;
45 	bp->b_link = biobufs;
46 	biobufs = bp;
47 }
48 
49 int	bwrerror;
50 
51 bwrite(p, cnt, bp)
52 	register char *p;
53 	register int cnt;
54 	register struct biobuf *bp;
55 {
56 	register int put;
57 	register char *to;
58 
59 top:
60 	if (cnt == 0)
61 		return;
62 	if (bp->b_nleft) {
63 		put = bp->b_nleft;
64 		if (put > cnt)
65 			put = cnt;
66 		bp->b_nleft -= put;
67 		to = bp->b_ptr;
68 #ifdef lint
69 		*to = *to;
70 #endif lint
71 		asm("movc3 r8,(r11),(r7)");
72 		bp->b_ptr += put;
73 		p += put;
74 		cnt -= put;
75 		goto top;
76 	}
77 	if (cnt >= biobufsize) {
78 		if (bp->b_ptr != bp->b_buf)
79 			bflush1(bp);
80 		put = cnt - cnt % biobufsize;
81 		if (boffset != bp->b_off)
82 			(void)lseek(biofd, (long)bp->b_off, 0);
83 		if (write(biofd, p, put) != put) {
84 			bwrerror = 1;
85 			error(1, "Output write error");
86 		}
87 		bp->b_off += put;
88 		boffset = bp->b_off;
89 		p += put;
90 		cnt -= put;
91 		goto top;
92 	}
93 	bflush1(bp);
94 	goto top;
95 }
96 
97 bflush()
98 {
99 	register struct biobuf *bp;
100 
101 	if (bwrerror)
102 		return;
103 	for (bp = biobufs; bp; bp = bp->b_link)
104 		bflush1(bp);
105 }
106 
107 bflush1(bp)
108 	register struct biobuf *bp;
109 {
110 	register int cnt = bp->b_ptr - bp->b_buf;
111 
112 	if (cnt == 0)
113 		return;
114 	if (boffset != bp->b_off)
115 		(void)lseek(biofd, (long)bp->b_off, 0);
116 	if (write(biofd, bp->b_buf, cnt) != cnt) {
117 		bwrerror = 1;
118 		error(1, "Output write error");
119 	}
120 	bp->b_off += cnt;
121 	boffset = bp->b_off;
122 	bp->b_ptr = bp->b_buf;
123 	bp->b_nleft = biobufsize;
124 }
125 
126 bflushc(bp, c)
127 	register struct biobuf *bp;
128 	char	c;
129 {
130 	bflush1(bp);
131 	bputc(c, bp);
132 }
133