home *** CD-ROM | disk | FTP | other *** search
- /*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 ) ;
-
- }
-