A binary conversion tool has been modified to support variations.

This commit is contained in:
matsutsuka 2008-07-02 07:17:14 +00:00
parent 29b17c6933
commit 4ecebdd842
15 changed files with 714 additions and 8 deletions

View file

@ -2,7 +2,7 @@
# Makefile for PC-6001 using z80/SDCC # Makefile for PC-6001 using z80/SDCC
# @author Takahide Matsutsuka <markn@markn.org> # @author Takahide Matsutsuka <markn@markn.org>
# #
# $Id: Makefile.pc-6001,v 1.7 2007/11/28 10:11:55 matsutsuka Exp $ # $Id: Makefile.pc-6001,v 1.8 2008/07/02 07:17:14 matsutsuka Exp $
# #
ifndef CONTIKI ifndef CONTIKI
@ -48,7 +48,7 @@ endif
### setup default values ### setup default values
ifndef HEX2BIN ifndef HEX2BIN
HEX2BIN = hex2cas HEX2BIN = ../../tools/z80/hexameter/hexameter
endif endif
### setup flags to be used in compiler, assembler, and HEX2BIN ### setup flags to be used in compiler, assembler, and HEX2BIN
@ -59,16 +59,16 @@ CFLAGS += -DMEMORY_$(MEMORY) -DARCH_$(ARCH) -DCTK_$(CTKCONF)
ifeq ($(MEMORY),16K) ifeq ($(MEMORY),16K)
LDFLAGS += --code-loc 0xc40f --data-loc 0 LDFLAGS += --code-loc 0xc40f --data-loc 0
HEX2BINFLAGS = -1 -n contki -o contiki.p6 HEX2BINFLAGS = -p mode1 -s suffix -n contki -o contiki.p6
else ifeq ($(MEMORY),ROM) else ifeq ($(MEMORY),ROM)
LDFLAGS += --code-loc 0x4004 --data-loc 0xf000 LDFLAGS += --code-loc 0x4004 --data-loc 0xf000
HEX2BINFLAGS = -r -o contiki.rom HEX2BINFLAGS = -p rom60 -o contiki.rom
else ifeq ($(ARCH),PC6001MK2) else ifeq ($(ARCH),PC6001MK2)
LDFLAGS += --code-loc 0x800f --data-loc 0 LDFLAGS += --code-loc 0x800f --data-loc 0
HEX2BINFLAGS = -5 -o contiki2.p6 HEX2BINFLAGS = -p mode5 -s suffix -o contiki2.p6
else else
LDFLAGS += --code-loc 0x840f --data-loc 0 LDFLAGS += --code-loc 0x840f --data-loc 0
HEX2BINFLAGS = -2 -n contki -o contiki.p6 HEX2BINFLAGS = -p mode2 -s suffix -n contki -o contiki.p6
endif endif
ifeq ($(LOADER),1) ifeq ($(LOADER),1)
@ -107,10 +107,13 @@ contiki: contiki.p6
.SUFFIXES: .SUFFIXES:
%.p6: %.ihx %.p6: $(HEX2BIN) %.ihx
$(HEX2BIN) $(HEX2BINFLAGS) $< $(HEX2BIN) $(HEX2BINFLAGS) $<
%.rom: %.ihx %.rom: %.ihx
$(HEX2BIN) $(HEX2BINFLAGS) $< $(HEX2BIN) $(HEX2BIN) $(HEX2BINFLAGS) $<
$(HEX2BIN):
cd ../../tools/z80/hexameter/; make
remove-ctk: remove-ctk:
rm -f obj_$(TARGET)/ctk*; rm -f obj_$(TARGET)/ctk*;

View file

@ -0,0 +1 @@
hexameter.exe

View file

@ -0,0 +1,17 @@
#
# Makefile for hexameter
# @author Takahide Matsutsuka <markn@markn.org>
#
# $Id: Makefile,v 1.1 2008/07/02 07:17:14 matsutsuka Exp $
#
CFLAGS =
SOURCEDIR = src
TARGET = hexameter.o ihx2bin.o
vpath %.c $(SOURCEDIR)
hexameter: $(TARGET)
clean:
rm -f *.o *~ hexameter.exe

View file

@ -0,0 +1,131 @@
hexameter : Convert Intel hex files to a binary file
version 2.0.0
Copyright (c) 2003-2008, Takahide Matsutsuka.
1/ What is it?
It converts Intel hex files, which emitted by SDCC-Z80 compiler, to
a binary file. You can attach additional prefix and/or suffix file
to comply the file with arbitrary binary format.
It provides a development environment of C language on PC-6001 and
other old computers.
2/ Installation
Installation can be done in following steps.
a) Download and install SDCC from http://sdcc.sf.net/
Version 2.8.0 is 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".
3/ Use
a) Write your own C code.
b) Compile your code using SDCC.
While linking, you need to specify options for SDCC so that the
code can be worked on your machine.
See sample/Makefile for actual usage.
% sdcc -mz80 -c YOUR_CODE1.c
% sdcc -mz80 -c YOUR_CODE2.c
This step creates a file YOUR_CODE1.o and YOUR_CODE2.o respectively,
which run on Z80-based machine.
% for target in YOUR_CODE1.o YOUR_CODE2.o; do echo $@ >> YOUR_LIB.lib $@; done
This step makes a library file.
sdcc -mz80 --no-std-crt0 --code-loc 0x840f --data-loc 0 -o YOUR_APP.ihx crt0.o -lYOUR_LIB.lib
-mz80 specifies the Z80 mode.
--code-loc specifies the start address of your object code.
Basically, it depends on the machine and RAM size. As for PC-6001,
0x840f for 32kB, or 0xc40f for 16kB. As for PC-6001mkII, it would
be 0x800f.
If you are not sure what you are about to do, just leave it as
default 0x840f.
--data-loc 0 specifies the code is followed by data.
You can specify an arbitrary address instead.
--no-std-crt0 indicates that you use your own crt0 instead of sdcc's
default crt0 object. The customized crt0.o file is in lib directory
of this release.
c) Convert ihx file to cas file using hex2cas.
hexameter YOUR_CODE.ihx [YOUR_CODE2.ihx ...]
The ihx files are just attached in the specified order.
Here you can take some options:
-p <filename> specify prefix file name.
-s <filename> specify suffix file name.
-n <name> specify PC-6001 cassette file name,
must be 6 characters or less.
-v verbose output
-o <filename> specify output file name
-b <size> 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
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
e) Load your cas file into your 6001 emulator.
I've checked it working on the following emulators:
VirtualTrek
http://www.geocities.com/emucompboy/
iP6Win
http://www.retropc.net/mm/pc6001/
PC-6001VW
http://bernie.hp.infoseek.co.jp/develop/pc6001vw.html
4/ Note
- While I've tested the tool on Cigwin on Win32, I think it works
on other environments with a little work.
- SDCC has many isuues regarding compilation. Don't blame me about them! :)
5/ History
3/29/2003 1.0.0 First version
4/20/2003 1.0.1 Mode option has been added
9/01/2007 1.1.0 ROM-mode has been added
9/28/2007 1.2.0 Customized crt0 has been introduced to clear global data
3/15/2008 1.3.0 VRAM options introduced
4/28/2008 1.4.0 Header file option introduced
5/17/2008 2.0.0 Migrated to hexameter, to support more flexible configurations
Enjoy!
http://www.markn.org/
markn@markn.org

BIN
tools/z80/hex2bin/mode1 Normal file

Binary file not shown.

BIN
tools/z80/hex2bin/mode2 Normal file

Binary file not shown.

BIN
tools/z80/hex2bin/mode5 Normal file

Binary file not shown.

BIN
tools/z80/hex2bin/n88 Normal file

Binary file not shown.

1
tools/z80/hex2bin/rom60 Normal file
View file

@ -0,0 +1 @@
AB@

1
tools/z80/hex2bin/rom62 Normal file
View file

@ -0,0 +1 @@
CD@

View file

@ -0,0 +1,315 @@
/*
* 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.
*/
/*
* A main file for hex2cas.
*/
#if __CYGWIN32__
#include <windows.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <unistd.h>
#ifndef TRUE
#define TRUE 1
#endif
#include "ihx2bin.h"
#define MAXFILES 256
struct Configuration {
char* output;
char* prefix;
char* suffix;
char* dir;
char archname[6];
char *files[MAXFILES];
unsigned char verbose;
// number of the ihx files
int length;
// output file size
int size;
// output file wriiten size
int written;
};
static char *changeExt(const char *path, const char* ext) {
char *p;
char *tail;
char *changed;
int len;
int extlen = strlen(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);
strncpy(changed, path, len + 1);
strcpy(changed + len + 1, ext);
return changed;
}
}
len = strlen(path);
changed = (char*) malloc(len + extlen + 2);
strncpy(changed, path, len);
*(changed + len) = '.';
strcpy(changed + len + 1, ext);
return changed;
}
static unsigned char analyzeOption(int argc, char **argv, struct Configuration *config) {
int c;
opterr = 0;
while ((c = getopt(argc, argv, "hvo:p:s:n:b:")) != EOF) {
int i;
switch (c) {
case 'v':
config->verbose = TRUE;
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 'h':
printf("%s : Convert Intel HEX file (ihx) to binary file, ver. 2.0.0\n", getprogname());
printf("Copyright (c) 2003-2008 Takahide Matsutsuka <markn@markn.org>\n");
printf("Usage: %s [options] <ihx> [<ihx>...]\n", argv[0]);
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(" -b <output file size in hexadecimal bytes>\n");
printf(" -h print this help\n");
return 1;
default:
printf("unknown option:%c\n", optopt);
return 1;
}
}
return 0;
}
static int isFileExists(const char *dir, const char *filename) {
char path[MAX_PATH];
FILE *f;
if (!filename) {
return 0;
}
if (dir) {
strcpy(path, dir);
strcpy(path + strlen(path), filename);
} else {
strcpy(path, filename);
}
if (!(f = fopen(path, "rb"))) {
printf("cannot open: %s\n", filename);
return 1;
}
fclose(f);
return 0;
}
static int checkExistence(struct 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) {
printf("cannot open: %s\n", config->files[i]);
return 1;
}
fclose(f);
}
return 0;
}
/**
* @return writtn size in bytes
*/
static
int copy(FILE *out, const char* dir, const char* filename, unsigned char verbose) {
FILE *in;
char ch;
char path[MAX_PATH];
int bytes = 0;
if (!filename) {
return 0;
}
if (dir) {
strcpy(path, dir);
strcpy(path + strlen(path), filename);
} 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++;
}
return bytes;
}
static int output(struct 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);
}
config->written += copy(out, config->dir, config->suffix, config->verbose);
if (config->size) {
if (config->verbose) {
printf("Writing trailing bytes\n");
}
for (; config->size > config->written; config->written++) {
putc(0, out);
}
}
fclose(out);
return 0;
}
int main(int argc, char **argv) {
struct 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
while (optind < argc) {
if (r = analyzeOption(argc, argv, &config)) {
return r;
}
if (optind == argc) {
break;
}
if (config.length == MAXFILES) {
printf("too much files specified\n");
return 1;
}
config.files[config.length] = argv[optind];
config.length++;
optind++;
}
if (config.length == 0) {
printf("no input specified\n");
return 1;
}
if (config.output == NULL) {
config.output = changeExt(config.files[0], "bin");
}
if (r = checkExistence(&config)) {
return r;
}
if (config.verbose) {
printf("Generating file: %s\n", config.output);
}
if (r = output(&config)) {
return r;
}
if (config.verbose) {
printf("Done.\n");
}
return 0;
}

View file

@ -0,0 +1,190 @@
/*
* 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);
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2003-2007, 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 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 BY THE AUTHOR ``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 AUTHOR 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.
*
* $Id: ihx2bin.h,v 1.1 2008/07/02 07:17:14 matsutsuka Exp $
*
*/
/*
* A header file for ihx2bin
* @author Takahide Matsutsuka <markn@markn.org>
*/
#ifndef __IHX2BIN_H__
#define __IHX2BIN_H__
/* A default architecture-depend file name. */
#define DEFAULT_ARCH_FILENAME "noname"
int ihx2bin(FILE* dst, const char *src, unsigned char verbose);
#endif /* __IHX2BIN_H__ */

BIN
tools/z80/hex2bin/suffix Normal file

Binary file not shown.

Binary file not shown.