home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff345.lzh
/
X2X
/
x2x_main.c
< prev
Wrap
C/C++ Source or Header
|
1990-04-16
|
16KB
|
570 lines
/*SCCS header - %W% %G% */
/************************************************************************
* *
* Filename: x2x_main.c *
* Version: 0.0 *
* Author : Gary Duncan *
* 24 Inkster St *
* Kambah ACT 2902 *
* Australia *
* *
*-----------------------------------------------------------------------*/
#include "x2x_amiga.h"
#include "x2x_data.c"
extern uchar Ichar();
extern char *MakeDate[] ;
/*************************************************************************
*
* Modification record
* -------------------
*
* Date By whom Change
* ---- ------- ------
*
* 12 Apr 89 GMD AMIGA'd
*
*------------------------------------------------------------------------
*
* This program will convert a given file in Down-Line Load (DLL) format
* to another (or the same) DLL format .
*
* The DLL formats are the usual ASCII_hex formats of
* INTEL / TEKTRONIX ( and extended) / MOTOROLA (S1-3)
*
* If no input params , the program solicits for :-
*
* 1) Input File name ( which it then scans to determine DLL format)
* 2) Output file DLL format
* 3) Output DLL record DATA length ( 0 < len < 256 )
*
* ( In MOTOROLA format , prompts are made for addr length , ie 2,3, 4 bytes)
*
* else ( if there are params ) , it is invoked as follows :-
*
* x2x -Ifilename -Otype [-Srecord_data_length]
*
* type : I=INTEL , T=TEKTRONIX ,t= TEKTRONIX (extended)
* M1=MOTOROLA (S1) , M2=MOTOROLA (S2) M3=MOTOROLA (S3)
*
*
* Output file name generation
*-----------------------------
*
* VAX
*
* The input file name then has ".xi / .xt / .xm2,3,or4 / or .xq appended
* to form the output file name. Note that no overwrite check is done.
* e.g fred.xi -> fred.xi.xi -> fred.xi.xi.x(whatever) etc
*
* PC
*
* A filename in wonderful MS_DOS is limited to the form of :-
* <8 charas max>.< 3 charas max> thus appending ( appension ?) to
* avoid ambiguity is not possible thus we progressively "backspace"
* from the "." separator looking for a non-'&' chara which is then
* transformed to '&'.
* e.g (INTEL to INTEL ) , abcdef.xi -> abcde&.xi -> abcd&&.xi etc
*
* Note that there is no restriction on cross-conversion ; ie you can
* use this program to produce a file of the same format but of a different
* data length. ( This could be useful because utilities such as AZTEC
* 'hex86' program only create DLL records with the boring length of 16)
*
* Whilst running , the program displays dots before the eyes to soothe
* those who are nervous about silent programs.
*
*
* On Completion
* -------------
* ... some nice stats are presented. Note that the
* checksum is a one_byte_sum_with_carry_wrap of the data
* bytes ( a la MICE ) so if using the MICE you can verify
* the Down Line Load with its memory checksum command (T).
* ( valid only for contiguous load , of course )
*
*************************************************************************
*
* *
* This program will run on a uVAX or IBM PC *
* *
* VAX build : cc -o x2x x2x.c ( produces x2x* ) *
* *
* IBM PC " : cc -DAMIGA x2x.c *
* ln x2x.o \lib\c.lib \lib\s.lib *
* ( produces x2x.exe ) *
* *
* *
*************************************************************************
*
#############################################################################
#
# Examples of ACSII-hex formats for :-
#
# INTEL
# MOTOROLA
# TEKTRONIX ( inc extended format )
#
#
# Note: the INTEL example (data length 16dec bytes) is the reference.
# : in following "byte" = binary value of 2 ASCII-hex charas
# hi nibble = 1st byte
#
#############################################################################
#
# Format : INTEL
#
:LLAAAATTdd..ddCC
LL = # of data bytes
AAAA = 16 bit address
TT = type
0 = data
1 = end record
2 = Upper Segment Base Address (USBA)
3 = start address record ( data length = 4 bytes)
CC = checksum ( = -ve sum of record : ie sum of all byte-pairs = 0 )
dd = ASCII-hex charas
USBA format = :02000002ssssCC
( following data records will be have (16 * ssss) added to their load addr)
----------------------------------------------------------------------------
:020000020500?? # type 2 record , base = 500H
:1012340090FAFCE96B002020202020202020202090 # type 0 record (data)
# (load addr = 1234H)
:00000001FF # type 1 record (end)
# above converted to :-
:1062340090FAFCE96B002020202020202020202040 <<EXAMPLE
:00000001FF
#-----------------------------------------------------------------------------
#
# MOTOROLA - all use S9 as end record
#
#
# Format : Motorola ( S1 , 16 bit address )
#
|<-------------- LL ---------------->|
S1LLAAAAdd..ddCC << Format
LL = 2 + (# of data bytes) + 1
AAAA = address
CC = ~( LL + (AA .. + AA) + ( data bytes )) : Note 1's complement!
S1LLAAAAdd..ddCC << Format
S113623490FAFCE96B00202020202020202020203C <<EXAMPLE
S9030000FC
#-----------------------------------------------------------------------------
#
# Format : Motorola ( S2 , 24 bit address )
#
S2LLAAAAAAdd..ddCC << Format
S21400623490FAFCE96B00202020202020202020203B <<EXAMPLE
S904000000FB
#-----------------------------------------------------------------------------
#
# Format : Motorola ( S3 , 32 bit address )
#
STLLAAAAAAAAdd..ddCC << Format
S3150000623490FAFCE96B00202020202020202020203A <<EXAMPLE
S90500000000FA
#-----------------------------------------------------------------------------
#
# Format : Tektronix
#
# Note checksum algorithm
#
/AAAALLRRdd..ddCC << Format
AAAA = load address
LL = record length ( # of data bytes : 0 = last record )
RR = load checksum ( = sum of previous 6 de-ASCII'd CHARAS )
CC = data " ( sum of de-ASCII'D CHARAS )
/AAAALLRRdd..ddCC << Format
/6234101090FAFCE96B002020202020202020202079 <<EXAMPLE
/00000000
#-----------------------------------------------------------------------------
#
# Format : Tektronix (extended)
#
# Note checksum algorithm
#
%LLTCCky......ydd..dd << Format
LL = length ( all charas after % )
T = type chara ( 6 = data , 8 = end )
CC = checksum ( sum of all de-ASCII'd CHARAS = 0 )
k = # of address charas, max 8 ( = 4 bytes )
y...y = 'k' address charas
xx = data as usual
%LLTCCky......ydd..dd << Format
%2E6A680000623490FAFCE96B0020202020202020202020 <<EXAMPLE
%0E81E800000000
*
*------------------------------------------------------------------------------
* Contents
* -------
*+
*+ main exec bit..
*+ getc2 gets byte from 2 ASCII hex bytes
*+ convc2 converts 2 ASCII hex bytes to a byte
*+ get_hex converts ASCII hex chara to binary
*+ Ichar gets chara from input file
*+
*
******************************************************************************/
/*------------------------------------------------------------------------*/
main (argc,argv)
int argc;
char *argv[];
{
int temp ;
/*----------------------- announce program / vers -------------------------*/
printf ( "\nX2X - %s : written by Gary Duncan\n" , MakeDate[0] ) ;
iffp = 0 ;
opftype = -1 ; /* invalidate things */
if ( argc == 1 ) /* no params , solicit for them */
sol_params () ;
else /* use command line params then */
xmode = com_params ( argc , argv ) ;
/*------------------------ build o/p file here -------------------------*/
f_reset () ;
xlen = 1 ;
while ( xlen ) /* loop to process input file */
{
#if 0
if ( func1 () ) /* PC only - exit on FUNC1 */
exit (1) ;
#endif
fill_ipbuf () ; /* fill input data buffer */
xaddr = 0 ;
xlen = get_len ( &xaddr ) ; /* find length of continuous chunk */
switch ( opftype )
{
case 0 : /* INTEL */
if ( ousba != ousban ) /* .. build a type 2 record maybe ? */
{
ousba = ousban ;
xdllen = dll_Irec ( 2 , (long)ousba , 2 ) ; /* gen record */
opbuf [xdllen++] = '\n' ; /* append RETURN to record */
rite_rec ( offp , opbuf , xdllen ) ; /* write it */
++oprecs ;
}
if (xlen) /* end record ? */
{
xtype = 0 ; /* no */
}
else /* yes , maybe insert checksum record */
{
xtype = 1 ;
if ( xmode == 3 ) /* checksum mode ? */
{
gen_csum () ; /* build and write last data rec */
}
}
xdllen = dll_Irec ( xtype, xaddr, xlen ) ; /* build INTEL record */
break ;
case 1 : /* MOTOROLA */
case 2 :
case 3 :
(xlen) ? (xtype = opftype + '0') : (xtype = '9') ;
/* data or eof rec type */
xdllen = dll_Mrec ( xtype , xaddr , xlen ) ;
break ;
case 4 : /* TEKTRONIX */
xdllen = dll_Trec ( 0 , xaddr ,xlen ) ;
break ;
case 5 : /* TEKTRONIX - extended */
(xlen) ? (xtype = '6') : (xtype = '8') ; /* data or eof rec type */
xdllen = dll_Txrec ( xtype , xaddr ,xlen ) ;
break ;
case 6 : /* QTAM */
xdllen = dll_Qrec ( 0 , xaddr , xlen ) ;
break ;
} ;
/*--------------now write record to disc ----------------------------------*/
++datarecs ;
++oprecs ;
totchars += xlen ; /* update total data chara count */
opbuf [xdllen++] = '\n' ; /* append RETURN to each record */
rite_rec ( offp , opbuf , xdllen ) ; /* write it */
if ( (!(totchars & 0x3FF) ) && (!pdots) )
fprintf ( stderr , "." ) ; /* dots before the eyes.... , every 1K */
}
/*-------------------- FIN , print a message -------------------------------*/
if ( odccon ) /* flush write buffer */
{
if ( write( offp , dlldbuf , odccon) != odccon )
{
perror("Disc write error: ");
exit(3);
}
}
printf ( "\nOutput file is : %s\n" , ofile ) ;
printf ( "*** Total recs = %d, Data recs = %d \n", oprecs , datarecs ) ;
printf ( "*** Reclen = %d, Data chars = %ldDec/%lXH \n",
reclen , totchars, totchars ) ;
/*--------- if -P/-C option , put printable charas in checksum buffer
into "temp.x2x" ( bit of a kluge for documentation) ----*/
if ( temp = strlen ( mallocptr ) )
if ( write( tffp , mallocptr , temp ) != temp )
{
fprintf (stderr,"(rite_rec) - write error" );
perror("Disc write error: ");
exit(3);
}
exit (0) ;
}
/***************************************************************************
Function : getc2
Purpose :
Entry :
Returns : TRUE -
FALSE-
****************************************************************************/
int getc2 ( ) /* returns with de-hexed byte
from 2 ASCII hex bytes */
{
int c , c0 , c1 ;
if ( (c = Ichar ()) == -1 ) /* MS nibble */
{
fprintf ( stderr , "\Ichar fail" ) ;
exit (3) ;
}
if ( (c0 = get_hex (c) ) == -1 )
{
fprintf ( stderr , "\Non ASCII-hex chara in file = %c " , c ) ;
exit (3) ;
}
if ( (c = Ichar ()) == -1 ) /* MS nibble */
{
fprintf ( stderr , "\Ichar fail" ) ;
exit (3) ;
}
if ( (c1 = get_hex (c) ) == -1 )
{
fprintf ( stderr , "\Non ASCII-hex chara in file" ) ;
exit (3) ;
}
c = (( c0 << 4 ) | c1 ) ;
return ( c & 0xFF ) ; /* ensure return byte here only */
}
/***************************************************************************
Function : convc2
Purpose : converts byte to 2 ASCII hex charas
Entry :
Returns : (hi byte/lo byte) as int
****************************************************************************/
int convc2 ( bite )
unsigned char bite ;
{
unsigned char cc , k ;
unsigned int chch = 0 ;
cc = bite ;
k = cc ;
cc = (k >> 4) & 0xF ; /* MS nibble */
(cc < 0xA) ? ( cc = cc + '0') : ( cc = cc + 'A' - 10 ) ;
chch = (int) cc << 8 ; /*Hi nibble */
cc = k & 0xF ;
(cc < 0xA) ? ( cc = cc + '0') : ( cc = cc + 'A' - 10 ) ;
return ( chch | cc ) ;
}
/***************************************************************************
Function : get_hex
Purpose : Returns with given ASCII hex chara de-ASCIIed
Entry : chara
Returns : - 1 , error , else chara ( 0 > 15 )
**************************************************************************/
int get_hex ( bite )
uchar bite ;
{
if ( isdigit (bite) )
return ( bite & 0xF ) ; /* number */
bite |= 0x20 ;
if ( islower (bite) && ( bite < 'g') )
return ( (bite & 0xF) + 9 ) ; /* A _ F */
return ( -1 ) ; /* error */
}
/***************************************************************************
Function : Ichar
Purpose : Returns with chara from input file
Entry : chara
Returns : - 1 , error , else chara
**************************************************************************/
uchar Ichar ()
{
int ch ;
if ( boffs == -1 )
return ( -1 ) ; /* File empty */
if ( !disclen )
{
disclen = read (iffp , dbuf , 1024 ) ; /* read a block of file */
boffs = 0 ;
}
if ( !disclen )
return ( -1 ) ;
ch = dbuf[ boffs ] &0xFF ;
xchek += ch ; /* accum a checksum for ext use */
if ( ++boffs != disclen )
return ( ch ) ;
else if ( boffs == 1024 )
disclen = 0 ; /* flag buffer empty */
else
boffs = -1 ; /* flag file empty */
return ( ch ) ;
}