From 24c8bcfe7f76b20124e2862ea050f815c0f768e7 Mon Sep 17 00:00:00 2001 From: tlatorre Date: Tue, 14 Aug 2018 10:08:27 -0500 Subject: move everything to src directory --- src/zebra.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 src/zebra.c (limited to 'src/zebra.c') diff --git a/src/zebra.c b/src/zebra.c new file mode 100644 index 0000000..4ce51a2 --- /dev/null +++ b/src/zebra.c @@ -0,0 +1,219 @@ +#include "zebra.h" +#include /* for FILE */ +#include /* for size_t */ +#include "pack2b.h" +#include /* for memmove() */ +#include /* for uint8_t, etc. */ +#include /* for strerror(), etc. */ + +char zebra_err[256]; + +zebraFile *zebra_open(const char *filename) +{ + FILE *f = fopen(filename, "r"); + + if (!f) { + sprintf(zebra_err, "failed to open '%s': %s", filename, strerror(errno)); + return NULL; + } + + zebraFile *z = (zebraFile *) malloc(sizeof(zebraFile)); + z->f = f; + z->offset = 0; + z->lr_size = 0; + z->buf = NULL; + z->buf_size = 0; + + return z; +} + +int read_next_physical_record(zebraFile *z) +{ + /* Read the next physical record from the zebra file and append it to the + * buffer. + * + * Returns 0 on success, -1 on error, and 1 on EOF. */ + uint8_t buf[48]; + size_t nbytes; + uint32_t s0, s1, s2, s3, nwphr, nfast; + + nbytes = fread(buf,4,8,z->f); + + if (nbytes == 0) return 1; + + if (nbytes != 8) { + sprintf(zebra_err, "expected %i words but only read %zu", 8, nbytes); + return -1; + } + + s0 = unpacki32(buf); + s1 = unpacki32(buf+4*1); + s2 = unpacki32(buf+4*2); + s3 = unpacki32(buf+4*3); + nwphr = unpacki32(buf+4*4); + nfast = unpacki32(buf+7*4); + + if (nwphr & (ZEBRA_EMERGENCY_STOP | ZEBRA_END_OF_RUN)) + return 1; + + nwphr &= ZEBRA_BLOCK_SIZE_MASK; + + uint32_t words = nwphr*(1 + nfast) - 8; + + if (s0 != ZEBRA_SIG0) { + sprintf(zebra_err, "invalid steering block stamp 0x%08x", s0); + return -1; + } + + if (s1 != ZEBRA_SIG1) { + sprintf(zebra_err, "invalid steering block stamp 0x%08x", s1); + return -1; + } + + if (s2 != ZEBRA_SIG2) { + sprintf(zebra_err, "invalid steering block stamp 0x%08x", s2); + return -1; + } + + if (s3 != ZEBRA_SIG3) { + sprintf(zebra_err, "invalid steering block stamp 0x%08x", s3); + return -1; + } + + z->buf = realloc(z->buf, z->buf_size+words*4); + + nbytes = fread(z->buf+z->buf_size, 4, words, z->f); + + z->buf_size += words*4; + + if (nbytes != words) { + sprintf(zebra_err, "expected %i words but only read %zu", words, nbytes); + return -1; + } + + return 0; +} + +int get_bytes(zebraFile *z, size_t size) +{ + /* Read bytes from the zdab file until there are at least `size` words in + * the buffer. + * + * Returns 0 on success, -1 on error, and 1 on EOF. */ + int rv; + + while ((z->buf_size - z->offset) < size*4) { + rv = read_next_physical_record(z); + + if (rv == -1) { + return -1; + } else if (z->buf_size == 0 && rv == 1) { + /* EOF and there are no bytes left. */ + return 1; + } + } + + return 0; +} + +int read_next_logical_record(zebraFile *z) +{ + /* Read the next logical record into the buffer. + * + * Returns 0 on success, -1 on error, and 1 on EOF. */ + uint32_t size, type, nwtx, nwseg, nwtab, nwuh; + + while (1) { + memmove(z->buf,z->buf+z->offset,z->buf_size-z->offset); + z->buf = realloc(z->buf, z->buf_size-z->offset); + z->buf_size -= z->offset; + z->offset = 0; + + switch (get_bytes(z,1)) { + case 1: + return 1; + case -1: + return -1; + } + size = unpacki32(z->buf+z->offset); + z->offset += 4; + + if (size == 0) continue; + + switch (get_bytes(z,1)) { + case 1: + return 1; + case -1: + return -1; + } + type = unpacki32(z->buf+z->offset); + z->offset += 4; + + switch (type) { + case 5: + case 6: + get_bytes(z,size-1); + z->offset += (size-1)*4; + continue; + case 1: + get_bytes(z,size); + z->offset += size*4; + continue; + } + + z->lr_size = (size + 2)*4; + get_bytes(z,size); + + nwtx = unpacki32(z->buf+z->offset+4*4); + nwseg = unpacki32(z->buf+z->offset+5*4); + nwtab = unpacki32(z->buf+z->offset+6*4); + nwuh = unpacki32(z->buf+z->offset+9*4); + + z->offset += 10*4; + + z->offset += nwtx*4; + z->offset += nwseg*4; + z->offset += nwtab*4; + z->offset += nwuh*4; + + break; + } + + return 0; +} + +int next_bank(zebraFile *z, bank *b) +{ + int rv; + uint32_t io, noff; + + if (z->offset == z->lr_size) { + rv = read_next_logical_record(z); + if (rv) return rv; + } + + io = unpacki32(z->buf+z->offset); + z->offset += 4; + + noff = io & 0xFFFF; + + if (noff > 12) { + z->offset += (noff-12)*4; + } + + unpack(z->buf+z->offset,"lllllllll",&b->next, &b->up, &b->orig, &b->number, &b->name, &b->num_links, &b->num_structural_links, &b->num_data_words, &b->status); + z->offset += 9*4; + + b->data = (uint32_t *) (z->buf+z->offset); + + z->offset += b->num_data_words*4; + + return 0; +} + +void zebra_close(zebraFile *z) +{ + fclose(z->f); + if (z->buf) free(z->buf); + free(z); +} -- cgit