Removed dependency of Cygwin from hexameter.
This commit is contained in:
parent
f822ac9797
commit
6c9291f38b
23 changed files with 440 additions and 182 deletions
|
@ -38,29 +38,24 @@
|
|||
* A main file for hex2cas.
|
||||
*/
|
||||
|
||||
#define MAX_PATH 1024
|
||||
|
||||
#if __CYGWIN32__
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ihx2bin.h"
|
||||
|
||||
#define MAXFILES 256
|
||||
|
||||
struct Configuration {
|
||||
typedef struct {
|
||||
char* output;
|
||||
char* prefix;
|
||||
char* suffix;
|
||||
char* dir;
|
||||
char archname[6];
|
||||
char *files[MAXFILES];
|
||||
unsigned int defsize;
|
||||
struct ConvertDefinition defs[DEF_MAX];
|
||||
unsigned char verbose;
|
||||
// number of the ihx files
|
||||
int length;
|
||||
|
@ -68,9 +63,33 @@ struct Configuration {
|
|||
int size;
|
||||
// output file wriiten size
|
||||
int written;
|
||||
};
|
||||
} Configuration;
|
||||
|
||||
static char *changeExt(const char *path, const char* ext) {
|
||||
static
|
||||
const char* IHXEXT = ".ihx";
|
||||
|
||||
static
|
||||
const char *strcasestr(const char *haystack, const char *needle) {
|
||||
int haypos;
|
||||
int needlepos;
|
||||
|
||||
haypos = 0;
|
||||
while (haystack[haypos]) {
|
||||
if (tolower (haystack[haypos]) == tolower(needle[0])) {
|
||||
needlepos = 1;
|
||||
while ( (needle[needlepos]) &&
|
||||
(tolower(haystack[haypos + needlepos])
|
||||
== tolower(needle[needlepos])) )
|
||||
++needlepos;
|
||||
if (! needle[needlepos]) return (haystack + haypos);
|
||||
}
|
||||
++haypos;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
char *changeExt(const char *path, const char* ext) {
|
||||
char *p;
|
||||
char *tail;
|
||||
char *changed;
|
||||
|
@ -79,7 +98,6 @@ static char *changeExt(const char *path, const char* ext) {
|
|||
|
||||
for (tail = (char*) path; *tail != 0; tail++);
|
||||
for (p = tail; p > path; p--) {
|
||||
|
||||
if (*p == '.') {
|
||||
len = p - path;
|
||||
changed = (char*) malloc(len + extlen + 2);
|
||||
|
@ -98,47 +116,50 @@ static char *changeExt(const char *path, const char* ext) {
|
|||
return changed;
|
||||
}
|
||||
|
||||
static unsigned char analyzeOption(int argc, char **argv, struct Configuration *config) {
|
||||
static
|
||||
unsigned char analyzeOption(int argc, char **argv, Configuration *config) {
|
||||
int c;
|
||||
char *defval;
|
||||
|
||||
opterr = 0;
|
||||
while ((c = getopt(argc, argv, "hvo:p:s:n:b:")) != EOF) {
|
||||
int i;
|
||||
while ((c = getopt(argc, argv, "hvo:d:b:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
config->verbose = TRUE;
|
||||
config->verbose = 1;
|
||||
break;
|
||||
case 'o':
|
||||
config->output = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
config->prefix = optarg;
|
||||
break;
|
||||
case 's':
|
||||
config->suffix = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
sscanf(optarg, "%x", &config->size);
|
||||
break;
|
||||
// case 'n':
|
||||
// for (i = 0; i < 6; i++) {
|
||||
// if (optarg[i] == 0) {
|
||||
// break;
|
||||
// }
|
||||
// config->archname[i] = optarg[i];
|
||||
// }
|
||||
// break;
|
||||
case 'd':
|
||||
if (config->defsize >= DEF_MAX) {
|
||||
printf("excess number of definitions\n");
|
||||
return 1;
|
||||
}
|
||||
defval = strchr(optarg, '=');
|
||||
if (defval) {
|
||||
*defval = 0;
|
||||
config->defs[config->defsize].name = optarg;
|
||||
config->defs[config->defsize].value = defval + 1;
|
||||
config->defsize++;
|
||||
} else {
|
||||
printf("definition value required:%s\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'h':
|
||||
printf("%s : Convert Intel HEX file (ihx) to binary file, ver. 2.0.0\n", getprogname());
|
||||
printf("Hexameter: Convert Intel HEX file (ihx) to binary file, ver. 2.1.0\n");
|
||||
printf("Copyright (c) 2003-2008 Takahide Matsutsuka <markn@markn.org>\n");
|
||||
printf("Usage: %s [options] <ihx> [<ihx>...]\n", argv[0]);
|
||||
printf("Usage: hexameter [options] <ihx|bin> [<ihx|bin>...]\n");
|
||||
printf("Options:\n");
|
||||
printf(" -v verbose output\n");
|
||||
printf(" -o <output file name>\n");
|
||||
// printf(" -n <cassette file name> (for NEC PC series)\n");
|
||||
printf(" -p <prefix file>\n");
|
||||
printf(" -s <suffix file>\n");
|
||||
printf(" -d <name>=<value> define property\n");
|
||||
printf(" -b <output file size in hexadecimal bytes>\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -h show this help\n");
|
||||
|
||||
return 1;
|
||||
default:
|
||||
|
@ -150,7 +171,9 @@ static unsigned char analyzeOption(int argc, char **argv, struct Configuration *
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int isFileExists(const char *dir, const char *filename) {
|
||||
#if 0
|
||||
static
|
||||
int isFileExists(const char *dir, const char *filename) {
|
||||
char path[MAX_PATH];
|
||||
FILE *f;
|
||||
|
||||
|
@ -171,19 +194,25 @@ static int isFileExists(const char *dir, const char *filename) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return 1 if given filename has an extension of ".ihx"
|
||||
*/
|
||||
static
|
||||
int isIhx(const char *filename) {
|
||||
const char* pos = strcasestr(filename, IHXEXT);
|
||||
if (pos && pos[strlen(IHXEXT)] == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int checkExistence(struct Configuration *config) {
|
||||
static
|
||||
int checkExistence(Configuration *config) {
|
||||
int i;
|
||||
int r;
|
||||
FILE *f;
|
||||
fclose(f);
|
||||
if (r = isFileExists(config->dir, config->prefix)) {
|
||||
return r;
|
||||
}
|
||||
if (r = isFileExists(config->dir, config->suffix)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < config->length; i++) {
|
||||
f = fopen(config->files[i], "r");
|
||||
if (!f) {
|
||||
|
@ -201,7 +230,7 @@ static int checkExistence(struct Configuration *config) {
|
|||
static
|
||||
int copy(FILE *out, const char* dir, const char* filename, unsigned char verbose) {
|
||||
FILE *in;
|
||||
char ch;
|
||||
int ch;
|
||||
char path[MAX_PATH];
|
||||
int bytes = 0;
|
||||
if (!filename) {
|
||||
|
@ -213,31 +242,42 @@ int copy(FILE *out, const char* dir, const char* filename, unsigned char verbose
|
|||
} else {
|
||||
strcpy(path, filename);
|
||||
}
|
||||
if (verbose) {
|
||||
printf("importing file: %s\n", path);
|
||||
}
|
||||
in = fopen(path, "rb");
|
||||
while ((ch = getc(in)) != EOF) {
|
||||
putc(ch, out);
|
||||
bytes++;
|
||||
}
|
||||
fclose(in);
|
||||
if (verbose) {
|
||||
printf("imported file: %s, size=%d\n", path, bytes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static int output(struct Configuration *config) {
|
||||
static
|
||||
int output(Configuration *config) {
|
||||
FILE *out;
|
||||
int i;
|
||||
// TODO: ARCH FILE NAME
|
||||
|
||||
if (!(out = fopen(config->output, "wb"))) {
|
||||
printf("cannot open output file:%s\n", config->output);
|
||||
return 1;
|
||||
}
|
||||
config->written += copy(out, config->dir, config->prefix, config->verbose);
|
||||
|
||||
for (i = 0; i < config->length; i++) {
|
||||
config->written += ihx2bin(out, config->files[i], config->verbose);
|
||||
struct ConvertInfo info;
|
||||
info.out = out;
|
||||
info.filename = config->files[i];
|
||||
info.verbose = config->verbose;
|
||||
info.defsize = config->defsize;
|
||||
info.defs = config->defs;
|
||||
|
||||
if (isIhx(config->files[i])) {
|
||||
config->written += ihx2bin(&info);
|
||||
} else {
|
||||
config->written += copy(out, NULL, config->files[i], config->verbose);
|
||||
}
|
||||
}
|
||||
config->written += copy(out, config->dir, config->suffix, config->verbose);
|
||||
|
||||
if (config->size) {
|
||||
if (config->verbose) {
|
||||
|
@ -254,27 +294,14 @@ static int output(struct Configuration *config) {
|
|||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct Configuration config;
|
||||
Configuration config;
|
||||
unsigned char r;
|
||||
|
||||
memset(&config, 0, sizeof(struct Configuration));
|
||||
|
||||
#if __CYGWIN32__
|
||||
char path[MAX_PATH];
|
||||
GetModuleFileName(NULL, path, MAX_PATH);
|
||||
int len = strlen(path);
|
||||
while (len > 0) {
|
||||
if (path[len] == '\\') {
|
||||
path[len + 1] = 0;
|
||||
break;
|
||||
}
|
||||
len--;
|
||||
}
|
||||
config.dir = path;
|
||||
#endif
|
||||
memset(&config, 0, sizeof(Configuration));
|
||||
|
||||
while (optind < argc) {
|
||||
if (r = analyzeOption(argc, argv, &config)) {
|
||||
r = analyzeOption(argc, argv, &config);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
if (optind == argc) {
|
||||
|
@ -298,13 +325,15 @@ int main(int argc, char **argv) {
|
|||
config.output = changeExt(config.files[0], "bin");
|
||||
}
|
||||
|
||||
if (r = checkExistence(&config)) {
|
||||
r = checkExistence(&config);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
if (config.verbose) {
|
||||
printf("Generating file: %s\n", config.output);
|
||||
}
|
||||
if (r = output(&config)) {
|
||||
r = output(&config);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,19 +35,41 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Intel HEX format to PC-6001 CAS format conversion utility.
|
||||
* Intel HEX format (extended) to binary format conversion utility.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ihx2bin.h"
|
||||
|
||||
#define TYPE_DATA 0
|
||||
#define TYPE_END 1
|
||||
#define TYPE_STRING 2
|
||||
#define TYPE_BYTE 3
|
||||
#define TYPE_WORD 4
|
||||
|
||||
#define MEMORY_SIZE 0x10000
|
||||
|
||||
typedef struct {
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
unsigned char buffer[MEMORY_SIZE];
|
||||
// current line
|
||||
int type;
|
||||
unsigned int address;
|
||||
unsigned int length;
|
||||
} Memory;
|
||||
|
||||
static
|
||||
const char NAME_CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
|
||||
|
||||
/**
|
||||
* 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;
|
||||
static
|
||||
int aton(const unsigned char ch) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
return ch - '0';
|
||||
}
|
||||
|
@ -66,19 +88,95 @@ static int aton(const unsigned char ch) {
|
|||
* @param in file
|
||||
* @return -1 if EOF
|
||||
*/
|
||||
static int getByte(FILE *in) {
|
||||
static
|
||||
int getByte(FILE *in) {
|
||||
int ch1, ch2;
|
||||
ch1 = getc(in);
|
||||
if (ch1 == EOF) {
|
||||
if (feof(in)) {
|
||||
printf("eof");
|
||||
return -1;
|
||||
}
|
||||
ch2 = getc(in);
|
||||
if (ch2 == EOF) {
|
||||
ch1 = fgetc(in);
|
||||
if (feof(in)) {
|
||||
printf("eof");
|
||||
return -1;
|
||||
}
|
||||
ch2 = fgetc(in);
|
||||
return 16 * aton(ch1) + aton(ch2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-zero if error
|
||||
*/
|
||||
static
|
||||
void replace(FILE* in, struct ConvertInfo *info, Memory *memory) {
|
||||
int i, j;
|
||||
char name[DEF_NAMELEN];
|
||||
int len = 0;
|
||||
// read name
|
||||
while (len < DEF_NAMELEN - 1) {
|
||||
char ch = fgetc(in);
|
||||
if (!strchr(NAME_CHARS, ch)) {
|
||||
break;
|
||||
}
|
||||
name[len] = ch;
|
||||
len++;
|
||||
}
|
||||
name[len] = 0;
|
||||
|
||||
for (i = 0; i < info->defsize; i++) {
|
||||
if (!strcmp(name, info->defs[i].name)) {
|
||||
int tmp;
|
||||
char value[DEF_VALUELEN];
|
||||
|
||||
// replace!
|
||||
switch (memory->type) {
|
||||
case TYPE_STRING:
|
||||
for (j = 0; j < memory->length; j++) {
|
||||
memory->buffer[memory->address] = value[j] = info->defs[i].value[j];
|
||||
memory->address++;
|
||||
}
|
||||
value[j] = 0;
|
||||
if (info->verbose) {
|
||||
printf("[%s]->[%s], ", name, value);
|
||||
}
|
||||
break;
|
||||
case TYPE_BYTE:
|
||||
tmp = 0;
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (aton(info->defs[i].value[j])) {
|
||||
tmp = tmp * 16 + aton(info->defs[i].value[j]);
|
||||
}
|
||||
}
|
||||
memory->buffer[memory->address] = tmp;
|
||||
if (info->verbose) {
|
||||
printf("[%s]->[%02x], ", name, tmp);
|
||||
}
|
||||
break;
|
||||
case TYPE_WORD:
|
||||
tmp = 0;
|
||||
for (j = 0; j < 2; j++) {
|
||||
tmp = tmp * 16 + aton(info->defs[i].value[j]);
|
||||
}
|
||||
memory->buffer[memory->address + 1] = tmp;
|
||||
tmp = 0;
|
||||
for (j = 2; j < 4; j++) {
|
||||
tmp = tmp * 16 + aton(info->defs[i].value[j]);
|
||||
}
|
||||
memory->buffer[memory->address] = tmp;
|
||||
if (info->verbose) {
|
||||
printf("[%s]->[%02x%02x], ", name,
|
||||
memory->buffer[memory->address + 1],
|
||||
memory->buffer[memory->address]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extract a 64kB memory map from given file.
|
||||
* IHEX format is as follows:
|
||||
|
@ -86,6 +184,7 @@ static int getByte(FILE *in) {
|
|||
* A_ : size of this chunk
|
||||
* B___: address (big endian)
|
||||
* C_ : record type (00: notmal data, 01: end)
|
||||
* extension: 02: char, 03: byte(hex), 04: word(hex, little-endian)
|
||||
* D_....D_: data
|
||||
* E_ : check sum
|
||||
* :0DCCCF00673008D620D607D63013C937C904
|
||||
|
@ -95,68 +194,71 @@ static int getByte(FILE *in) {
|
|||
* @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) {
|
||||
static
|
||||
int ihx2mem(struct ConvertInfo *info, Memory *memory) {
|
||||
FILE *in;
|
||||
*start = 0xffff;
|
||||
*end = 0;
|
||||
memory->start = MEMORY_SIZE - 1;
|
||||
memory->end = 0;
|
||||
|
||||
in = fopen(inFilename, "rb");
|
||||
in = fopen(info->filename, "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) {
|
||||
while (!feof(in)) {
|
||||
if (fgetc(in) == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ch == EOF) {
|
||||
if (feof(in)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// get length of this chunk
|
||||
length = getByte(in);
|
||||
if (length <= 0) {
|
||||
// TODO: end of bytes, retrieve variables
|
||||
if ((memory->length = getByte(in)) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// make an address
|
||||
tmp = getByte(in);
|
||||
if (tmp < 0) {
|
||||
if ((tmp = getByte(in)) < 0) {
|
||||
break;
|
||||
}
|
||||
address = tmp * 256;
|
||||
tmp = getByte(in);
|
||||
if (tmp < 0) {
|
||||
memory->address = tmp * 256;
|
||||
if ((tmp = getByte(in)) < 0) {
|
||||
break;
|
||||
}
|
||||
address += tmp;
|
||||
if (*start > address) {
|
||||
*start = address;
|
||||
}
|
||||
memory->address += tmp;
|
||||
|
||||
if (*end < (address + length)) {
|
||||
*end = address + length;
|
||||
}
|
||||
|
||||
// ignore record type
|
||||
if (getByte(in) < 0) {
|
||||
// process record type
|
||||
if ((memory->type = getByte(in)) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (length > 0) {
|
||||
buffer[address] = getByte(in);
|
||||
address++;
|
||||
length--;
|
||||
if (memory->type != TYPE_END) {
|
||||
// modify start and end
|
||||
if (memory->start > memory->address) {
|
||||
memory->start = memory->address;
|
||||
}
|
||||
if (memory->end < (memory->address + memory->length)) {
|
||||
memory->end = memory->address + memory->length;
|
||||
}
|
||||
}
|
||||
|
||||
if (memory->type == TYPE_DATA) {
|
||||
while (memory->length > 0) {
|
||||
memory->buffer[memory->address] = getByte(in);
|
||||
memory->address++;
|
||||
memory->length--;
|
||||
}
|
||||
} else if (memory->type == TYPE_STRING
|
||||
|| memory->type == TYPE_BYTE
|
||||
|| memory->type == TYPE_WORD) {
|
||||
replace(in, info, memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,24 +269,28 @@ static int ihx2mem(const char *inFilename, unsigned char *buffer, unsigned int *
|
|||
/**
|
||||
* @return written size
|
||||
*/
|
||||
int ihx2bin(FILE* dst, const char *src, unsigned char verbose) {
|
||||
unsigned int start, end;
|
||||
unsigned char buffer[65536];
|
||||
int ihx2bin(struct ConvertInfo *info) {
|
||||
Memory memory;
|
||||
unsigned int i;
|
||||
|
||||
memset(buffer, 0, 65536);
|
||||
memset(&memory, 0, sizeof(Memory));
|
||||
|
||||
if (ihx2mem(src, buffer, &start, &end)) {
|
||||
printf("cannot open input file: %s\n", src);
|
||||
if (info->verbose) {
|
||||
printf("importing ihx: %s, ", info->filename);
|
||||
}
|
||||
|
||||
if (ihx2mem(info, &memory)) {
|
||||
printf("cannot open input file: %s\n", info->filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf("importing ihx : %s (%04x:%04x)\n", src, start, end);
|
||||
}
|
||||
for (i = start; i < end; i++) {
|
||||
putc(buffer[i], dst);
|
||||
if (info->verbose) {
|
||||
printf("(%04x:%04x)\n", memory.start, memory.end);
|
||||
}
|
||||
|
||||
return (end - start);
|
||||
for (i = memory.start; i < memory.end; i++) {
|
||||
putc(memory.buffer[i], info->out);
|
||||
}
|
||||
|
||||
return (memory.end - memory.start);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ihx2bin.h,v 1.1 2008/07/02 07:17:14 matsutsuka Exp $
|
||||
* $Id: ihx2bin.h,v 1.2 2008/07/20 07:44:39 matsutsuka Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -39,9 +39,27 @@
|
|||
#ifndef __IHX2BIN_H__
|
||||
#define __IHX2BIN_H__
|
||||
|
||||
#define DEF_MAX 1024
|
||||
#define DEF_NAMELEN 256
|
||||
#define DEF_VALUELEN 256
|
||||
|
||||
struct ConvertDefinition {
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct ConvertInfo {
|
||||
FILE* out;
|
||||
char* filename;
|
||||
unsigned char verbose;
|
||||
unsigned int defsize;
|
||||
struct ConvertDefinition *defs;
|
||||
};
|
||||
|
||||
/* A default architecture-depend file name. */
|
||||
#define DEFAULT_ARCH_FILENAME "noname"
|
||||
|
||||
int ihx2bin(FILE* dst, const char *src, unsigned char verbose);
|
||||
// int ihx2bin(FILE* dst, const char *src, unsigned char verbose);
|
||||
int ihx2bin(struct ConvertInfo* info);
|
||||
|
||||
#endif /* __IHX2BIN_H__ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue