/*
* 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;
}