?? emitter.c
字號:
/* ---------------------------------------------------------------------- * 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 <stdio.h>/* ---------------------------------------------------------------------- * 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<FORMTABSIZE; ) { fprintf(stderr, "%s", formtab[i].name); if( ++i < FORMTABSIZE) fprintf(stderr, ", "); } fprintf(stderr, ".\n");}emitopen(file,ftype,arg)char *file,*ftype,*arg;{ int i; if( ftype ) { for(i=0; i<FORMTABSIZE; i++ ) { if( !strcmp(formtab[i].name,ftype) ) { format = i; (*formtab[format].e_open)(file,ftype,arg); return; } } fprintf(stderr, "warning: no format \"%s\", using \"%s\"\n", ftype, formtab[0].name); } /* * 0th entry is the default format type */ format = 0; (*formtab[format].e_open)(file,ftype,arg);}emitclose(){ (*formtab[format].e_close)();}emitaddr(a)unsigned long int a;{ (*formtab[format].e_addr)(a);}emitbyte(b)int b;{ (*formtab[format].e_byte)(b);}/* ---------------------------------------------------------------------- * Individual file format routines appear here: * Each file format must define the following routines: * open() - Called ONCE before any of the others. * It is passed with a filename and a format * specific argument. * * close() - Called ONCE when no more emit_byte() * function calls will be made. * * addr() - Called when ever a new address has been set * in the assembler (ie. .org, .skip). * This routine is also called once when the * location counter is set to 0 at the very start of * assembling. * * byte() - Called with each byte to be outputed. * *//* ---------------------------------------------------------------------- * "tdr" format. For tdr's 68008 system. Generates a * script file readable by a debugger. * [addr] : [byte] [byte] .. * * arg: This is a number in decimal which specifies * the offset, -Ftdr -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 0x10000. * */static unsigned long addr;static FILE *fout;static long int offset;static int newaddr;static int pos=-666;static open1(file,ftype,arg)char *file, *ftype, *arg;{ fout = fopen(file,"w"); if( fout == NULL ) { fprintf(stderr,"Cannot open %s for writting.\n",file); exit(1); } if( arg ) { offset = atoi(arg); } else offset = 0x10000;}static close1(){ if( pos != 15 ) fprintf(fout,"\n"); fclose(fout);}static addr1(a)unsigned long int a;{ addr = a; newaddr = 1;}static byte1(b)unsigned char b;{ if( newaddr ) { if( pos != -666 ) fprintf(fout,"\n"); newaddr = 0; pos = 15; fprintf(fout,"%06x: ",addr+offset); } else if( pos == 15 ) { fprintf(fout,"%06x: ",addr+offset); } fprintf(fout,"%02x ", b&0xff ); if( pos-- == 0 ) { fprintf(fout,"\n"); pos = 15; } addr += 1;}/* ---------------------------------------------------------------------- * "byte" format. * Like "tdr" but each byte is on a line by itself. * This is nice for debugging. No -A is used. */static open2(file,ftype,arg)char *file, *ftype, *arg;{ fout = fopen(file,"w"); if( fout == NULL ) { fprintf(stderr,"Cannot open %s for writting.\n",file); exit(1); }}static close2(){ fclose(fout);}static addr2(a)unsigned long int a;{ addr = a;}static byte2(b)unsigned char b;{ fprintf(fout,"%04x: %02x\n", addr, b&0xff ); addr += 1;}/* ---------------------------------------------------------------------- * "od", this format shows 16 bytes per line, with address. * It also includes ascii on one side. * * The format is similar to the od(1) program under Unix. * */static int pos3;static unsigned char buf[16];static unsigned long saveaddr;static open3(file,ftype,arg)char *file, *arg;{ fout = fopen(file,"w"); if( fout == NULL ) { fprintf(stderr,"Cannot open %s for writting.\n",file); exit(1); }}static close3(){ dumpline(saveaddr,buf,pos3-1); fclose(fout);}static addr3(a)unsigned long int a;{ newaddr = 1; addr = a;}static byte3(b)unsigned char b;{ if( newaddr ) { dumpline(saveaddr,buf,pos3-1); pos3 = 0; newaddr = 0; saveaddr = addr; } else if( pos3 == 16 ) { dumpline(saveaddr,buf,pos3-1); pos3 = 0; saveaddr = addr; } buf[pos3++] = b & 0x00ff; addr += 1;}dumpline(a,b,len)unsigned long a;unsigned char *b;int len;{ int i; if(len <= 0 ) return; fprintf(fout,"%04x: ",a); for(i=0; i<8; i++ ) { if( i <= len ) fprintf(fout,"%02x ",b[i]); else fprintf(fout," "); } fprintf(fout,"- "); for(i=8; i<16; i++ ) { if( i <= len ) fprintf(fout,"%02x ",b[i]); else fprintf(fout," "); } fprintf(fout," "); for(i=0; i<16; i++ ) { if( i <= len ) fprintf(fout,"%c", (b[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 32static 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<index4; i++) { fprintf(fout, "%02X", buf4[i] & 0xff); check4 += buf4[i]; } fprintf(fout, "%02X\n", (~check4 & 0xff) ); index4 = 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -