home *** CD-ROM | disk | FTP | other *** search
- #define NAME "BinHex"
- #define REVISION "20"
- #define DATE "22.06.2000"
- //#define DEBUG
-
- /* Programmheader
-
- Name: BinHex
- Author: SDI
- Distribution: PD
- Description: converts binary into hexadecimal data and reverse
- Compileropts: -
- Linkeropts: -l amiga
-
- 1.0 03.10.95 : first version
- 1.1 15.10.95 : recompiled
- 1.2 05.02.96 : recompiled with better includes
- 1.3 06.02.96 : MakeHEX instead of MakeBASE
- 1.4 10.02.96 : compiled with my own StartUp
- 1.5 12.03.96 : added option ONLYDATA, \ Option, english texts
- 1.6 04.05.96 : removed error with ReadArgs
- 1.7 11.05.96 : option ROWS added
- 1.8 12.05.96 : option ASMDATA added
- 1.9 11.06.96 : EndCode like in SDI_defines.h
- 1.10 16.06.96 : corrected buffer overworking bug
- 1.11 06.10.96 : if last char was an \t program hanged - fixed
- 1.12 21.11.96 : added option CDATA, same as ASMDATA but for C
- 1.13 04.02.97 : added REVERSED option (now MAKEBIN only)
- 1.14 09.02.97 : own functions for ASMDATA and CDATA, SIZE parameter
- 1.15 08.93.97 : fixed forgotten address problem, compiler error ?
- 1.16 18.03.97 : SDI include names changed
- 1.17 26.05.97 : fixed problems with c:Ed
- 1.18 31.05.97 : SDI_isprint no longer allows 0x7f
- 1.19 27.06.99 : added NOASCII
- 1.20 22.06.00 : removed need for SDI_ASM_protos.h
- */
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include "SDI_version.h"
- #include "SDI_structures.h"
- #include "SDI_ASM_STD_protos.h"
- #include "SDI_protos.h"
- #include "SDI_GetLength.c" /* These files are in SDI_functions.o. Remove */
- #include "SDI_FillBuf.c" /* the lines and build your own makefile. */
- #include "SDI_WriteBuf.c"
- #include "SDI_FreeBuf.c" /* Add also the .lib files to the makefile */
- #include "SDI_GetBuffer.c" /* to make compilation successful! */
-
- struct SDI_InOut bin = {0, 0, 0, 0, 0},
- hex = {0, 0, 0, 0, 0};
- STRPTR revbuf = 0;
- ULONG revsize = 16;
- struct RDArgs *rda = 0;
- ULONG DosVersion = 37; /* forces OS 37! */
-
- #define PARAM "BIN/A,HEX/A,MAKEBIN/S,ONLYDATA/S,ROWS/N,ASMDATA/S,CDATA/S" \
- ",REV=REVERSED/S,SIZE/N,NOTAB/S,NOASCII/S"
-
- struct Args {
- STRPTR bin;
- STRPTR hex;
- LONG makebin;
- LONG onlydata;
- LONG *rows;
- LONG asmdata;
- LONG cdata;
- LONG reversed;
- LONG *size;
- LONG notab;
- LONG noascii;
- };
-
- #define NUMPERLINE (rows<<2)
- #define LINESIZE (rows*(4*(2+1)+1)+8+1+1)
- /* rowcount * (4 * (2 numbers + 1 ASCII-character) + 1 space) +
- 9 for address + 1 space + 1 return */
- #define MAINSIZE (rows*(4*2+1))
- #define ASCIIPOS (MAINSIZE+8+1)
- #define RESTSIZE (NUMPERLINE+8+1+1)
-
- UBYTE GetHEXNum(UBYTE);
- STRPTR MakeBin(STRPTR, ULONG, ULONG);
- ULONG WriteDataLine(ULONG, ULONG, ULONG);
- void MakeHEX(STRPTR p, BYTE num, ULONG val);
- void End(UBYTE err);
-
- #define MAKECLINE 1
- #define MAKEASMLINE 0
-
- void main(void)
- {
- LONG size = 0;
- struct Args args;
- ULONG h;
- UBYTE rows = 5;
-
- SDI_memset(&args, 0, sizeof(struct Args));
- args.size = &size;
-
- if(!(rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
- End(RETURN_FAIL);
-
- rda->RDA_ExtHelp =
- /*
- "Mit dem Programm können binäre Dateien in Hexadezimal dargestellte "
- "Dateien umgewandelt werden. Diese kann man dann mit einem Editor "
- "bearbeitet und wieder in eine Binärdatei umwandeln. "
- "Das Programm liest aus der Hexdatei alle Hex-Zahlen bis zu einem "
- "Tabulator, dann geht es nach dem nächsten Return weiter. Sie müssen "
- "also nicht darauf achten, wieder die genaue Zeilenlänge zu erhalten. "
- "Zwischen Return und Tabulator dürfen jedoch nur die Zeichen 0-9 und A-F "
- "stehen und zwar in einer geraden Anzahl. Das Leerzeichen ist als "
- "Trenner erlaubt. Nach einem \\ wird alles so übernommen, wie gegeben. "
- "Das ist für Texteingaben sehr nützlich.\n";
- */
- "Use this program to convert binary data into hexadecimal data. This data "
- "can be edited with a normal text editor. After that it can again become"
- "binary. The program reads in the hexadecimal file all numbers from line "
- "start to next tab stop or return. You do not need to make the linelength "
- "exact as before! Only 0-9 and A-F are allowed in the data part. "
- "Spaces and data after the tab stop are ignored. After a \\ all data is "
- "not converted and taken as given to the binary file (useful for texts).\n";
-
- if(!ReadArgs(PARAM, (LONG *) &args, rda))
- End(RETURN_FAIL);
-
- if(args.rows && *args.rows > 0 && *args.rows < 256)
- rows = (UBYTE) *args.rows;
-
- if((args.makebin && (args.asmdata || args.cdata)) ||
- (args.asmdata && args.cdata))
- {
- PrintFault(ERROR_TOO_MANY_ARGS, 0);
- End(RETURN_FAIL);
- }
-
- if(args.makebin)
- {
- if(
- !(hex.file = Open(args.hex, MODE_OLDFILE)) ||
- !(bin.size = SDI_GetLength(hex.file)))
- End(RETURN_FAIL);
- bin.size = (bin.size >> 2) + 1;
- if(bin.size < NUMPERLINE)
- bin.size = NUMPERLINE;
- }
- else
- {
- if(
- !(bin.file = Open(args.bin, MODE_OLDFILE)) ||
- !(bin.size = SDI_GetLength(bin.file)))
- End(RETURN_FAIL);
- }
-
- if((hex.size = bin.size << 2) > (h = AvailMem(MEMF_LARGEST)))
- hex.size = h;
- if(hex.size < LINESIZE)
- hex.size = LINESIZE;
- if(!SDI_GetBuffer(&hex))
- End(RETURN_FAIL);
- if(args.noascii && args.onlydata)
- args.noascii = 0;
-
- if(args.reversed)
- {
- if(*args.size > 0)
- revsize = *args.size;
-
- if(bin.size < revsize) /* need at least revsize buffer */
- bin.size = revsize;
- }
- else if(*args.size != 2 && *args.size != 4)
- *args.size = 1; /* set correct size info */
-
- if(bin.size > (h = AvailMem(MEMF_LARGEST)))
- bin.size = (h > revsize ? h : revsize);
-
- if(!SDI_GetBuffer(&bin))
- End(RETURN_FAIL);
-
- if(!(args.makebin ? (bin.file = Open(args.bin, MODE_NEWFILE)) :
- (hex.file = Open(args.hex, MODE_NEWFILE))))
- End(RETURN_FAIL);
-
- if(args.reversed && !(revbuf = (STRPTR) AllocMem(revsize, MEMF_ANY)))
- End(RETURN_FAIL);
-
- if(args.asmdata)
- {
- STRPTR start = "\tDC.B\t";
-
- if(*args.size == 2)
- start[4] = 'W';
- else if(*args.size == 4)
- start[4] = 'L';
-
- SDI_FillBuf(&bin);
- do
- { /* WriteDataLine everytime lets enough space in destination buffer */
- CopyMem(start, hex.pos, 6);
- hex.pos += 6;
- } while(WriteDataLine(*args.size, rows<<2, MAKEASMLINE));
- SDI_WriteBuf(&hex, 0);
- }
- else if(args.cdata)
- {
- SDI_FillBuf(&bin);
- switch(*args.size)
- {
- case 1: CopyMem("UBYTE bin_data[] = {\n", hex.pos, 21); break;
- case 2: CopyMem("UWORD bin_data[] = {\n", hex.pos, 21); break;
- case 4: CopyMem("ULONG bin_data[] = {\n", hex.pos, 21); break;
- };
- hex.pos += 21;
-
- do
- {
- *(hex.pos++) = ' '; *(hex.pos++) = ' ';
- } while(WriteDataLine(*args.size, rows<<2, MAKECLINE));
- *(hex.pos++) = '}';
- *(hex.pos++) = ';';
- *(hex.pos++) = '\n';
- SDI_WriteBuf(&hex, 0);
- }
- else if(args.makebin)
- {
- SDI_FillBuf(&hex);
- if(!args.reversed)
- {
- while(!(bin.pos = MakeBin(bin.pos, bin.size, args.notab)))
- {
- bin.pos = bin.buf + bin.size;
- SDI_WriteBuf(&bin, 0);
- }
- }
- else
- {
- STRPTR bufptr;
- while(!(bufptr = MakeBin(revbuf, revsize, args.notab)))
- {
- bufptr = revbuf + revsize;
- if(bin.buf+bin.size-bin.pos < revsize)
- SDI_WriteBuf(&bin, 0);
- while(bufptr != revbuf)
- *(bin.pos++) = *(--bufptr);
- }
- if(bin.buf+bin.size-bin.pos < bufptr-revbuf)
- SDI_WriteBuf(&bin, 0);
- while(bufptr != revbuf)
- *(bin.pos++) = *(--bufptr);
- }
- SDI_WriteBuf(&bin, 0);
- }
- else
- {
- ULONG address = 0;
-
- SDI_FillBuf(&bin);
- while(bin.count && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
- {
- STRPTR strptr;
-
- strptr = hex.pos + ASCIIPOS;
-
- for(h = 0; h < NUMPERLINE; ++h, ++bin.pos)
- {
- if(bin.pos < bin.buf + bin.count)
- {
- MakeHEX(hex.pos, 2, *bin.pos);
- hex.pos += 2;
- if(!args.onlydata && !args.noascii)
- *(strptr++) = SDI_isprint(*bin.pos) ? *bin.pos : '.';
- /* C:Ed cannot handle 0x7F */
- }
- else if(args.onlydata || args.noascii)
- break;
- else
- {
- *(hex.pos++) = ' '; *(hex.pos++) = ' ';
- *(strptr++) = ' ';
- }
- if(!((h+1 & 3) || args.onlydata))
- *(hex.pos++) = ' ';
- }
- if(!args.onlydata && !args.noascii)
- {
- *hex.pos = '$';
- MakeHEX(hex.pos+1, 7, address);
- *(hex.pos-1) = '\t'; *(hex.pos+8) = ' '; *strptr = '\n';
- hex.pos += RESTSIZE;
- }
- else if(args.noascii)
- *(hex.pos-1) = '\n';
- else
- *(hex.pos++) = '\n';
- address += NUMPERLINE;
- if(bin.pos >= bin.buf + bin.count - NUMPERLINE)
- SDI_FillBuf(&bin);
- if(hex.pos >= hex.buf + hex.size - LINESIZE)
- SDI_WriteBuf(&hex, 0);
- }
- SDI_WriteBuf(&hex, 0);
- }
-
- End(RETURN_OK);
- }
-
- UBYTE GetHEXNum(UBYTE h)
- {
- if(h > 47 && h < 58)
- return (UBYTE) (h - '0');
- else if(h > 64 && h < 71)
- return (UBYTE) (h - 'A' + 10);
- else if(h > 96 && h < 103)
- return (UBYTE) (h - 'a' + 10);
- return 0;
- }
-
- STRPTR MakeBin(STRPTR buf, ULONG size, ULONG notab)
- {
- static ULONG line = 1, row = 1;
- static UBYTE realmode = 0;
-
- while(hex.count && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
- {
- if(*hex.pos == '\t' || (notab && *hex.pos == '$'))
- {
- while(hex.count && *hex.pos != '\n')
- {
- ++hex.pos;
- if(hex.pos >= hex.buf + hex.count - 2)
- SDI_FillBuf(&hex);
- }
- }
- else if(*hex.pos == '\n')
- {
- ++line; row = 1; ++hex.pos; realmode = 0;
- }
- else if(!realmode && *hex.pos == ' ')
- {
- ++hex.pos; ++row;
- }
- else if(*hex.pos == '\\')
- {
- realmode = 1; ++hex.pos;
- }
- else
- {
- if(realmode)
- {
- *(buf++) = *(hex.pos++); ++row; --size;
- }
- else
- {
- if(!SDI_isxdigit(*hex.pos) || !SDI_isxdigit(*(hex.pos+1)))
- {
- Printf("line %ld, row %ld : ", line, row);
- SetIoErr(ERROR_SEEK_ERROR);
- End(RETURN_FAIL);
- }
- *buf = GetHEXNum(*(hex.pos++)) << 4;
- *(buf++) += GetHEXNum(*(hex.pos++));
- --size;
- row+=2;
- }
- }
- if(hex.pos >= hex.buf + hex.count - 2)
- SDI_FillBuf(&hex);
- if(!size)
- return 0;
- }
- return buf;
- }
-
- ULONG WriteDataLine(ULONG size, ULONG bytes, ULONG type)
- {
- ULONG pos = size;
- while(bin.count && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
- {
- if(hex.pos >= hex.buf + hex.size - 20)
- SDI_WriteBuf(&hex,0);
- if(pos == size)
- {
- pos = 0;
- if(!type)
- *(hex.pos++) = '$';
- else
- {
- *(hex.pos++) = '0'; *(hex.pos++) = 'x';
- }
- }
- MakeHEX(hex.pos, 2, *(bin.pos++)); hex.pos += 2;
- --bytes;
- if((++pos == size) && (type || bytes))
- *(hex.pos++) = ',';
- if(bin.pos >= bin.buf + bin.count)
- SDI_FillBuf(&bin);
- if(!bytes && bin.count)
- {
- *(hex.pos++) = '\n'; return 1;
- }
- }
-
- while(pos != size)
- {
- ++pos; *(hex.pos++) = '0'; *(hex.pos++) = '0';
- }
-
- *(hex.pos++) = '\n';
-
- return 0;
- }
-
- void MakeHEX(STRPTR p, BYTE num, ULONG val)
- {
- p[num] = 0; /*Ende der Zeichenkette gleich Null setzen --> CSTRING ! */
- while(--num >= 0)
- {
- p[num] += (p[num] = val&15) >= 10 ? 'A'-10 : '0';
- val >>= 4;
- }
- }
-
- void End(UBYTE err)
- {
- if((SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
- {
- err = RETURN_WARN;
- SetIoErr(ERROR_BREAK);
- }
-
- if(bin.file) Close(bin.file);
- if(hex.file) Close(hex.file);
- SDI_FreeBuf(&bin);
- SDI_FreeBuf(&hex);
- if(rda)
- {
- FreeArgs(rda);
- FreeDosObject(DOS_RDARGS, rda);
- }
- if(err)
- PrintFault(IoErr(), 0);
- exit(err);
- }
-
-