/* ---------------------------------------------------------------------- * FILE: emitter.c * PACKAGE: as31 - 8031/8051 Assembler. * * DESCRIPTION: * This file contains the code to generate various * object code formats. Provisions exist to * support many types of output formats within the * same executable. * * REVISION HISTORY: * Jan. 19, 1990 - Created. (Ken Stauffer) * Jan. 29, 1990 - Added S-records (Theo Deraadt) * * * AUTHOR: * All code in this file written by Ken Stauffer (University of Calgary). * January, 1990. */ #include /* ---------------------------------------------------------------------- * DECLARE your own open(), close(), addr(), and byte() routines here. * */ static int open1(), close1(), addr1(), byte1(); static int open2(), close2(), addr2(), byte2(); static int open3(), close3(), addr3(), byte3(); static int open4(), close4(), addr4(), byte4(); /* ---------------------------------------------------------------------- * ADD an entry to this table to register your * output format routines. Give your object format * a name to be specified with the -F option. * */ static int format; static struct { char *name; int (*e_open)(); int (*e_close)(); int (*e_addr)(); int (*e_byte)(); } formtab[] = { { "tdr", open1, close1, addr1, byte1 }, { "byte", open2, close2, addr2, byte2 }, { "od", open3, close3, addr3, byte3 }, { "srec2", open4, close4, addr4, byte4 }, { "srec3", open4, close4, addr4, byte4 }, { "srec4", open4, close4, addr4, byte4 } }; #define FORMTABSIZE (sizeof(formtab)/sizeof(formtab[0])) emitusage() { int i; fprintf(stderr, "\tfmt is one of:"); for(i=0; i=' ' && b[i]<='~') ? b[i] : '.' ); else break; } fprintf(fout,"\n"); } /* ---------------------------------------------------------------------- * srecord format. This is called with "-Fsrec2", "-Fsrec3", or * "-Fsrec4"... * * arg: This is a number in decimal which specifies * the offset, -Fsrec3 -A0000 * * These options specifies the tdr format, with an argument * of 0. This becomes the offset used in generating the * script file. The default if no A is present is 0x0000. * */ #define SREC_BYTESPERLINE 32 static char format4; static int check4, index4; static char buf4[SREC_BYTESPERLINE]; static long address4; static open4(file,ftype,arg) char *file, *ftype, *arg; { format4 = ftype[4]; /* will be '2' -- '4' */ fout = fopen(file,"w"); if( fout == NULL ) { fprintf(stderr,"Cannot open %s for writing.\n",file); exit(1); } if(arg) offset = atoi(arg); else offset = 0; fprintf(fout, "S0030000%02X\n", (~3 & 0xff) ); } static close4() { if(index4) finishline(); switch(format4) { case '2': fprintf(fout, "S9030000%02X\n", ~3 & 0xff); break; case '3': fprintf(fout, "S804000000%02X\n", ~4 & 0xff); break; case '4': fprintf(fout, "S70500000000%02X\n", ~5 & 0xff); break; } fclose(fout); } static addr4(a) unsigned long int a; { if(index4>0) finishline(); address4 = a + offset; } static byte4(b) { buf4[index4++] = b; if(index4==SREC_BYTESPERLINE) { finishline(); address4 += SREC_BYTESPERLINE; } } finishline() { int i; check4 = index4 + (address4 & 0xff) + ((address4>>8) & 0xff) + 4; switch(format4) { case '2': fprintf(fout, "S1%02X%04X", index4 + 4, address4 & 0xffff); break; case '3': fprintf(fout, "S2%02X%06X", index4 + 6, address4 & 0xffffff); check4 += ((address4>>16) & 0xff) + 2; break; case '4': fprintf(fout, "S3%02X%08X", index4 + 8, address4); check4 += ((address4>>16) & 0xff) +((address4>>24) & 0xff) + 4; break; } for(i=0; i