/*SCCS header - %W% %G% */ /************************************************************************ * * * Filename: x2x_3.c * * Version: 0.0 * * Author : Gary Duncan * * 24 Inkster St * * Kambah ACT 2902 * * Australia * * * *-----------------------------------------------------------------------* * * Modification record * ------------------- * * Date By whom Change * ---- ------- ------ * * 12 Apr 89 GMD AMIGA'd * *------------------------------------------------------------------------ * *------------------------------------------------------------------------------ * Contents * ------- *+ *+ dos_fname gens output file name if under DOS *+ func1 exitsif Func 1 key hit ( DOS only ) *+ get_rstart looks for DLL record start *+ sol_params solicits for input params *+ com_params processes command line parameters *+ open_ifile opens input file *+ open_ofile opens output file *+ gen_csum builds and writes checksum record *+ date reformats SCCS vers / date *+ usage error message - *+ * ******************************************************************************/ #include "x2x_amiga.h" #include "x2x_data.c" /*************************************************************************** Function : dos_fname Purpose : cater for limited file name length etc in MS_DOS ( PC application ) Entry : Returns : TRUE - FALSE- ***************************************************************************/ int dos_fname () { #ifdef AMIGA int j = 0 ; int k = 0 ; uchar ch ; while ( ch = ofile[j]) { if ( ch == '.' ) break ; ++j ; } ofile [j] = '\0' ; strcat ( ofile , sfx[opftype] ) ; /* append suffix */ if ( strcmp ( ofile , ifile ) ) /* ensure difference */ return ; /* some , exit */ /*-- in file name ...XYZ.EXT , start replacing from X <- with & until * uniqueness , or exhaustion */ while ( --j ) { ofile [j] = '&' ; /* god , this is tedious.... */ if ( strcmp ( ofile , ifile ) ) /* ensure difference */ return ; /* some , exit */ } fprintf ( stderr , "Too many &s in input file name !\n" ) ; exit( 1 ) ; #endif } #if 0 /*************************************************************************** Function : func1 Purpose : looks for Func1 from keyboard Entry : Returns : TRUE - found it FALSE- ****************************************************************************/ int func1 () { #ifdef AMIGA uchar ch ; if ( scr_poll () != -1 ) { ch = scr_getc () ; if ( ch == (0x3B | 0x80 ) ) return ( TRUE ) ; /* found it */ } #endif return (FALSE ) ; } #endif /*************************************************************************** Function : get_rstart Purpose : search for DLL record start given header char Entry : header chara ( : / % S Q ) Returns : if found , exits from program otherwise ***************************************************************************/ int get_rstart ( ich ) uchar ich ; { int j = 0 ; int cch = 0 ; while ( ich != cch ) /* search for record start */ { if ( ( cch=Ichar() ) == -1 ) /* get chara from input file */ { fprintf ( stderr , "Unexpected EOF on input file" ) ; exit (1) ; } if ( j++ > 100 ) /* nominal length of search */ { fprintf ( stderr , "Can't find a record header chara ( %c ) in 100 chara search!\n" , ich ) ; exit (1) ; } } } /*************************************************************************** Function : sol_params Purpose : solicits user for parameters Entry : Returns : ***************************************************************************/ int sol_params () { int kk ; /*------------------ get input DLL file ---------------------------*/ printf("Input file name ? " ); gets ( ifile ) ; open_ifile ( ifile ) ; /* open file - determine type */ /*------------------ get output DLL file type ---------------------------*/ kk = 0 ; while ( !kk ) { printf ( "\nOutput file type ( I, M1, M2, M3, T, Tx ) ? " ) ; gets ( kbuf ) ; switch ( kk = kbuf[0] ) /* announce input file type */ { case 'i' : /* INTEL */ case 'I' : /* INTEL */ opftype = 0 ; break ; case 'm' : /* MOTOROLAs */ case 'M' : /* MOTOROLAs */ opftype = 0 ; switch ( kbuf[1] - '0' ) { case 3 : ++opftype ; case 2 : ++opftype ; case 1 : ++opftype ; xoMaddr = opftype +1 ; /* addr len */ break ; default : kk = 0 ; /* force error */ } break ; case 't' : case 'T' : /* TEKTRONIX */ ( kbuf[1] == 'x' ) ? (opftype = 5) : (opftype = 4 ) ; break ; default : kk = 0 ; /* error - loop */ } } /*----------------- create o/p file -------------------------*/ open_ofile ( ifile ) ; /*------------ now solicit record data length --------------------------*/ while (1) { reclen = 0 ; printf ( "\nRecord data length ( Max = 255 , default = 16 bytes) ? " ) ; gets ( opbuf ) ; if ( !strlen (opbuf) ) /* RET means default */ { reclen = 16 ; break ; } kk = sscanf ( opbuf , "%d" , &reclen ) ; if ( (reclen > 0) && (reclen < 256 ) ) break ; } /*----- adjust reclen if MOTOROLA and overflow ---------------------------*/ if ( (xoMaddr + reclen) > 255 ) /* 1 byte length only ! */ { reclen = 255 - xoMaddr ; /* adjust */ fprintf ( stderr , "Rec length overflow , data length adjusted to %d \n" , reclen ) ; } } /*************************************************************************** Function : open_ifile Purpose : opens input file , announces type Entry : Returns : file ptr ***************************************************************************/ int open_ifile ( ptr ) char *ptr ; { if(( iffp = open( ptr , O_RDONLY)) < 0) /* source file */ { fprintf(stderr,"Error: unable to open '%s'\n", ifile); exit(1); } /*---------------- validate file type -------------------------------*/ ipftype = get_rtype ( ) ; /* get DLL file type */ switch ( ipftype ) /* announce input file type */ { case 0 : /* INTEL */ case 1 : /* MOTOROLAs */ case 2 : case 3 : case 4 : /* TEKTRONIX */ case 5 : /* TEKTRONIX - extended */ break ; default : fprintf ( stderr , "Unknown input file type\n" ); exit (1) ; } printf ( "\nInput file type is : %s" , iipftype[ ipftype ] ) ; } /*************************************************************************** Function : com_params Purpose : scans command line for invocation parameters - does things with them Entry : Returns : mode type ( 2 or 3 ) ***************************************************************************/ int com_params ( count , ptr ) int count ; char **ptr ; { char *argptr ; char *iptr ; int ch ; int mode = 2 ; while ( --count ) /* scan the input params , if any */ { argptr = *++ptr ; if ( *argptr++ == '-' ) { switch ( *argptr++ ) /* look for the param */ { case 'I' : case 'i' : /* Input file name */ open_ifile ( iptr = argptr ) ; /* open it */ break ; case 'D' : /* dots ?? */ case 'd' : pdots = 1; /* no */ break ; case 'O' : case 'o' : /* Output file type */ switch ( *argptr++ ) { case 'i' : case 'I' : /* INTEL */ opftype = 0 ; break ; case 'm' : case 'M' : /* MOTOROLA */ ch = *argptr - '0' ; opftype = 0 ; switch (ch) { case 3 : ++opftype ; case 2 : ++opftype ; case 1 : ++opftype ; xoMaddr = opftype + 1; break ; default : usage () ; exit (1) ; } break ; case 'T' : /* TEKTRONIX */ opftype = 4 ; break ; case 't' : /* TEKTRONIX - extended */ opftype = 5 ; break ; } break ; case 'S' : case 's' : /* record length */ reclen = atoi ( argptr ) ; if ( !reclen || (reclen > 255) ) { usage () ; exit (1) ; } break ; case 'C' : /* Checksum generation */ case 'c' : opftype = 0 ; /* set o/p file type = INTEL */ if ( xmode == 3 ) /* ensure INTEL file if mode 3 ( checksum gen ) */ { if ( ipftype != 0 ) { fprintf ( stderr , "File must be INTEL format!\n" ) ; exit (1) ; } } if ( !(mallocptr = malloc ( (long)(64*1024) )) ) /* get a K64 byte array */ { fprintf ( stderr , "Malloc fail!\n" ) ; exit (1) ; } for ( aa=0 ; aa < 64*1024L ; ++aa ) /* init with FFs */ { *(mallocptr+aa) = 0xFF ; } mode = 3 ; /* set mode type */ break ; case 'R' : /* checksum mode - optional ROM size */ case 'r' : romsize = atoi ( argptr ) ; switch ( romsize ) /* yes , validate ROM size */ { case 2 : case 4 : case 8 : case 16 : case 32: case 64: break ; /* valid sizes s*/ default : fprintf ( stderr , "Invalid ROM size !\n" ) ; exit (1) ; } break ; case 'P' : case 'p' : /* checksum mode - dump printable charas to "temp.x2x" ; used for getting EMU screen dumps in manual preparation */ xpflag = TRUE ; if(( tffp= open( "temp.x2x" , O_RDWR | O_CREAT | O_TRUNC , 0666)) < 0 ) { fprintf(stderr,"Error: unable to open temp.x2x\n" ); exit(1); } break ; default : /* Invalid para */ { usage () ; exit (1) ; } } } else /* no "-" sign , error */ { usage (); exit (1) ; } } /*-------- verify params ---------------------*/ if ( (!iffp) || (opftype == -1 ) ) /* ensure enough params */ { usage () ; exit (1) ; } open_ofile ( iptr ) ; /* open output file */ if ( mode == 3 ) /* checksum mode ? */ { return ( mode ) ; } /*----- adjust reclen if MOTOROLA and overflow ---------------------------*/ if ( (xoMaddr + reclen) > 255 ) /* 1 byte length only ! */ reclen = 255 - xoMaddr ; /* adjust */ return ( mode ) ; } /*************************************************************************** Function : open_ofile Purpose : gens o/p file name and opens same Entry : Returns : ***************************************************************************/ int open_ofile ( iptr ) char *iptr ; { strcpy ( ofile , iptr ) ; /* create a o/p file */ /*---------------- muck around if using stone-age MS_DOS on PC ------*/ #ifdef AMIGA dos_fname () ; /* MS_DOS :chara file-names, only one '.' allowed , yuk ..*/ #else strcat ( ofile , sfx[opftype] ) ; /* append suffix */ #endif if(( offp= open( ofile , O_RDWR | O_CREAT | O_TRUNC , 0666)) < 0 ) { fprintf(stderr,"Error: unable to open '%s'\n" , ofile ); exit(1); } printf ( "\nOutput file is : %s ( %s )\n" , ofile ,iipftype[opftype] ) ; } /*************************************************************************** Function : gen_csum Purpose : builds and writes checksum record to disc Entry : Returns : ****************************************************************************/ int gen_csum () { int j , k ; int addr = (long)romsize*1024 -2 ; /*------------ now calc ROM checksum ----------------------------*/ for ( j=0 , csum=0 ; j < addr ; j +=2 ) { csum += *(uchar *)(mallocptr + j) ; csum += ((int)*(uchar *)(mallocptr + j + 1)) << 8 ; } /* ----------- now calc record checksum -----------------------*/ k = 2 + (addr&0xFF) + (addr>>8) + (csum&0xFF) + (csum>>8) ; k = -k ; /*------------- now build record ------------------------------*/ opbuf[0] = ':' ; opbuf[1] = '0' ; opbuf[2] = '2' ; /* length */ j = convc2 ( addr >> 8 ) ; /* load addr - hi */ opbuf [IRADDR] = j >> 8 ; opbuf [IRADDR+1] = j & 0xFF ; j = convc2 ( addr ) ; /* load addr - lo */ opbuf [IRADDR+2] = j >> 8 ; opbuf [IRADDR+3] = j & 0xFF ; j = convc2 ( csum ) ; /* ROM checksum - lo */ opbuf [IRDATA] = j >> 8 ; opbuf [IRDATA+1] = j & 0xFF ; j = convc2 ( csum >> 8 ) ; /* ROM checksum - hi */ opbuf [IRDATA+2] = j >> 8 ; opbuf [IRDATA+3] = j & 0xFF ; j = convc2 ( k ) ; /* record checksum */ opbuf [IRDATA+4] = j >> 8 ; opbuf [IRDATA+5] = j & 0xFF ; opbuf [xdllen=IRDATA+6] = '\n' ; /* append RETURN to record */ /*--------------now write record to disc ----------------------------------*/ ++datarecs ; ++oprecs ; totchars += 2 ; /* update total data chara count */ rite_rec ( offp , opbuf , ++xdllen ) ; /* write it */ } /*************************************************************************** Function : date Purpose : plants SCCS Vers #/build date in banner Entry : ptr to start of vers/date in banner Exit conditions: ptr to rehacked string ****************************************************************************/ char *date ( optr ) char *optr ; /* ptr to date line */ { static char month[] = "JanFebMarAprMayJunJulAugSepOctNovDec" ; /* 0123456789012345678901234 */ static char copy[] = "[ V x.x - dd mmm yy ]" ; /* build, copy out*/ int j , k ; char ch ; char *iptr ; /*---------------------------------------------------------------------------*/ iptr = &sccs_id[0] ; while ( *iptr++ == ' ' ) ; /* look for start of SCCS vers. # */ --iptr ; /*----------- copy Vers # to build buffer---------------------------*/ j = 4 ; /* start of Vers in build buffer */ while ( (ch = *iptr++) != ' ' ) copy[j++] = ch ; /*---------------- get Months, convert and put in buffer-------------*/ while ( (ch = *iptr++) == ' ' ) ; /* look for start of months */ --iptr ; j = 0 ; while ( (ch = *iptr++) != '/' ) /* 1 or 2 charas */ { j = 10*j + (ch - '0') ; /* yes */ } j = 3 * (j-1) ; /* index to start of "mmm" charas */ for ( k=0 ; k < 3 ; ++k , ++j ) copy [17+k] = month[j] ; /* copy 3 charas to buffer */ /*---------------- get days, and put in buffer-----------------------*/ copy[15] = *iptr++ ; /* days - 1 */ if ( (ch = *iptr++) != '/' ) { copy[14] = copy[15] ; /* shuffle up */ copy[15] = ch ; /* days 2 - if there */ } ++iptr; /*---------------- get years, and put in buffer-----------------------*/ copy[21] = *iptr++ ; copy[22] = *iptr++ ; return ( copy ) ; /* return with ptr to string */ } /*************************************************************************** Function : usage Purpose : prints calling params for "emu" Entry : Returns : ****************************************************************************/ int usage () { static char *rats[] = { "\n", "Usage 1 & 2 :\n", "-----------\n", " Converts a given ASCII-hex file in Down-Line Load (DLL) format to another\n", " or the same DLL format . \n", " ( Note that record checksums are not verified in the source file - this\n", " means that a record can be altered and the file regenerated without the\n", " tedium of having to recalculate the checksum ).\n", "\n", "usage <1> : x2x ( parameters are solicited )", "\n", "usage <2> : x2x -Ifilename -Otype [-Sxxx] \n", "\n", " (O)utput file types : \n" , " I = Intel\n", " M1 = Motorola S1\n", " M2 = Motorola S2\n", " M3 = Motorola S3\n", " T = Tektronix\n", " t = Tektronix-extended\n", " xxx = record data length ( 1-255 , def=16 )\n" , "\n", "" } ; int j = 0 ; char *ptr ; while ( *(ptr = rats[j++]) ) printf ( "%s", ptr ) ; }