1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-23 07:32:50 +00:00
Files
rcornwell.sims/SEL32/taptools/mpxblk.c
2019-07-23 20:37:41 -04:00

175 lines
5.5 KiB
C

/*
* mpxblk.c
*
* This program converts a unix/dos ascii file to an mpx blocked file
* trailing blanks are not deleted from the source file
* input - stdin
* output - stdout
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MPXMAX 254
int mpxbb();
int getloi();
#define BLKSIZE 768
int main (argc, argv)
int argc;
char *argv[];
{
char s[MPXMAX];
int i;
int fn = fileno(stdout);
while (1) {
if ((i = getloi(s, MPXMAX)) == 0) {
mpxbb(fn, s, 0, 1); /* last write to output */
exit(0);
}
if (i == 1 && s[0] == '\n')
s[0] = ' '; /* replace single n/l with blank */
if (s[i-1] == '\n')
i--; /* remove trailing n/l */
if (mpxbb(fn, s, i, 0) < 0) { /* last data record out */
fprintf(stderr, "output file error\n");
exit(1);
}
}
}
/* get a line of input. */
/* terminate line on \n or \r\n */
/* allow max of 254 chars in a line */
int getloi(s, lim)
char s[];
int lim;
{
int c, i;
for(i = 0; --lim > 0; ) {
c = getchar();
switch (c) {
case '\n':
/* terminate on \n */
s[i++] = c;
goto linedone;
case '\r':
c = getchar();
/* terminate on \r\n */
if (c == '\n') {
s[i++] = c;
goto linedone;
}
/* put back the character */
ungetc(c, stdin);
/* output the \r to the stream */
c = '\r';
/* drop through */
default:
s[i++] = c;
break;
case EOF:
return (0);
break;
}
}
linedone:
return (i);
}
/*
** output line of text from the source
*/
static unsigned char bb[BLKSIZE]; /* blocking buffer */
static char first = 0; /* 1st time thru flag */
/*
* mpxbb - make up mpx block file output
* input - buffer address
* - byte count
* - last write flag
*/
int
mpxbb(fd, buf, cnt, last)
int fd;
unsigned char *buf;
int cnt;
int last;
{
int boff; /* next write address offset */
if (!first) { /* is this 1st time thru */
first = 1; /* set the flag */
memset (bb, '\0', BLKSIZE); /* zero the buffer */
bb[3] = 4; /* next write byte offset */
bb[4] = 0x60; /* set beg/end of block */
bb[5] = 0; /* 1st block count is 0 bytes */
}
boff = (bb[2] << 8) | (bb[3]); /* get next write address offset */
if (last)
goto alldone; /* close out the file */
/* see if enough room in buffer for this record */
/* add current offset + 2 (for last record info) plus new */
/* record size plus 4 (2 for this rec, 2 for last) */
if ((boff + 2 + cnt + 4) >= BLKSIZE) {
/* not enough space, write out this record */
if (write(fd, bb, BLKSIZE) < 0)
return(-1);
memset (bb, '\0', BLKSIZE); /* zero the buffer */
bb[4] = 0x60; /* set beg/end of block */
bb[5] = 0; /* 1st block count is 0 bytes */
/* after 1st write */
boff = 4; /* init count at 4 bytes */
}
/* we have enough room, move in the record */
/* clear last record end of block flag, set up this record */
/* info and last rec info at end of data, and update cnt */
bb[boff] &= ~0x20; /* clear end of block flag */
bb[boff+2] = 0x00; /* clear this blocks flags */
bb[boff+3] = cnt; /* set this record count */
memcpy(&bb[boff+4], buf, cnt); /* copy in the data */
boff += (cnt+4); /* update count */
bb[boff] = 0x20; /* set eob status flag */
bb[boff+1] = cnt; /* set last rec byte count */
bb[2] = (boff & 0xff00) >> 8; /* set hi byte of count */
bb[3] = (boff & 0xff); /* set lo byte of count */
return(cnt); /* done */
alldone:
/* that was the last record, set eof flag in bb, write it and exit */
/* see if enough room in buffer for EOM record */
/* add current offset + 2 (for last record info) plus new */
/* EOF record size of 4 (2 for this rec, 2 for last) */
if ((boff + 2 + 4) >= BLKSIZE) {
/* not enough space, write out this record */
if (write(fd, bb, BLKSIZE) < 0)
return(-1);
memset (bb, '\0', BLKSIZE); /* zero the buffer */
bb[4] = 0x60; /* set beg/end of block */
bb[5] = 0; /* 1st block count is 0 bytes */
/* after 1st write */
boff = 4; /* init count at 4 bytes */
}
bb[boff] &= ~0x20; /* clear end of block flag */
/* bb[boff+2] = 0xa0; /* clear this blocks flags */
bb[boff+2] = 0x80; /* clear this blocks flags */
bb[boff+3] = 0; /* set record count of 0 */
bb[boff+4] = 0xa0; /* set EOF/EOB flags */
boff += 4; /* 4 more bytes */
bb[2] = (boff & 0xff00) >> 8; /* set hi byte of count */
bb[3] = (boff & 0xff); /* set lo byte of count */
/* write out EOF record */
if (write(fd, bb, BLKSIZE) < 0)
return(-1);
first = 0; /* reset 1st time flag */
return(cnt); /* get out, done */
}