/************************************************************* * File: mon/fload.c * Purpose: fast-format file loader * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Start of revision history * 980404 Added DL_MFLAG */ #include /* * Useful fast-records for testing purposes: * /ACgAgAA - addr = a0020000 * /ZAI - clear 24 bytes * /E - define entry at 'addr' and exit * AAABAAAC - 00 00 01 00 00 02 * /Sfred,X - symbol = 'addr' * /BAB - byte of 01 */ #define MSK 0xff Uchar exta = ','; Uchar extb = '.'; Uchar extc = '/'; extern int chksum; extern ADDR nextaddr; extern int blksz; extern int blkinx; /************************************************************* * fload(rec,offset,plen,pFlags) * load a fast-mode record */ fload(Uchar *rec,ADDR offset,int *plen,int *pFlags) { int n,i,c,len,s,flags; Uchar adat[8],name[LINESZ]; Uchar buf[3]; ADDR addr; Ulong zcnt,bdat,j; flags = *pFlags; *plen = 0; s = 1; for (len=0;;) { if (!getrec(adat,rec)) break; if (flags&DL_MFLAG && !(adat[0] == 'A' || adat[0] == 'S')) continue; /* don't load memory */ if (adat[0] == '/') { switch (adat[1]) { case 'D' : /* this is a driver */ flags |= DL_DFLAG; break; case 'K' : /* klear checksum (sic) */ chksum = 0; break; case 'C' : /* compare checksum */ if (!getb64(&zcnt,&adat[2],-2)) return(-1); chksum &= 0xfff; if (!(flags&DL_IFLAG) && zcnt != chksum) return(-4); chksum = 0; break; case 'Z' : /* zero fill */ if (!getb64(&zcnt,&adat[2],2)) return(-1); buf[0] = buf[1] = buf[2] = 0; for (i=0;i= 4) { if (!getrec(adat,rec)) return(-2); i = 0; } } name[j] = 0; if (!(flags&DL_DFLAG)) /* ignore syms if driver */ if (!newsym(name,nextaddr)) return(-5); break; default : return(-3); } } else { /* data */ if (!getb64(&bdat,&adat[0],4)) return(-1); for (i=2;i>=0;i--) { buf[i] = bdat&MSK; bdat>>= 8; } memwrite(buf,3,flags); len += 3; } } *plen = len; *pFlags = flags; return(s); } /************************************************************* * getrec(p,curblk) * get the next 4-byte record (if there are any left) */ getrec(p,curblk) Uchar *p,*curblk; { int i; if (blkinx >= blksz) return(0); for (i=0;i<4;i++) p[i] = curblk[blkinx++]; return(1); } /************************************************************* * memwrite(dat,n,flags) * write the data to memory */ memwrite(dat,n,flags) Uchar *dat; int n,flags; { int i; for (i=0;i= 'A' && c <= 'Z') v |= c-'A'; else if (c >= 'a' && c <= 'z') v |= c-'a'+26; else if (c >= '0' && c <= '9') v |= c-'0'+52; else if (c == exta) v |= 62; else if (c == extb) v |= 63; else return(0); } switch (n) { case 6 : chksum += (v>>24)&0xfff; case 4 : chksum += (v>>12)&0xfff; case 2 : chksum += v&0xfff; } *vp = v; return(1); }