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