/** Reference table generator, HP48 Utility Borland C++ 3.0 Detlef Mueller, 24.04.1992 Q&D hack - Usage: GENTAB <[entries file] >[table file] 0.000 24.04.1992 DM coded 100 25.08.1992 DM mofified output to feed it into sasm only 200 26.10.1994 MH modified for unix 300 19.11.1994 MH modified to make a library suitable for Jazz 400 03.01.1995 MH added the DIS.TAB 00000 terminator 500 19.06.1995 MH made to output proper headers made preferrance clear via indexing 600 31.05.1996 MH added MAXLEN definition to reduce memory use changed to use unsigned int for ENTRY->index **/ #include #include #include #include #include #include #ifndef MSDOS #include #endif #ifdef MSDOS #include #include /* MesS-DOS */ #include /* MesS-DOS */ #endif #define MAJVER 1 #define MINVER 0 #define REVER 0 #define WRKFILE "________.TMP" #define STARTCH ' ' #define MAXLEN 12 /* Max name length in chars */ typedef enum { ERROR, WARNING } ERRTYPE ; typedef struct { char name[MAXLEN+1] ; unsigned long addr ; unsigned int index ; /* Added for DIS.TAB generation */ } ENTRY ; static ENTRY **table = NULL ; static unsigned int entries = 0; static unsigned int hash[128 - STARTCH] = { 0 } ; void Error ( ERRTYPE messt, char *msg, ... ) { va_list argptr ; char *tstr, str[81] ; va_start( argptr, msg ) ; vsprintf( str, msg, argptr ) ; switch ( messt ) { case ERROR : tstr = "\nError: %s " ; break ; case WARNING : tstr = "\nWarning: %s " ; break ; default : tstr = "Unknown error: %s " ; } fprintf( stderr, tstr, str ) ; #ifdef MSDOS if ( errno != EZERO ) #else if ( errno != 0 ) /* No idea what EZERO is.. */ #endif perror( "" ) ; else fputc( '\n', stderr ) ; va_end( argptr ) ; if ( messt == ERROR ) exit( -1 ) ; } static int compare ( const void *s1, const void *s2 ) { register char *s_1, *s_2 ; for ( s_1 = (*(ENTRY **)s1)->name, s_2 = (*(ENTRY **)s2)->name ; *s_1 || *s_2 ; ++s_1, ++s_2 ) if ( *s_1 != *s_2 ) return ( *s_1 - *s_2 ) ; return ( 0 ) ; } /* * qsort is not stable, but we need stability to get preferrance * Thus we assign indexes to the entries based on input order, and if * the addresses of the entries match then input order determines * comparison result. Thus address sort never returns equality. */ static int compare2 ( const void *s1, const void *s2 ) { long ind1, ind2 ; if( (*(ENTRY **)s1)->addr > (*(ENTRY **)s2)->addr) return 1; else if( (*(ENTRY **)s1)->addr < (*(ENTRY **)s2)->addr) return -1; else if( (*(ENTRY **)s1)->index > (*(ENTRY **)s2)->index) return 1; else return -1; } static void Work ( void ) { static char image[] = "\\|/-" ; static int i = 0 ; fputc( '\b', stderr ) ; fputc( image[i = (i + 1) & 3], stderr ) ; } static void WriteRTab ( FILE *fout ) { unsigned int i, *h ; char ch = '\0' ; ENTRY **entry ; fputs( "\nWriting hash table ...", stderr ) ; fputs( "RplTab\n", fout ); fputs( "\tCON(5)\t#02A2C\t\t=DOCSTR\n", fout ); fputs( "\tREL(5)\tRplEnd\n", fout ); fputs( "\tNIBASC\t'\\00\\n'\n", fout ); for ( i = 0, h = hash ; i < (sizeof( hash ) / sizeof( *hash )) - 1 ; ++i ) if ( *h++ ) fprintf( fout, "\tREL(5)\t_%c_\n", i + STARTCH ) ; else fprintf( fout, "\tCON(5)\t0\n" ) ; fprintf( fout, "\tREL(5)\tRplEnd\n" ) ; fputs( "\nWriting reference table ... ", stderr ) ; for ( i = 0, entry = table ; i < entries ; ++i, ++entry ) { if ( *(*entry)->name != ch ) fprintf( fout, "_%c_\n", ch = *(*entry)->name ) ; fprintf( fout, "lb%04X", (*entry)->index); fprintf( fout,"\tCON(6)\t#%lX\n\tNIBASC\t`%s`\n", (*entry)->addr | ((long)strlen( (*entry)->name ) << 20), (*entry)->name ) ; if ( ! (i % 100) ) Work() ; } fputs( "RplEnd\n", fout ) ; fputs( "\b ", stderr ) ; } static void WriteDTab ( FILE *fout ) { unsigned int i, *h ; char ch = '\0' ; ENTRY **entry ; fputs( "\nWriting address table ...", stderr ) ; fputs( "DisTab\n", fout ); fputs( "\tCON(5)\t#02A2C\t\t=DOCSTR\n", fout ); fputs( "\tREL(5)\tDisEnd\n", fout ); fputs( "\tNIBASC\t'\\x00\\x0B'\n", fout ); fprintf( fout, "\tCON(5)\t%ld\n", entries); for ( i = 0, entry = table ; i < entries ; ++i, ++entry ) { fprintf( fout, "\tCON(5)\t(lb%04X)-(RplTab)\t\t%s\n", (*entry)->index, (*entry)->name); if ( ! (i % 100) ) Work() ; } fputs( "\tCON(5)\t0\n", fout ) ; fputs( "DisEnd\n", fout ) ; fputs( "\b ", stderr ) ; } static void ReadTab ( FILE *fin ) { static char line[80], buffer[256] ; char *pl, *pa ; unsigned int i ; long addr ; ENTRY entry, **tab ; FILE *ftmp ; if ( ! (ftmp = fopen( WRKFILE, "wb" )) ) Error( ERROR, "Can't create <%s>", WRKFILE ) ; fprintf( stderr, "\nReading and converting input ... " ) ; while ( fgets( line, 80, fin ) ) if ( strlen( line ) && *line != '\n' ) { pl = strcpy( buffer, line ) ; if ( ! (pl = strtok( *pl == '=' ? pl + 1 : pl, "\n\r\t " )) || strlen( pl ) > MAXLEN || *pl == '*' || *pl > '~' || ! strtok( NULL, "\n\r\t " ) || ! (pa = strtok( NULL, "\n\r\t " )) || ! (i = sscanf( *pa == '#' ? pa + 1 : pa, "%lX", &addr )) || i == EOF || (addr & 0xFFF00000L) ) continue ; hash[*pl - STARTCH] = 1 ; strcpy( entry.name, pl ) ; entry.addr = addr ; entry.index = 0 ; if ( ! fwrite( &entry, sizeof( ENTRY ), 1, ftmp ) ) Error( ERROR, "Write error on <%s>", WRKFILE ) ; if ( ! (++entries % 100) ) Work() ; } fclose( ftmp ) ; if ( ! entries ) Error( ERROR, "Sorry, no entries found" ) ; fputs( "\b ", stderr ) ; fprintf( stderr, "\nFound %u symbols\nGenerating table ... ", entries ) ; if ( ! (ftmp = fopen( WRKFILE, "rb" )) ) Error( ERROR, "Can't reopen <%s>", WRKFILE ) ; if ( ! (table = (ENTRY **)malloc( entries * sizeof( ENTRY *) )) ) Error( ERROR, "Can't alloc room for %u entries", entries ) ; for ( i = 0, tab = table ; i < entries ; ++i, ++tab ) { if ( ! (*tab = (ENTRY *)malloc( sizeof( ENTRY ) )) ) Error( ERROR, "Can't alloc %d bytes room for %uth entry", sizeof( ENTRY ), i ) ; if ( ! fread( *tab, sizeof( ENTRY ), 1, ftmp ) ) Error( ERROR, "Can't read %uth entry from <%s>", i, WRKFILE ) ; if ( ! (i % 100) ) Work() ; } fputs( "\b ", stderr ) ; fclose( ftmp ) ; unlink( WRKFILE ) ; } void main ( int argc, char *argv[] ) { int i; ENTRY **tab ; #ifdef MSDOS fprintf( stderr, "\n%s, Version %d.%d.%d, %s %s BC %X.%X, (c) 1992 DM.\n", argv[0], MAJVER, MINVER, REVER, __DATE__, __TIME__, __TURBOC__ >> 8, __TURBOC__ & 0x00FF ) ; /* MesS-DOS */ setmode( fileno( stdout ), O_BINARY ) ; /* MesS-DOS */ setmode( fileno( stdin ), O_BINARY ) ; /* MesS-DOS */ #endif ReadTab( stdin ) ; /* Output download header */ fputs( "\tNIBASC\t\\HPHP48-X\\\n", stdout ) ; /* Output library header */ fputs( "\tCON(5)\t#02B40\t\tDOLIB\n", stdout ) ; fputs( "\tREL(5)\tLibEnd\n", stdout ); fputs( "\tCON(2)\t0\t\tNo title\n", stdout ); fputs( "\tCON(3)\t993\t\tLID\n", stdout ); fputs( "\tREL(5)\tHshTab\n", stdout ); fputs( "\tCON(5)\t0\t\tNo message table\n", stdout ); fputs( "\tREL(5)\tLnkTab\n", stdout ); fputs( "\tREL(5)\tCfgObj\n", stdout ); /* Output configuration object */ fputs( "CfgObj\tCON(5)\t#02D9D\tDOCOL\n", stdout ); fputs( "\tCON(5)\t#02911\tDOBINT\n", stdout ); fputs( "\tCON(5)\t993\n", stdout ); fputs( "\tCON(5)\t#07709\tTOSRRP\n", stdout ); fputs( "\tCON(5)\t#0312B\tSEMI\n", stdout ); /* Output hash table */ fputs( "\nHshTab\tCON(5)\t#02A4E\tDOHSTR\n", stdout ); fputs( "\tREL(5)\tHshEnd\n", stdout ); for(i = 1 ; i <= 16 ; i++ ) if( i != 7 ) fprintf( stdout, "\tCON(5)\t0\tNo names of lenght %d\n", i); else fputs( "\tREL(5)\tNamRpl\n", stdout ); fputs( "\tREL(5)\tNamsEnd\n", stdout ); fputs( "NamRpl\tCON(2)\t7\n\tNIBASC\t'RPL.TAB'\n\tCON(3)\t0\n", stdout ); fputs( "NamDis\tCON(2)\t7\n\tNIBASC\t'DIS.TAB'\n\tCON(3)\t1\n", stdout ); fputs( "NamsEnd\tCON(5)\t(*)-(NamRpl)\n", stdout ); fputs( "\tCON(5)\t(*)-(NamDis)\n", stdout ); fputs( "HshEnd\n", stdout ); /* Output link table */ fputs( "\nLnkTab\tCON(5)\t#02A4E\tDOHSTR\n", stdout ); fputs( "\tREL(5)\tLnkEnd\n", stdout ); fputs( "\tREL(5)\tRplTab\n", stdout ); fputs( "\tREL(5)\tDisTab\n", stdout ); fputs( "LnkEnd\n", stdout ); /* Assign preferrance indexes based on input order */ for( i = 0, tab = table ; i < entries ; ++i, ++tab) (*tab)->index = i; /* Output RPL.TAB */ fprintf( stderr, "\nSorting (by name)..." ) ; qsort( table, entries, sizeof( ENTRY * ), compare ) ; fputs( "\n\tCON(1)\t8\n", stdout ); fputs( "\tCON(3)\t993\n", stdout ); fputs( "\tCON(3)\t0\n", stdout ); WriteRTab( stdout ) ; /* Output DIS.TAB */ fprintf( stderr, "\nSorting (by address)..." ) ; qsort( table, entries, sizeof( ENTRY * ), compare2 ) ; fputs( "\n\tCON(1)\t8\n", stdout ); fputs( "\tCON(3)\t993\n", stdout ); fputs( "\tCON(3)\t1\n", stdout ); WriteDTab( stdout ) ; /* Output library end */ fputs( "\tCON(4)\t0\t\tCRC\n", stdout ); fputs( "LibEnd\n", stdout ); free( table ) ; fprintf( stderr, "\nTo create library table execute:\n"); fprintf( stderr, "\tsasm -EHN tab\n"); fprintf( stderr, "\tlbcrc tab.o\n"); exit( 0 ) ; }