📄 sload.c
字号:
/************************************************************* * File: mon/sload.c * Purpose: S-record loader * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Removed duplicate globals * 970303 Switched chksum to static. * 970901 Added getNextSloadAdr(). Needed for sdtf cmd. * 970919 Changed getNextSloadAdr to getHighLoadAdr for BSO. Also * changed code to make nextaddr be highest addr, not last. * 970920 Added msgs for illegal loads. * 980404 Added DL_MFLAG * 981212 Accept but ignore S5 recs (ghs) */#include <stdio.h>#include <termio.h>#include <string.h>#include <mon.h>/* * Useful S-records for testing purposes: * S0030000FC * S309900200001234567860 * S7058002000073 * */static int chksum;static Ulong nextaddr;char recbuf[MAXREC];/************************************************************** sload(rec,offset,pLen,pFlags)* load Motorola S-records* returns:* -1 on error* 0 at end* N for data records (N = bytes transferred)*/sload(rec,offset,pLen,pFlags)char *rec;Ulong offset;int *pLen,*pFlags;{int len,x,flags;flags = *pFlags;*pLen = 0;len = 0;if(rec[0] == 'S') { if (rec[1] >= '7' && rec[1] <= '9') { if (flags&DL_MFLAG) ; /* don't set entry address */ else if (!endrec(rec,offset,flags)) return(0); else return(-1); } else if (rec[1] == 'D') { flags |= DL_DFLAG; *pFlags = flags; if (regChain) /* 970920 */ printf("ERROR: Reset controller before reloading driver.\n"); } else if (rec[1] == '4') { if (dlsym(rec,(flags&DL_AFLAG)?0:offset,flags)) return(-1); } else if (rec[1] >= '1' && rec[1] <= '3') { if (!regChain && !(flags&DL_DFLAG)) /* 970920 */ printf("ERROR: Load driver first.\n"); else if (flags&DL_MFLAG) ; /* don't load memory */ else if (x=datarec(rec,offset,&len,flags)) return(x); } else if (rec[1] == '0') return(1); else if (rec[1] == '5') ; /* accept but ignore S5 recs (ghs) */ else return(-1); }else return(-1);if (len >= 0) { *pLen = len; return(1); }else return(-1);}/************************************************************** datarec(p,offset,pLen,flags)* handle an S-record data record*/datarec(p,offset,pLen,flags)Uchar *p;Ulong offset;int *pLen,flags;{int len,i,cs;Ulong addr,v;*pLen = 0;chksum = 0;if (!gethex(&len,&p[2],2)) return(-1);chksum += len;if (len*2 != strlen(p)-4) return(-2);i = 4; addr = 0;switch (p[1]) { case '3' : if (!gethex(&v,&p[i],2)) return(-1); addr = (addr<<8)+v; chksum += v; i += 2; /* fall thru */ case '2' : if (!gethex(&v,&p[i],2)) return(-1); addr = (addr<<8)+v; chksum += v; i += 2; /* fall thru */ case '1' : if (!gethex(&v,&p[i],2)) return(-1); addr = (addr<<8)+v; chksum += v; if (!gethex(&v,&p[i+2],2)) return(-1); addr = (addr<<8)+v; chksum += v; break; default : return(-3); }#if 0/* This stuff is to implement input files under PMON. It is not clear * whether something like this is possible under IMON. For the moment * I have disabled it. */if (flags&DL_TFLAG) { if (getGpr(7) == 0) { topClientMem -= addr; putGpr(29,clienttos()); tbase = topClientMem-addr; putGpr(7,topClientMem); } addr += tbase; }else addr += offset;#elseaddr += offset;#endifp = &p[i+4];len -= (i/2)+1; /* substract address and chksum fields from length */for (i=0;i<len;i++,p+=2) { if (!gethex(&v,p,2)) return(-1); if (flags&DL_DFLAG) store_byte(addr++,v); else write_target(XT_MEM,addr++,v,1); chksum += v; }if (!gethex(&cs,p,2)) return(-1);if (!(flags&DL_IFLAG) && cs != ((~chksum)&0xff)) return(-4);*pLen = i;if (addr > nextaddr) nextaddr = addr;return(0);}/************************************************************** writec(fd,ch)*/writec(fd,ch)int fd;Uchar ch;{write(fd,&ch,1);}/************************************************************** dlsym(p,offset,flags)* handle S4 records, i.e., symbols*/dlsym(p,offset,flags)Uchar *p;Ulong offset;int flags;{Uchar val;Ulong adr;int len,csum;Uchar name[LINESZ],*t;/* S4LLAAAAAAAANNNNNNNN,AAAAAAAANNNNNN,AAAAAAAANNNNNNNNNN,CCLL=length AAAAAAAA=addr NNNN,=name CC=checksum */if (flags&DL_DFLAG) return(0); /* ignore syms if loading a driver */p += 2; /* skip past S4 */if (!gethex(&len,p,2)) return(1);p += 2; /* skip past length */for (;len > 2;) { if (!gethex(&adr,p,8)) return(2); p += 8; /* skip past addr */ len -= 8; t = (Uchar *)strchr(p,','); if (t == 0) return(1); strNcpy(name,p,t-p); len -= t-p; if (!newsym(name,adr+offset)) return(3); p = t+1; }if (!gethex(&csum,p,2)) return(4);/* csum neither generated nor checked */return(0);}/************************************************************** endrec(p,offset,flags)* handle the S-record termination record*/endrec(p,offset,flags)Uchar *p;Ulong offset;int flags;{Ulong adr;switch (p[1]) { case '7' : if (!gethex(&adr,&p[4],8)) return(-1); break; case '8' : if (!gethex(&adr,&p[4],6)) return(-1); break; case '9' : if (!gethex(&adr,&p[4],4)) return(-1); break; }if (!(flags&DL_DFLAG)) putPc(adr+offset);return(0);}/************************************************************** Ulong getHighLoadAdr()*/Ulong getHighLoadAdr(){return nextaddr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -