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   
C/C++ Source or Header  |  1990-04-16  |  16KB  |  570 lines

  1. /*SCCS header -          %W%   %G%                                     */
  2. /************************************************************************ 
  3. *                                                                       * 
  4. *                      Filename:        x2x_main.c                      *      
  5. *                       Version:        0.0                             * 
  6. *                       Author :        Gary Duncan                     * 
  7. *                    24 Inkster St                   *
  8. *                    Kambah ACT 2902                 *
  9. *                    Australia                       *
  10. *                                                                       * 
  11. *-----------------------------------------------------------------------*/
  12.  
  13. #include "x2x_amiga.h"
  14. #include "x2x_data.c"
  15. extern uchar Ichar();
  16. extern char *MakeDate[] ;
  17. /*************************************************************************
  18. * Modification record 
  19. * ------------------- 
  20. * Date         By whom             Change 
  21. * ----         -------             ------ 
  22. * 12 Apr 89     GMD                AMIGA'd
  23. *------------------------------------------------------------------------ 
  24. *  
  25. *    This program will convert a given file in Down-Line Load (DLL) format 
  26. *    to another (or the same)  DLL format .  
  27. *    The DLL formats are the usual ASCII_hex formats of  
  28. *    INTEL / TEKTRONIX ( and extended) /  MOTOROLA (S1-3)  
  29. *    If no input params , the program solicits for :- 
  30. *        1) Input File name ( which it then scans to determine DLL format) 
  31. *        2) Output file DLL format 
  32. *        3) Output DLL record DATA length ( 0 < len < 256 ) 
  33. *   ( In MOTOROLA format , prompts are made for addr length , ie 2,3, 4 bytes)  
  34. *      else ( if there are params ) , it is invoked as follows :- 
  35. *      x2x -Ifilename -Otype [-Srecord_data_length] 
  36. *      type :  I=INTEL , T=TEKTRONIX ,t= TEKTRONIX (extended) 
  37. *              M1=MOTOROLA (S1) , M2=MOTOROLA (S2) M3=MOTOROLA (S3) 
  38. *     
  39. * Output file name generation 
  40. *----------------------------- 
  41. * VAX 
  42. *    The input file name then has ".xi / .xt / .xm2,3,or4 / or .xq appended 
  43. *    to form the output file name. Note that no overwrite check is done. 
  44. *    e.g  fred.xi -> fred.xi.xi -> fred.xi.xi.x(whatever) etc  
  45. * PC 
  46. *    A filename in wonderful MS_DOS is limited to the form of :- 
  47. *    <8 charas max>.< 3 charas max> thus appending ( appension ?) to 
  48. *    avoid ambiguity is not possible thus we progressively "backspace" 
  49. *    from the "." separator looking for a non-'&' chara which is then 
  50. *    transformed to '&'. 
  51. *    e.g   (INTEL to INTEL ) , abcdef.xi -> abcde&.xi -> abcd&&.xi etc  
  52.  
  53. *     
  54. *    Note that there is no restriction on cross-conversion ; ie you can 
  55. *    use this program to produce a file of the same format but of a different  
  56. *    data length. ( This could be useful because utilities such as  AZTEC  
  57. *    'hex86' program only create DLL records  with the boring length of 16)  
  58. *    Whilst running , the program displays dots before the eyes to soothe 
  59. *    those who are nervous about silent programs. 
  60. * On Completion 
  61. * ------------- 
  62. *                 ... some nice stats are presented. Note that the  
  63. *                checksum is a one_byte_sum_with_carry_wrap of the data  
  64. *                bytes ( a la MICE ) so if using the MICE you can verify  
  65. *                the Down Line Load with its memory checksum command (T). 
  66. *                ( valid only for contiguous load , of course )  
  67. ************************************************************************* 
  68. *                                                                       * 
  69. *         This program  will run on a uVAX or IBM PC                    * 
  70. *                                                                       * 
  71. *  VAX build    :   cc -o x2x x2x.c        ( produces x2x* )            * 
  72. *                                                                       * 
  73. *  IBM PC  "    :   cc -DAMIGA x2x.c                                    * 
  74. *                   ln x2x.o \lib\c.lib \lib\s.lib                      * 
  75. *                                              ( produces x2x.exe )     * 
  76. *                                                                       * 
  77. *                                                                       * 
  78. ************************************************************************* 
  79.  
  80. ############################################################################# 
  81. #  Examples of ACSII-hex formats for :- 
  82. #    INTEL 
  83. #    MOTOROLA 
  84. #    TEKTRONIX ( inc extended format ) 
  85. #  Note: the INTEL example (data length 16dec bytes) is the reference. 
  86. #      : in following "byte" =  binary value of 2 ASCII-hex charas 
  87. #                               hi nibble = 1st byte  
  88. ############################################################################# 
  89.  
  90. # Format :  INTEL 
  91.  
  92. :LLAAAATTdd..ddCC 
  93.  
  94. LL   = # of data bytes  
  95. AAAA = 16 bit address 
  96. TT   = type  
  97.         0 = data 
  98.         1 = end record 
  99.         2 = Upper Segment Base Address (USBA) 
  100.         3 = start address record ( data length = 4 bytes) 
  101.  
  102. CC   = checksum ( = -ve sum of record : ie sum of all byte-pairs = 0 ) 
  103. dd = ASCII-hex charas 
  104.  
  105. USBA format = :02000002ssssCC 
  106. ( following data records will be have (16 * ssss) added to their load addr) 
  107.  
  108.  
  109. ---------------------------------------------------------------------------- 
  110.  
  111. :020000020500??                              # type 2 record , base = 500H 
  112. :1012340090FAFCE96B002020202020202020202090  # type 0 record (data) 
  113.                                              #      (load addr = 1234H) 
  114. :00000001FF                                  # type 1 record (end) 
  115.  
  116. # above converted to :- 
  117.  
  118. :1062340090FAFCE96B002020202020202020202040    <<EXAMPLE 
  119. :00000001FF 
  120.  
  121. #----------------------------------------------------------------------------- 
  122. #  MOTOROLA - all use S9 as end record 
  123. # Format :  Motorola ( S1 , 16 bit address ) 
  124.     |<-------------- LL ---------------->| 
  125. S1LLAAAAdd..ddCC                             << Format 
  126.  
  127. LL = 2 + (# of data bytes) + 1    
  128. AAAA = address 
  129. CC = ~( LL + (AA .. + AA) + ( data bytes ))  : Note 1's complement! 
  130.  
  131.  
  132. S1LLAAAAdd..ddCC                              << Format 
  133. S113623490FAFCE96B00202020202020202020203C    <<EXAMPLE 
  134. S9030000FC 
  135.  
  136. #----------------------------------------------------------------------------- 
  137. # Format :  Motorola ( S2 , 24 bit address ) 
  138. S2LLAAAAAAdd..ddCC                              << Format 
  139. S21400623490FAFCE96B00202020202020202020203B    <<EXAMPLE 
  140. S904000000FB 
  141.  
  142. #----------------------------------------------------------------------------- 
  143. # Format :  Motorola ( S3 , 32 bit address ) 
  144. STLLAAAAAAAAdd..ddCC                              << Format 
  145. S3150000623490FAFCE96B00202020202020202020203A    <<EXAMPLE 
  146. S90500000000FA 
  147.  
  148. #----------------------------------------------------------------------------- 
  149. # Format :  Tektronix 
  150. #  Note checksum algorithm 
  151. /AAAALLRRdd..ddCC    << Format 
  152.  
  153. AAAA = load address 
  154. LL   = record length ( # of data bytes : 0 = last record ) 
  155. RR   = load checksum ( = sum of previous 6 de-ASCII'd CHARAS ) 
  156. CC   = data    "     ( sum of de-ASCII'D CHARAS ) 
  157.  
  158. /AAAALLRRdd..ddCC                              << Format 
  159. /6234101090FAFCE96B002020202020202020202079    <<EXAMPLE 
  160. /00000000 
  161.  
  162. #----------------------------------------------------------------------------- 
  163. # Format :  Tektronix (extended) 
  164. #  Note checksum algorithm 
  165. %LLTCCky......ydd..dd    << Format 
  166.  
  167. LL = length ( all charas after % ) 
  168. T  = type chara ( 6 = data , 8 = end ) 
  169. CC = checksum   ( sum of all de-ASCII'd CHARAS = 0 ) 
  170. k  = # of address charas, max 8 ( = 4 bytes ) 
  171. y...y = 'k' address charas 
  172. xx =  data as usual 
  173.  
  174.   
  175. %LLTCCky......ydd..dd    << Format 
  176.  
  177. %2E6A680000623490FAFCE96B0020202020202020202020    <<EXAMPLE 
  178. %0E81E800000000 
  179.  
  180.  
  181. *------------------------------------------------------------------------------ 
  182. * Contents 
  183. * ------- 
  184. *+ 
  185. *+              main            exec bit..           
  186. *+              getc2           gets byte from 2 ASCII hex bytes 
  187. *+              convc2          converts 2 ASCII hex bytes to a byte 
  188. *+              get_hex         converts ASCII hex chara to binary 
  189. *+              Ichar           gets chara from input file 
  190. *+  
  191. ******************************************************************************/ 
  192.  
  193.  
  194.  
  195. /*------------------------------------------------------------------------*/ 
  196.  
  197. main (argc,argv) 
  198. int argc; 
  199. char *argv[]; 
  200.  
  201. int temp ; 
  202.  
  203.  
  204.  /*----------------------- announce program / vers -------------------------*/ 
  205.  
  206.  
  207.  printf ( "\nX2X - %s : written by Gary Duncan\n" , MakeDate[0]  ) ; 
  208.  
  209.  iffp = 0 ; 
  210.  opftype = -1 ;                 /* invalidate things */ 
  211.  
  212.  if ( argc == 1 )                /* no params , solicit for them */ 
  213.    sol_params () ;          
  214.  else                            /* use command line params then */ 
  215.    xmode = com_params ( argc , argv ) ; 
  216.  
  217.  
  218.  /*------------------------   build o/p file here -------------------------*/ 
  219.  
  220.  f_reset () ; 
  221.  
  222.  xlen = 1 ;  
  223.  while ( xlen )                      /* loop to process input file  */ 
  224.    {  
  225.  #if 0
  226.      if ( func1 () )                /* PC only - exit on FUNC1   */ 
  227.        exit (1) ; 
  228.  #endif
  229.  
  230.      fill_ipbuf () ;                    /* fill input data buffer */ 
  231.      xaddr = 0 ; 
  232.      xlen = get_len ( &xaddr ) ;        /* find length of continuous chunk */ 
  233.      
  234.      switch ( opftype ) 
  235.      { 
  236.        case 0 :                      /* INTEL  */ 
  237.  
  238.          if ( ousba != ousban )  /* .. build a type 2 record maybe ? */ 
  239.            { 
  240.              ousba = ousban ; 
  241.              xdllen = dll_Irec ( 2 , (long)ousba  , 2 ) ;   /* gen record */ 
  242.  
  243.              opbuf [xdllen++] = '\n' ;     /* append RETURN  to  record */ 
  244.      
  245.              rite_rec ( offp , opbuf , xdllen ) ;   /* write it */ 
  246.              ++oprecs ; 
  247.            }             
  248.  
  249.          if (xlen)     /* end record ? */ 
  250.             { 
  251.               xtype = 0 ;                     /* no */ 
  252.             } 
  253.          else                  /* yes , maybe insert checksum record */ 
  254.             { 
  255.               xtype = 1 ;  
  256.               if ( xmode == 3 )    /* checksum mode ? */ 
  257.         { 
  258.                    gen_csum () ;   /* build and write last data rec */ 
  259.         } 
  260.             }  
  261.          
  262.          xdllen = dll_Irec ( xtype, xaddr, xlen ) ;  /* build INTEL record  */ 
  263.           
  264.          break ; 
  265.   
  266.        case 1 :                     /* MOTOROLA  */ 
  267.        case 2 : 
  268.        case 3 :   
  269.  
  270.          (xlen) ? (xtype = opftype + '0') : (xtype = '9') ; 
  271.                                                      /* data or eof rec type */ 
  272.           xdllen =  dll_Mrec ( xtype , xaddr , xlen )  ; 
  273.              break ; 
  274.  
  275.        case 4 :                       /* TEKTRONIX  */ 
  276.  
  277.           xdllen  = dll_Trec ( 0 , xaddr ,xlen ) ; 
  278.           break ; 
  279.  
  280.        case 5 :                       /* TEKTRONIX - extended   */ 
  281.           
  282.  
  283.          (xlen) ? (xtype = '6') : (xtype = '8') ; /* data or eof rec type */ 
  284.  
  285.           xdllen  = dll_Txrec ( xtype , xaddr ,xlen ) ; 
  286.           break ; 
  287.  
  288.        case 6 :                        /* QTAM  */ 
  289.            
  290.           xdllen = dll_Qrec ( 0 , xaddr , xlen ) ; 
  291.           break ; 
  292.  
  293.        }  ; 
  294.  
  295.   /*--------------now write record to disc ----------------------------------*/ 
  296.  
  297.     ++datarecs ; 
  298.     ++oprecs ; 
  299.     totchars += xlen ;                  /* update total data chara count */ 
  300.  
  301.     opbuf [xdllen++] = '\n' ;            /* append RETURN  to each record */ 
  302.      
  303.     rite_rec ( offp , opbuf , xdllen ) ;   /* write it */ 
  304.  
  305.     if ( (!(totchars & 0x3FF) )  && (!pdots)  )                        
  306.        fprintf ( stderr , "." ) ;   /* dots before the eyes.... , every 1K */ 
  307.  
  308.  
  309.    } 
  310.  
  311. /*-------------------- FIN , print a message -------------------------------*/ 
  312.  
  313.   if ( odccon )                                  /* flush write buffer */ 
  314.    {  
  315.     if ( write( offp , dlldbuf , odccon) != odccon ) 
  316.        {    
  317.         perror("Disc write error: "); 
  318.         exit(3); 
  319.        } 
  320.    } 
  321.  
  322.        printf (  "\nOutput file is :  %s\n" , ofile  ) ; 
  323.        printf ( "*** Total recs = %d, Data recs = %d \n", oprecs , datarecs ) ; 
  324.        printf ( "*** Reclen = %d, Data chars = %ldDec/%lXH \n", 
  325.                        reclen , totchars, totchars ) ; 
  326.  
  327.     /*--------- if -P/-C  option , put printable charas in checksum buffer 
  328.                 into "temp.x2x" ( bit of a kluge for documentation) ----*/ 
  329.  
  330.       if ( temp = strlen ( mallocptr ) ) 
  331.         if ( write( tffp , mallocptr , temp ) != temp ) 
  332.               {    
  333.                  fprintf (stderr,"(rite_rec) - write error" ); 
  334.                  perror("Disc write error: "); 
  335.                  exit(3); 
  336.               } 
  337.              
  338.  
  339.         
  340.     exit (0) ; 
  341.  
  342.  
  343.  
  344. /*************************************************************************** 
  345.  
  346.  
  347.   Function :      getc2 
  348.  
  349.   Purpose  : 
  350.  
  351.   Entry    : 
  352.  
  353.   Returns  :     TRUE -  
  354.  
  355.                  FALSE- 
  356.  
  357.  
  358.  
  359. ****************************************************************************/ 
  360.  
  361. int  getc2 (  )       /* returns with de-hexed byte  
  362.                  from 2 ASCII hex bytes       */ 
  363.  
  364.  
  365.  
  366.   int c , c0 , c1  ; 
  367.  
  368.   if ( (c = Ichar ()) == -1 )                  /* MS nibble   */ 
  369.     { 
  370.        fprintf ( stderr , "\Ichar fail" ) ; 
  371.        exit (3) ; 
  372.     } 
  373.   if ( (c0 = get_hex (c) ) == -1 ) 
  374.     { 
  375.        fprintf ( stderr , "\Non ASCII-hex chara in file = %c " , c ) ; 
  376.        exit (3) ; 
  377.     } 
  378.  
  379.   if ( (c = Ichar ()) == -1 )                  /* MS nibble   */ 
  380.     { 
  381.        fprintf ( stderr , "\Ichar fail" ) ; 
  382.        exit (3) ; 
  383.     } 
  384.   if ( (c1 = get_hex (c) ) == -1 ) 
  385.     { 
  386.        fprintf ( stderr , "\Non ASCII-hex chara in file" ) ; 
  387.        exit (3) ; 
  388.     } 
  389.  
  390.   c = (( c0 << 4 )  | c1 )  ;     
  391.  
  392.   return ( c & 0xFF ) ;         /* ensure return byte here only  */ 
  393.  
  394.  
  395.  
  396. /*************************************************************************** 
  397.  
  398.  
  399.   Function :      convc2 
  400.  
  401.   Purpose  :      converts byte to 2 ASCII hex charas  
  402.  
  403.   Entry    : 
  404.  
  405.   Returns  :      (hi byte/lo byte)  as int  
  406.  
  407.  
  408.  
  409.  
  410. ****************************************************************************/ 
  411.  
  412. int  convc2 ( bite  ) 
  413.  
  414. unsigned char bite ; 
  415.  
  416.  
  417.   unsigned char cc , k  ; 
  418.   unsigned int chch = 0  ; 
  419.  
  420.    cc = bite  ; 
  421.  
  422.    k = cc ; 
  423.  
  424.     cc = (k >> 4) & 0xF ;     /* MS nibble  */ 
  425.  
  426.   (cc < 0xA) ? ( cc = cc + '0') : ( cc = cc + 'A' - 10 ) ;  
  427.  
  428.   chch = (int) cc << 8  ;            /*Hi  nibble  */ 
  429.  
  430.   cc = k & 0xF ; 
  431.  
  432.   (cc < 0xA) ? ( cc = cc + '0') : ( cc = cc + 'A' - 10 ) ;  
  433.   
  434.   return ( chch | cc ) ; 
  435.  
  436.  
  437. /*************************************************************************** 
  438.  
  439.  
  440.   Function :    get_hex 
  441.  
  442.   Purpose  :    Returns with given ASCII hex chara de-ASCIIed 
  443.  
  444.   Entry    :    chara 
  445.  
  446.   Returns  :     - 1 , error , else chara ( 0 > 15 )  
  447.  
  448.  
  449.  
  450.  
  451. **************************************************************************/ 
  452.  
  453. int get_hex ( bite )  
  454.  
  455.  
  456. uchar bite ; 
  457.  
  458.    if ( isdigit (bite) ) 
  459.       return ( bite & 0xF ) ;                  /* number */ 
  460.  
  461.   bite |= 0x20 ; 
  462.  
  463.   if ( islower (bite) && ( bite < 'g')  ) 
  464.      return ( (bite & 0xF) + 9 )   ;           /* A _ F */ 
  465.  
  466.   return ( -1 )  ;                             /* error */ 
  467.  
  468.  
  469. /*************************************************************************** 
  470.  
  471.  
  472.   Function :    Ichar 
  473.  
  474.   Purpose  :    Returns with chara from input file 
  475.  
  476.   Entry    :    chara 
  477.  
  478.   Returns  :     - 1 , error , else chara  
  479.  
  480.  
  481.  
  482.  
  483. **************************************************************************/ 
  484.  
  485.  
  486. uchar Ichar () 
  487.  
  488.  int  ch ; 
  489.  
  490.    if ( boffs == -1 ) 
  491.        return ( -1 ) ;            /* File empty */ 
  492.  
  493.    if ( !disclen ) 
  494.      { 
  495.        disclen =   read (iffp , dbuf , 1024 ) ; /* read a block of file */ 
  496.        boffs = 0 ; 
  497.      } 
  498.  
  499.    if ( !disclen ) 
  500.       return ( -1 ) ; 
  501.     
  502.    ch =  dbuf[ boffs ] &0xFF  ; 
  503.  
  504.    xchek += ch ;                  /* accum a checksum for ext use */ 
  505.  
  506.    if (  ++boffs != disclen ) 
  507.        return ( ch ) ; 
  508.    else if ( boffs == 1024 ) 
  509.        disclen  = 0 ;                 /* flag buffer empty */ 
  510.    else  
  511.        boffs = -1 ;                   /* flag file empty   */ 
  512.  
  513.    return ( ch ) ; 
  514.    
  515.