/* * Mimas conversion tools * * Copyright (C) 2010 Benjamin Moody * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "output.h" #include "utils.h" ti8x_file *ti8x_file_new(const char *name) { ti8x_file *f; f = xnew(ti8x_file, 1); f->name = xstrdup(name); f->num_vars = 0; f->vars = NULL; return f; } void ti8x_file_free(ti8x_file *f) { int i; if (!f) return; if (f->vars) { for (i = 0; i < f->num_vars; i++) { if (f->vars[i]) { xfree(f->vars[i]->data); xfree(f->vars[i]); } } } xfree(f->name); xfree(f->vars); xfree(f); } ti8x_var_entry *ti8x_file_add_var(ti8x_file *f, unsigned int type, const char *name, int archived) { ti8x_var_entry *v; f->num_vars++; f->vars = xrenew(ti8x_var_entry *, f->vars, f->num_vars); f->vars[f->num_vars - 1] = v = xnew(ti8x_var_entry, 1); v->type = type; v->archived = archived; strncpy(v->name, name, 8); v->name[8] = 0; v->length = 0; v->length_a = 0; v->data = NULL; return v; } void ti8x_var_append_data(ti8x_var_entry *var, const unsigned char *data, unsigned int length) { if (var->length + length > var->length_a) { var->length_a = var->length + length + 1024; var->data = xrenew(unsigned char, var->data, var->length_a); } if (data) memcpy(var->data + var->length, data, length); else memset(var->data + var->length, 0, length); var->length += length; } static unsigned int checksum(const unsigned char *data, unsigned int length) { unsigned int n; n = 0; while (length != 0) { n += *data; data++; length--; } return n; } int ti8x_file_write(FILE *outf, ti8x_file *f) { unsigned char hdr[55]; unsigned int total_size; int i; unsigned int sum; total_size = 0; for (i = 0; i < f->num_vars; i++) total_size += 2 + 13 + 2 + f->vars[i]->length; if (total_size >= 0x10000) { fprintf(stderr, "Cannot write %s: contents too large (%u)", f->name, total_size); return 1; } memset(hdr, 0, sizeof(hdr)); memcpy(hdr, "**TI83F*\032\012", 11); hdr[53] = total_size; hdr[54] = total_size >> 8; if (fwrite(hdr, 1, 55, outf) != 55) { fprintf(stderr, "Error writing %s\n", f->name); return 1; } sum = 0; for (i = 0; i < f->num_vars; i++) { /* var header */ hdr[0] = 13; hdr[1] = 0; hdr[2] = f->vars[i]->length; hdr[3] = f->vars[i]->length >> 8; hdr[4] = f->vars[i]->type; strncpy((char *) &hdr[5], f->vars[i]->name, 8); hdr[13] = 0; hdr[14] = f->vars[i]->archived ? 0x80 : 0; /* length of var data */ hdr[15] = f->vars[i]->length; hdr[16] = f->vars[i]->length >> 8; if (fwrite(hdr, 1, 17, outf) != 17 || (fwrite(f->vars[i]->data, 1, f->vars[i]->length, outf) != f->vars[i]->length)) { fprintf(stderr, "Error writing %s\n", f->name); return 1; } sum += checksum(hdr, 17) + checksum(f->vars[i]->data, f->vars[i]->length); } hdr[0] = sum; hdr[1] = sum >> 8; if (fwrite(hdr, 1, 2, outf) != 2) { fprintf(stderr, "Error writing %s\n", f->name); return 1; } return 0; }