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_2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-16
|
22KB
|
906 lines
/*SCCS header - %W% %G% */
/************************************************************************
* *
* File : x2x_2.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
* 01 Jul 89 " Changed K64 to K64K
*
*------------------------------------------------------------------------
*
*------------------------------------------------------------------------------
* Contents
* -------
*+
*+ rite_rec writes DLL record to disc
*+ get_rtype validates input file as INTEL/MOTOROLA/TEK..
*+ f_reset resets file pointer to start
*+ dll_Irec builds an INTEL record
*+ dll_Mrec builds a MOTOROLA record
*+ dll_Trec builds a TEKTRONIX record
*+ dll_Txrec builds a TEKTRONIX-extended record
*+ dll_Qrec builds a QTAM record
*+ sum_get gets a checksum on a string
*+ xgetc gets a DLL byte
*+ xputc puts a DLL addr/byte pair in buffer
*+ fill_ipbuf replenish i/p buffer
*+ get_len determine # of contiguous bytes in record
*+
*
******************************************************************************/
#include "x2x_amiga.h"
#include "x2x_data.c"
/***************************************************************************
Function : rite_rec
Purpose : Puts DLL record into buffer and writes to disc when
full , or when forced
Entry :
Returns :
****************************************************************************/
int rite_rec ( fptr , fmadr , len )
int fptr ;
char *fmadr ;
int len ;
{
while ( len-- )
{
dlldbuf [odccon++] = *fmadr++ ; /* copy to buffer */
if ( odccon == OPBUFLEN ) /* if full write */
{
if ( write( fptr , dlldbuf , OPBUFLEN) != OPBUFLEN )
{
fprintf (stderr,"(rite_rec) - write error" );
perror("Disc write error: ");
exit(3);
}
odccon = 0 ;
}
}
}
/***************************************************************************
Function : get_rtype
Purpose : Determines type of DLL file
Entry :
Returns : with file type
****************************************************************************/
int get_rtype ( )
{
int ch ;
int retval = 1 ;
ch = Ichar () ; /* 1st chara assumed to define file type !*/
switch ( ch )
{
case ':' : /* INTEL */
break ;
case 'S' : /* MOTOROLA */
ch = Ichar() -'0' ; /* get type 1,2,3 */
switch (ch)
{
case 3 : ++retval ;
case 2 : ++retval ;
case 1 : ++retval ;
xiMaddr = retval + 1 ;
break ;
default :
retval = 0 ;
}
break ;
case '/' : /* TEKTRONIX */
retval = 5 ;
break ;
case '%' : /* TEKTRONIX - extended */
retval = 6 ;
break ;
case 'Q' : /* QTAM */
retval = 7 ;
break ;
default :
retval = 0 ;
break ; /* ????????? */
}
f_reset () ; /* reset file ptrs */
return ( retval -1 ) ;
}
/***************************************************************************
Function : f_reset
Purpose : resets pointers to DLL file- ensures read starts at
beginning
Entry :
Returns : TRUE -
FALSE-
****************************************************************************/
int f_reset ()
{
boffs = 0 ;
disclen = 0 ;
if ( lseek ( iffp , 0L , L_SET ) == -1 ) /* reset file ptr */
{
fprintf (stderr, "lseek fail\n" ) ;
exit(1) ;
}
}
/***************************************************************************
Function : dll_Irec
Purpose : builds an INTEL DLL record
Entry :
Returns : # of charas in record
****************************************************************************/
int dll_Irec ( tipe , addr , len )
int tipe , len ;
long addr ;
{
int count , j ;
uchar ch ;
int t2data ;
t2data = addr << 12 ; /* convert to seg offset */
if ( tipe == 2 )
addr = 0 ;
/*----------- calc checksum --------------------------------*/
Icsum = 0 ;
Icsum += sum_get ( 'I' , &addr , 2 ) ; /* addr */
Icsum += sum_get ( 'I' , &tipe , 1 ) ; /* type */
Icsum += sum_get ( 'I' , &len , 1 ) ; /* len */
/* -----------now build buffer ------------------------*/
opbuf [0] = ':' ;
chcon = convc2 ( len ) ;
opbuf [IRLEN] = chcon >> 8 ;
opbuf [IRLEN+1] = chcon & 0xFF ;
chcon = convc2 ( tipe ) ; /* rec type - data= 0 */
opbuf [IRTYPE] = chcon >> 8 ;
opbuf [IRTYPE+1] = chcon & 0xFF ;
chcon = convc2 ( (int)(addr >> 8) ) ; /* load addr - hi */
opbuf [IRADDR] = chcon >> 8 ;
opbuf [IRADDR+1] = chcon & 0xFF ;
chcon = convc2 ( (int)addr ) ; /* load addr - lo */
opbuf [IRADDR+2] = chcon >> 8 ;
opbuf [IRADDR+3] = chcon & 0xFF ;
for ( count = 0 , j = 0; count < len ; ++ count, j += 2 ) /* now the
data */
{
if ( tipe == 2 ) /* fudge for USBA record */
{
ch = t2data >> 8 ;
t2data <<= 8 ;
}
else
ch = xgetc ( ) ; /* get data chara */
Icsum += sum_get ( 'I' , &ch , 1 ) ; /* accum c/sum */
chcon = convc2 ( ch ) ;
opbuf [IRDATA + j ] = chcon >> 8 ;
opbuf [IRDATA+1 + j ] = chcon & 0xFF ;
}
Icsum = - Icsum ;
chcon = convc2 ( Icsum ) ; /* checksum */
opbuf [IRDATA + j ] = chcon >> 8 ;
opbuf [IRDATA + 1 +j ] = chcon & 0xFF ;
return ( IRDATA + 2 + j ) ; /* return length */
}
/***************************************************************************
Function : dll_Mrec
Purpose : builds a MOTOROLA 68000 DLL record
Entry :
Returns : TRUE -
FALSE-
****************************************************************************/
int dll_Mrec ( tipe , addr , len )
int tipe , len ;
long addr ;
{
int count , j ;
uchar ch ;
static int size ;
int offs ;
/*------------- abort if S1 and addr > K64K ----------------------------*/
if ( (xoMaddr == 2) && ( (addr+len) > K64K ) )
{
fprintf ( stderr ,
"\007\nAbort: address overflow! ( %ld )\n" ,addr+len );
exit (1) ;
}
offs = 2 * ( xoMaddr - 2) ; /* addr offset start */
size = len + 1 + offs/2 + 2 ;
/*----------- calc checksum --------------------------------*/
Icsum = 0 ;
Icsum += sum_get ( 'I' , &addr , 4 ) ; /* addr */
Icsum += sum_get ( 'I' , &size , 1 ) ; /* len */
/* -----------now build buffer ------------------------*/
opbuf [0] = 'S' ;
opbuf [1] = tipe ;
chcon = convc2 ( size ) ;
opbuf [MRLEN] = chcon >> 8 ;
opbuf [MRLEN+1] = chcon & 0xFF ;
/*----------------- now the variable address length ------------------*/
for ( count=0 , j = 2*xoMaddr-2 ; count < (xoMaddr) ; ++count , j -= 2 )
{
ch = addr ;
addr >>= 8 ;
chcon = convc2 ( ch ) ; /* byte -> 2 ASCII hex */
opbuf [MRADDR+ j + 0] = chcon >> 8 ;
opbuf [MRADDR+ j + 1] = chcon & 0xFF ;
}
/*---------------------- now the data ----------------------------------*/
for ( count = 0 , j = 0; count < len ; ++ count, j += 2 )
/* now the data */
{
ch = xgetc ( ) ;
Icsum += sum_get ( 'I' , &ch , 1 ) ; /* accum c/sum */
chcon = convc2 ( ch ) ;
opbuf [MRDATA + offs + j ] = chcon >> 8 ;
opbuf [MRDATA+1 + offs +j ] = chcon & 0xFF ;
}
Icsum = ~Icsum ; /* 1s complement */
chcon = convc2 ( Icsum ) ; /* checksum */
opbuf [MRDATA + offs + j ] = chcon >> 8 ;
opbuf [MRDATA + offs + 1 +j ] = chcon & 0xFF ;
return ( MRDATA + offs + 2 + j ) ; /* return length */
}
/***************************************************************************
Function : dll_Trec
Purpose : builds a TEKTRONIX DLL record
Entry :
Returns : TRUE -
FALSE-
****************************************************************************/
int dll_Trec ( tipe , addr , len )
int tipe , len ;
long addr ;
{
int count , j ;
uchar ch ;
/*------------- abort if addr > K64K ----------------------------*/
if ( (addr+len) > K64K )
{
fprintf ( stderr ,
"\007\nAbort: address overflow! ( %ld )\n" ,addr+len );
exit (1) ;
}
/*----------- calc load checksum --------------------------------*/
Tcsum = 0 ;
Tcsum += sum_get ( 'T' , &addr , 2 ) ; /* addr */
Tcsum += sum_get ( 'T' , &len , 1 ) ; /* len */
chcon = convc2 ( Tcsum ) ; /* put checksum in record */
opbuf [ TRSUM ] = chcon >> 8 ;
opbuf [ TRSUM + 1 ] = chcon & 0xFF ;
/* -----------now build buffer ------------------------*/
opbuf [0] = '/' ;
chcon = convc2 ( len ) ;
opbuf [TRLEN] = chcon >> 8 ;
opbuf [TRLEN+1] = chcon & 0xFF ;
chcon = convc2 ( (int)(addr >> 8) ) ; /* load addr - hi */
opbuf [TRADDR] = chcon >> 8 ;
opbuf [TRADDR+1] = chcon & 0xFF ;
chcon = convc2 ( (int) addr ) ; /* load addr - lo */
opbuf [TRADDR+2] = chcon >> 8 ;
opbuf [TRADDR+3] = chcon & 0xFF ;
/* -----------now build buffer ------------------------*/
Tcsum = 0 ;
for ( count = 0 , j = 0; count < len ; ++ count, j += 2 )
/* now the data */
{
ch = xgetc ( ) ;
Tcsum += sum_get ( 'T' , &ch , 1 ) ; /* accum c/sum */
chcon = convc2 ( ch ) ;
opbuf [TRDATA + j ] = chcon >> 8 ;
opbuf [TRDATA+1 + j ] = chcon & 0xFF ;
}
if ( len ) /* last record , skip (small fudge)*/
{
chcon = convc2 ( Tcsum ) ; /* checksum */
opbuf [TRDATA + j ] = chcon >> 8 ;
opbuf [TRDATA + 1 +j ] = chcon & 0xFF ;
}
else
j -= 2 ;
return ( TRDATA + 2 + j ) ; /* return length */
}
/***************************************************************************
Function : dll_Txrec
Purpose : builds a TEKTRONIX - extended DLL record
Entry :
Returns : TRUE -
FALSE-
****************************************************************************/
int dll_Txrec ( tipe , addr , len )
int tipe , len ;
long addr ;
{
int count , j , k;
uchar ch ;
int nochars = 2*len +14 ; /* chara count in record */
opbuf [0] = '%' ; /* record header chara */
opbuf [ nochars + 2 ] = 0 ;
/*----------- record length (#of charas) -------------------------------*/
/* ( make addr field max of 8 charas ( 32 bit address ) */
chcon = convc2 ( nochars ) ; /* put checksum in record */
opbuf [ TRXLEN + 0 ] = chcon >> 8 ;
opbuf [ TRXLEN + 1 ] = chcon & 0xFF ;
/*-------------- now the record type ------------------------------------*/
opbuf [ TRXTYPE ] = tipe ;
/*--------------- now a fake csum ---------------------------------------*/
opbuf [ TRXSUM ] = '0' ;
opbuf [ TRXSUM +1 ] = '0' ;
/*-------------- now the addr length ( 8 for now ) ----------------------*/
opbuf [ TRXADDR ] = '8' ; /* # of charas */
count = addr >> 24 ; /* top 8 bits */
chcon = convc2 ( count ) ;
opbuf [TRXADDR + 1 ] = chcon >> 8 ;
opbuf [TRXADDR + 2 ] = chcon & 0xFF ;
count = addr >> 16 ; /* next 8 bits */
chcon = convc2 ( count ) ;
opbuf [TRXADDR + 3 ] = chcon >> 8 ;
opbuf [TRXADDR + 4 ] = chcon & 0xFF ;
count = addr >> 8 ; /* next 8 bits */
chcon = convc2 ( count ) ;
opbuf [TRXADDR + 5 ] = chcon >> 8 ;
opbuf [TRXADDR + 6 ] = chcon & 0xFF ;
count = addr ; /* low 8 bits */
chcon = convc2 ( count ) ;
opbuf [TRXADDR + 7 ] = chcon >> 8 ;
opbuf [TRXADDR + 8 ] = chcon & 0xFF ;
/*-------------- now put data in buffer -----------------------------*/
for ( count = 0 , j = 0; count < len ; ++ count, j += 2 )
/* now the data */
{
ch = xgetc ( ) ;
chcon = convc2 ( ch ) ;
opbuf [TRXDATA + j ] = chcon >> 8 ;
opbuf [TRXDATA+1 + j ] = chcon & 0xFF ;
}
/*----------------- now build and store checksum -----------------------*/
for ( count = 0 , k = 0 ; count < nochars ; ++count )
{
if ( (j = get_hex (opbuf [count + 1])) == -1)
{
fprintf ( stderr , "dll_TXrec bad hex chara\n" ) ;
fprintf ( stderr , opbuf ) ;
exit ( 1 ) ;
}
k += j ; /* accum checksum */
}
chcon = convc2 ( k ) ; /* put in buffer */
opbuf [TRXSUM ] = chcon >> 8 ;
opbuf [TRXSUM + 1 ] = chcon & 0xFF ;
return ( nochars + 1 ) ; /* return length */
}
/***************************************************************************
Function : dll_Qrec
Purpose : gen a QTAM record
Entry :
Returns : TRUE -
FALSE-
****************************************************************************/
int dll_Qrec ( tipe , addr , len )
int tipe , len ;
long addr ;
{
int count , j ;
uchar ch ;
/* -----------now build buffer ------------------------*/
opbuf [0] = 'Q' ;
opbuf [1] = len ;
opbuf [2] = addr >> 16 ;
opbuf [3] = addr >> 8 ;
opbuf [4] = addr ;
for ( count = 0 ; count < len ; ++ count) /* put data in buffer */
{
ch = xgetc ( ) ;
opbuf [ 5 + count ] = ch ;
}
for ( count = 0 , j = 0 ; count < (len + 4) ; ++ count ) /* calc c/sum */
j += opbuf [ 1 + count] ;
opbuf [ 1 + count ] = - j ; /* put c/sum in buffer */
return ( len + 6 ) ; /* return length */
}
/***************************************************************************
Function : sum_get
Purpose : Accumulates a checksum on a string
Entry : "I" / "T"
ptr to char string
length
Returns : uchar : checksum
****************************************************************************/
int sum_get ( type , ptr , len )
char *ptr ;
int type , len ;
{
int csum ;
int count ;
switch ( type )
{
case 'I' :
for ( count = 0 , csum = 0 ; count < len ; ++count , ++ptr )
csum += *ptr & 0xFF ;
break ;
case 'T' :
for ( count = 0 , csum = 0 ; count < len ; ++count , ++ptr)
csum += (*ptr & 0xF) + ((*ptr >> 4) & 0xF ) ;
break ;
}
return ( csum & 0xFF ) ;
}
/***************************************************************************
Function : xgetc
Purpose : gets next chara from input buffer
Entry :
Returns : chara , or -1 ( empty )
*ptr = addr
***************************************************************************/
int xgetc ( )
{
int ch , temp ;
char *ptr = mallocptr ;
if ( !xccnt )
return -1 ; /* empty */
ch = xipbuf [xnrp].bite ; /* get chara */
/* if mode 3 ( checksum gen ) , put byte in array */
if ( xmode == 3 )
{
if ( (temp = xipbuf[xnrp].addr) > 0xFFFF )
{
fprintf ( stderr , "(xgetc) : addr > K64K !\n" ) ;
exit (1) ;
}
ptr += temp ;
*ptr = ch ; /* plant byte in array */
}
--xccnt ;
if ( ++xnrp == IPLEN )
xnrp = 0 ;
return ( ch & 0xFF ) ;
}
/***************************************************************************
Function : xputc
Purpose : loads an addr/ data chara pair from DLL record to xipbuf
Entry :
Returns : TRUE - buffer not full
FALSE- buffer full
***************************************************************************/
int xputc ( addr , bite )
long addr ;
uchar bite ;
{
if ( csum > 255 )
csum = (++csum) & 0xFF ; /* wrap prev carry */
csum += bite ; /* accum checksum */
xipbuf [xnwp].addr = addr ;
xipbuf [xnwp++].bite = bite ;
if ( xnwp == IPLEN )
xnwp = 0 ;
if ( ++xccnt == IPLEN ) /* full check */
return ( FALSE ) ;
else
return ( TRUE ) ;
}
/***************************************************************************
Function : fill_ipbuf
Purpose : fills up xipbuf with addr/data pairs made from DLL
file records
Entry :
Returns : TRUE - ip file not empty
FALSE- ip fill now empty
***************************************************************************/
int fill_ipbuf ()
{
while ( (xccnt < (IPLEN-300)) && xeof )
/* read DLL records until EOF or enough for o/p */
{
switch ( ipftype )
{
case 0 :
xeof = get_Irec () ; /* get INTEL record -- deASCIIed */
break ;
case 1 : /* MOTOROLA */
case 2 :
case 3 :
xeof = get_Mrec() ;
break ;
case 4 : /* TEKTRONIX */
xeof = get_Trec () ;
break ;
case 5 : /* TEKTRONIX - extended */
xeof = get_trec () ;
break ;
case 6 : /* QTAM */
xeof = get_Qrec () ;
break ;
} ;
}
}
/***************************************************************************
Function : get_len
Purpose : scans i/p data buffer to see how many contiguous
bytes there are ( up to reclen )
- does not allow overflow past K64K boundary if dest.
file is INTEL ( to allow type 2 tec gen. )
Entry :
Returns : # of bytes
*ptr = addr field of start byte
***************************************************************************/
int get_len ( aptr )
long *aptr ;
{
int count = 0 ;
long addr ;
int ptr ;
ptr = xnrp ; /* scan from read ptr */
addr = xipbuf [ptr].addr ;
*aptr = addr ; /* hold start addr for external use */
ousban= addr >> 16 ; /* for INTEL , hold K64 seg # */
if ( !xccnt ) /* check odd conditions */
{
*aptr = 0 ;
return ( xccnt ) ;
}
else if ( xccnt == 1 )
return ( xccnt ) ;
while ( count++ != xccnt ) /* read up to what's in buffer */
{
if ( ptr == IPLEN )
ptr = 0 ; /* wrap buffer ptr */
if ( xipbuf [++ptr].addr != ++addr ) /* contiguous ? */
break ;
if ( count == reclen ) /* ( up to selected data length ) */
break ;
if ( !opftype )
{
if (ousban != (addr >> 16) ) /* if INTEL check for K64 overflow */
break ;
}
}
return ( count ) ;
}