diff --git a/platform/pc-6001/Makefile.pc-6001 b/platform/pc-6001/Makefile.pc-6001 index d43412eb2..0cb381973 100644 --- a/platform/pc-6001/Makefile.pc-6001 +++ b/platform/pc-6001/Makefile.pc-6001 @@ -2,7 +2,7 @@ # Makefile for PC-6001 using z80/SDCC # @author Takahide Matsutsuka # -# $Id: Makefile.pc-6001,v 1.9 2008/07/02 15:04:07 matsutsuka Exp $ +# $Id: Makefile.pc-6001,v 1.10 2008/07/20 07:44:39 matsutsuka Exp $ # ifndef CONTIKI @@ -48,7 +48,8 @@ endif ### setup default values ifndef HEX2BIN - HEX2BIN = ../../tools/z80/hex2bin/hexameter + HEX2BINDIR = ../../tools/z80/hex2bin/ + HEX2BIN = $(HEX2BINDIR)/hexameter endif ### setup flags to be used in compiler, assembler, and HEX2BIN @@ -59,16 +60,16 @@ CFLAGS += -DMEMORY_$(MEMORY) -DARCH_$(ARCH) -DCTK_$(CTKCONF) ifeq ($(MEMORY),16K) LDFLAGS += --code-loc 0xc40f --data-loc 0 - HEX2BINFLAGS = -p mode1 -s suffix -o contiki.p6 + HEX2BINFLAGS = -d TAPE=contki $(HEX2BINDIR)/ihx/mode1.ihx -o contiki.p6 else ifeq ($(MEMORY),ROM) LDFLAGS += --code-loc 0x4004 --data-loc 0xf000 - HEX2BINFLAGS = -p rom60 -o contiki.rom + HEX2BINFLAGS = -d ROMEXEC=4004 $(HEX2BINDIR)/ihx/rom60.ihx -b 4000 -o contiki.rom else ifeq ($(ARCH),PC6001MK2) LDFLAGS += --code-loc 0x800f --data-loc 0 - HEX2BINFLAGS = -p mode5 -s suffix -o contiki2.p6 + HEX2BINFLAGS = -d TAPE=contki $(HEX2BINDIR)/ihx/mode5.ihx -o contiki2.p6 else LDFLAGS += --code-loc 0x840f --data-loc 0 - HEX2BINFLAGS = -p mode2 -s suffix -o contiki.p6 + HEX2BINFLAGS = -d TAPE=contki $(HEX2BINDIR)/ihx/mode2.ihx -o contiki.p6 endif ifeq ($(LOADER),1) @@ -108,12 +109,12 @@ contiki: $(HEX2BIN) contiki.p6 .SUFFIXES: %.p6: %.ihx - $(HEX2BIN) $(HEX2BINFLAGS) $< + $(HEX2BIN) $(HEX2BINFLAGS) $< $(HEX2BINDIR)/ihx/suffix.ihx %.rom: %.ihx - $(HEX2BIN) $(HEX2BIN) $(HEX2BINFLAGS) $< + $(HEX2BIN) $(HEX2BINFLAGS) $< $(HEX2BIN): - cd ../../tools/z80/hex2bin/; make + cd $(HEX2BINDIR); make remove-ctk: rm -f obj_$(TARGET)/ctk*; diff --git a/platform/pc-6001/contiki-main.c b/platform/pc-6001/contiki-main.c index db893b588..2df42b854 100644 --- a/platform/pc-6001/contiki-main.c +++ b/platform/pc-6001/contiki-main.c @@ -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: contiki-main.c,v 1.2 2008/07/02 15:03:44 matsutsuka Exp $ + * $Id: contiki-main.c,v 1.3 2008/07/20 07:44:39 matsutsuka Exp $ * */ @@ -71,7 +71,7 @@ main(void) #else program_handler_add(&processes_dsc, "Processes", 1); program_handler_add(&mttest_dsc, "Multithread", 1); -// program_handler_add(&calc_dsc, "Calculator", 1); + program_handler_add(&calc_dsc, "Calculator", 1); program_handler_add(&about_dsc, "About", 1); // program_handler_add(&shell_dsc, "Command shell", 1); #endif diff --git a/tools/z80/hex2bin/LICENSE.txt b/tools/z80/hex2bin/LICENSE.txt new file mode 100644 index 000000000..b54de728e --- /dev/null +++ b/tools/z80/hex2bin/LICENSE.txt @@ -0,0 +1,26 @@ +Copyright (c) 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. Neither the name of the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS 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 INSTITUTE OR 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. diff --git a/tools/z80/hex2bin/Makefile b/tools/z80/hex2bin/Makefile index 2a24ab429..65aa70a5b 100644 --- a/tools/z80/hex2bin/Makefile +++ b/tools/z80/hex2bin/Makefile @@ -2,16 +2,30 @@ # Makefile for hexameter # @author Takahide Matsutsuka # -# $Id: Makefile,v 1.1 2008/07/02 07:17:14 matsutsuka Exp $ +# $Id: Makefile,v 1.2 2008/07/20 07:44:39 matsutsuka Exp $ # -CFLAGS = -SOURCEDIR = src -TARGET = hexameter.o ihx2bin.o +CFLAGS = -std=c99 -g -mno-cygwin -Wall +#CFLAGS = -std=c99 -g -Wall +SOURCEDIR = src +SOURCES = hexameter.c ihx2bin.c +OBJECTDIR = bin +OBJECTS = ${addprefix $(OBJECTDIR)/,$(SOURCES:.c=.o)} vpath %.c $(SOURCEDIR) -hexameter: $(TARGET) +ifeq (${wildcard $(OBJECTDIR)},) + DUMMY := ${shell mkdir $(OBJECTDIR)} +endif + +hexameter: $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $(OBJECTS) clean: - rm -f *.o *~ hexameter.exe + rm -rf bin + rm -f *~ *.stackdump + rm -f *~ hexameter.exe + +$(OBJECTDIR)/%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + diff --git a/tools/z80/hex2bin/README.txt b/tools/z80/hex2bin/README.txt index f0bc92907..ff3f17875 100644 --- a/tools/z80/hex2bin/README.txt +++ b/tools/z80/hex2bin/README.txt @@ -1,5 +1,5 @@ hexameter : Convert Intel hex files to a binary file -version 2.0.0 +version 2.1.0 Copyright (c) 2003-2008, Takahide Matsutsuka. 1/ What is it? @@ -13,15 +13,15 @@ other old computers. 2/ Installation -Installation can be done in following steps. +Installation can be done in the following steps. a) Download and install SDCC from http://sdcc.sf.net/ - Version 2.8.0 is tested. + Version 2.8.0 has been tested. SDCC is a cross-compiler for Z80 and other 8bit CPUs. Extract an archive on your disk, say "c:/sdcc". -b) Copy hexameter.exe to any path-available directory. for exmaple - "c:/sdcc/bin". +b) Place hexameter.exe and prefix/suffix files to any path-available + directory. 3/ Use @@ -60,38 +60,30 @@ b) Compile your code using SDCC. c) Convert ihx file to cas file using hex2cas. - hexameter YOUR_CODE.ihx [YOUR_CODE2.ihx ...] + hexameter [ihx_file|binary_file ...] The ihx files are just attached in the specified order. Here you can take some options: - -p specify prefix file name. - -s specify suffix file name. - -n specify PC-6001 cassette file name, - must be 6 characters or less. - -v verbose output - -o specify output file name - -b size of the output file in hexadecimal bytes. - only if the size of the output is less than the size - specified, the trailing bytes will filled by zeroes. - note that it doesn't mean the size of output is - restricted by the given size. - -h displays simple usage + -o specify output file name + -d = define ihx-specific value replacement + -v verbose output + -b size of the output file in hexadecimal bytes. + only if the size of the output is less than the size + specified, the trailing bytes will filled by zeroes. + note that it doesn't mean the size of output is + restricted by the given size. + -h displays simple usage - Prefixes and suffixes are provided by files, which should be in the same - directory as hexameter.exe. - mode1 - mode2 - mode5 - n88 - rom60 - rom62 - suffix + You can find various predefined library file in "lib" directory. + Each of them may take its own optional value, which you can specify + with -d option. d) Example The following is a typical example to convert from ihx files to PC-6001 loadable cassette format. - % hexameter -p mode2 -s suffix mycode1.ihx mycode2.ihx -o myapp.p6 + % hexameter -v TAPE=myfile mode2.ihx mycode2.ihx -o myapp.p6 + Note that TAPE value is defined in mode2.ihx, defines cassette file name. e) Load your cas file into your 6001 emulator. @@ -105,15 +97,52 @@ e) Load your cas file into your 6001 emulator. http://bernie.hp.infoseek.co.jp/develop/pc6001vw.html -4/ Note +4/ IHX extentions -- While I've tested the tool on Cigwin on Win32, I think it works - on other environments with a little work. +To support run-time user specified values in ihx files, Hexameter supports +extended ihx files. Examples are located in ihx directory. + +For example, mode2.ihx has the following line. + +:06000a02TAPE + +As in normal ihx format, the first 9 characters conform to the following +format: + +:AABBBBCC +AA bytes encoded in this line +BBBB start address of this line +CC type of this line + +The normal ihx file, which sdcc emits, has the type 00 (data) and 01 (end of +file). In addition to this, Hexameter supports the following types. + +02 string +03 byte +04 word (encoded in little endian) + +The rest of line defines a name of the definition. In the example above, +the name TAPE is assigned to this line. You can use latin alphabets, +numbers, and underscore (_) for the name. Letters are case-sensitive. + +When you run Hexameter, you can specify a value for this definition like: +hexameter -d TAPE=xxxx + +Since this example defines 06 in the bytes field, TAPE can have up to +six characters. This string will override the memory location 000a +specified in the second field. + +For type 03 (byte) and 04 (word), bytes field has no effect. + + +5/ Note + +- Cygwin dependency has been removed. - SDCC has many isuues regarding compilation. Don't blame me about them! :) -5/ History +6/ History 3/29/2003 1.0.0 First version 4/20/2003 1.0.1 Mode option has been added @@ -123,6 +152,8 @@ e) Load your cas file into your 6001 emulator. 4/28/2008 1.4.0 Header file option introduced 5/17/2008 2.0.0 Migrated to hexameter, to support more flexible configurations +7/16/2008 2.1.0 Support arguments in ihx file, remove prefix/suffix instead +7/18/2008 2.1.1 Cygwin dependency has been removed Enjoy! diff --git a/tools/z80/hex2bin/ihx/mode1.ihx b/tools/z80/hex2bin/ihx/mode1.ihx new file mode 100644 index 000000000..b6661c82c --- /dev/null +++ b/tools/z80/hex2bin/ihx/mode1.ihx @@ -0,0 +1,3 @@ +:10000000d3d3d3d3d3d3d3d3d3d3000000000000 +:0e0010000dc40a00a5264843343046000000 +:06000a02TAPE diff --git a/tools/z80/hex2bin/ihx/mode2.ihx b/tools/z80/hex2bin/ihx/mode2.ihx new file mode 100644 index 000000000..bab52b2fe --- /dev/null +++ b/tools/z80/hex2bin/ihx/mode2.ihx @@ -0,0 +1,3 @@ +:10000000d3d3d3d3d3d3d3d3d3d3000000000000 +:0e0010000d840a00a5264838343046000000 +:06000a02TAPE diff --git a/tools/z80/hex2bin/ihx/mode5.ihx b/tools/z80/hex2bin/ihx/mode5.ihx new file mode 100644 index 000000000..6d59c5e9a --- /dev/null +++ b/tools/z80/hex2bin/ihx/mode5.ihx @@ -0,0 +1,3 @@ +:10000000d3d3d3d3d3d3d3d3d3d3000000000000 +:0e0010000d800a00a5264838303046000000 +:06000a02TAPE diff --git a/tools/z80/hex2bin/ihx/mp6.ihx b/tools/z80/hex2bin/ihx/mp6.ihx new file mode 100644 index 000000000..20f928271 --- /dev/null +++ b/tools/z80/hex2bin/ihx/mp6.ihx @@ -0,0 +1,3 @@ +:10000000544d6767676767676767000000000000 +:02000c04MP6LOAD +:02000e04MP6EXEC diff --git a/tools/z80/hex2bin/ihx/n88.ihx b/tools/z80/hex2bin/ihx/n88.ihx new file mode 100644 index 000000000..bf26a708a --- /dev/null +++ b/tools/z80/hex2bin/ihx/n88.ihx @@ -0,0 +1,18 @@ +:10000000d3d3d3d3d3d3d3d3d3d3202020202020 +:100010000d000a009720e0f10c00010018001400 +:1000200041f1e028112900000020202020202020 +:1000300020202020202020202020202020202020 +:1000400020202020202020202020202020202020 +:1000500020202020202020202020202020202020 +:1000600020202020202020202020202020202020 +:1000700020202020202020202020202020202020 +:1000800020202020202020202020202020202020 +:1000900020202020202020202020202020202020 +:1000a00020202020202020202020202020202020 +:1000b00020202020202020202020202020202020 +:1000c00020202020202020202020202020202020 +:1000d00020202020202020202020202020202020 +:1000e00020202020202020202020202020202020 +:1000f00020202020202020202020202020202020 +:0f010000202020202020202020202020202020 +:06000a02TAPE diff --git a/tools/z80/hex2bin/ihx/rom60.ihx b/tools/z80/hex2bin/ihx/rom60.ihx new file mode 100644 index 000000000..b09bc3ce4 --- /dev/null +++ b/tools/z80/hex2bin/ihx/rom60.ihx @@ -0,0 +1,2 @@ +:0400000041420440 +:02000204ROMEXEC diff --git a/tools/z80/hex2bin/ihx/rom62.ihx b/tools/z80/hex2bin/ihx/rom62.ihx new file mode 100644 index 000000000..85130d106 --- /dev/null +++ b/tools/z80/hex2bin/ihx/rom62.ihx @@ -0,0 +1,2 @@ +:0400000043440440 +:02000204ROMEXEC diff --git a/tools/z80/hex2bin/ihx/suffix.ihx b/tools/z80/hex2bin/ihx/suffix.ihx new file mode 100644 index 000000000..e4bc38fb8 --- /dev/null +++ b/tools/z80/hex2bin/ihx/suffix.ihx @@ -0,0 +1 @@ +:0c000000000000000000000000000000 diff --git a/tools/z80/hex2bin/mode1 b/tools/z80/hex2bin/mode1 deleted file mode 100644 index 6124f2d1f..000000000 Binary files a/tools/z80/hex2bin/mode1 and /dev/null differ diff --git a/tools/z80/hex2bin/mode2 b/tools/z80/hex2bin/mode2 deleted file mode 100644 index 797cd18ae..000000000 Binary files a/tools/z80/hex2bin/mode2 and /dev/null differ diff --git a/tools/z80/hex2bin/mode5 b/tools/z80/hex2bin/mode5 deleted file mode 100644 index 7cb070a0d..000000000 Binary files a/tools/z80/hex2bin/mode5 and /dev/null differ diff --git a/tools/z80/hex2bin/n88 b/tools/z80/hex2bin/n88 deleted file mode 100644 index bd7cc8f5d..000000000 Binary files a/tools/z80/hex2bin/n88 and /dev/null differ diff --git a/tools/z80/hex2bin/rom60 b/tools/z80/hex2bin/rom60 deleted file mode 100644 index 648926b48..000000000 --- a/tools/z80/hex2bin/rom60 +++ /dev/null @@ -1 +0,0 @@ -AB@ \ No newline at end of file diff --git a/tools/z80/hex2bin/rom62 b/tools/z80/hex2bin/rom62 deleted file mode 100644 index 20fe7a638..000000000 --- a/tools/z80/hex2bin/rom62 +++ /dev/null @@ -1 +0,0 @@ -CD@ \ No newline at end of file diff --git a/tools/z80/hex2bin/src/hexameter.c b/tools/z80/hex2bin/src/hexameter.c index d94e7df3c..29b6a2547 100644 --- a/tools/z80/hex2bin/src/hexameter.c +++ b/tools/z80/hex2bin/src/hexameter.c @@ -38,29 +38,24 @@ * A main file for hex2cas. */ +#define MAX_PATH 1024 -#if __CYGWIN32__ -#include -#else -#include -#endif #include +#include +#include #include -#ifndef TRUE -#define TRUE 1 -#endif +#include #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 \n"); - printf("Usage: %s [options] [...]\n", argv[0]); + printf("Usage: hexameter [options] [...]\n"); printf("Options:\n"); printf(" -v verbose output\n"); printf(" -o \n"); -// printf(" -n (for NEC PC series)\n"); - printf(" -p \n"); - printf(" -s \n"); + printf(" -d = define property\n"); printf(" -b \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; } diff --git a/tools/z80/hex2bin/src/ihx2bin.c b/tools/z80/hex2bin/src/ihx2bin.c index 3a068e5a8..199f9ccc4 100644 --- a/tools/z80/hex2bin/src/ihx2bin.c +++ b/tools/z80/hex2bin/src/ihx2bin.c @@ -35,19 +35,41 @@ */ /* - * Intel HEX format to PC-6001 CAS format conversion utility. + * Intel HEX format (extended) to binary format conversion utility. */ #include +#include #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); } diff --git a/tools/z80/hex2bin/src/ihx2bin.h b/tools/z80/hex2bin/src/ihx2bin.h index d06c81d13..afa05f42c 100644 --- a/tools/z80/hex2bin/src/ihx2bin.h +++ b/tools/z80/hex2bin/src/ihx2bin.h @@ -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__ */ diff --git a/tools/z80/hex2bin/suffix b/tools/z80/hex2bin/suffix deleted file mode 100644 index ce58bc9f8..000000000 Binary files a/tools/z80/hex2bin/suffix and /dev/null differ