osd-contiki/tools/z80/hex2bin/src/ihx2bin.c

191 lines
4.7 KiB
C
Raw Normal View History

/*
* Copyright (c) 2003-2008, Takahide Matsutsuka.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by Takahide Matsutsuka."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Intel HEX format to PC-6001 CAS format conversion utility.
*/
#include <stdio.h>
#include "ihx2bin.h"
/**
* Convert a character to a value.
* @param ch a character to convert
* @return integer value represents the given character
*/
static int aton(const unsigned char ch) {
int n;
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
}
if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
}
return 0;
}
/**
* Convert a byte characters from a given file and returns a byte.
* @param in file
* @return -1 if EOF
*/
static int getByte(FILE *in) {
int ch1, ch2;
ch1 = getc(in);
if (ch1 == EOF) {
return -1;
}
ch2 = getc(in);
if (ch2 == EOF) {
return -1;
}
return 16 * aton(ch1) + aton(ch2);
}
/**
* Extract a 64kB memory map from given file.
* IHEX format is as follows:
* :A_B___C_D_....D_E_
* A_ : size of this chunk
* B___: address (big endian)
* C_ : record type (00: notmal data, 01: end)
* D_....D_: data
* E_ : check sum
* :0DCCCF00673008D620D607D63013C937C904
* :00000001FF
* @param inFilename file name to convert
* @param start pointer to start address
* @param end pointer to end address
* @return 0 if noerror, otherwise if error
*/
static int ihx2mem(const char *inFilename, unsigned char *buffer, unsigned int *start, unsigned int *end) {
FILE *in;
*start = 0xffff;
*end = 0;
in = fopen(inFilename, "rb");
if (in == NULL) {
printf("cannot open input file\n");
return 1;
}
while(1) {
int ch;
int length;
unsigned int address;
int tmp;
// skip checksum and cr/lf
while ((ch = getc(in)) != ':') {
if (ch == EOF) {
break;
}
}
if (ch == EOF) {
break;
}
// get length of this chunk
length = getByte(in);
if (length <= 0) {
// TODO: end of bytes, retrieve variables
break;
}
// make an address
tmp = getByte(in);
if (tmp < 0) {
break;
}
address = tmp * 256;
tmp = getByte(in);
if (tmp < 0) {
break;
}
address += tmp;
if (*start > address) {
*start = address;
}
if (*end < (address + length)) {
*end = address + length;
}
// ignore record type
if (getByte(in) < 0) {
break;
}
while (length > 0) {
buffer[address] = getByte(in);
address++;
length--;
}
}
fclose(in);
return 0;
}
/**
* @return written size
*/
int ihx2bin(FILE* dst, const char *src, unsigned char verbose) {
unsigned int start, end;
unsigned char buffer[65536];
unsigned int i;
memset(buffer, 0, 65536);
if (ihx2mem(src, buffer, &start, &end)) {
printf("cannot open input file: %s\n", src);
return 0;
}
if (verbose) {
printf("importing ihx : %s (%04x:%04x)\n", src, start, end);
}
for (i = start; i < end; i++) {
putc(buffer[i], dst);
}
return (end - start);
}