#include #include #include #include #include #include #include #include "pcbios.h" #include "vmemory.h" #define FILE_IO #include "file.h" #undef FILE_IO int fgethex(unsigned long *val,int n,FILE *fp) { int c; unsigned long v; int ret; if(0 == n) { *val = 0l; return(0); } v = 0l; ret = 0; while(n) { c = getc(fp); if(('0' <= c) && (c <= '9')) { v <<= 4; v += (unsigned long)(c - '0'); n--; } else if(('A' <= c) && (c <= 'F')) { v <<= 4; v += (unsigned long)(c - 'A' + 10); n--; } else if(('a' <= c) && (c <= 'f')) { v <<= 4; v += (unsigned long)(c - 'a' + 10); n--; } else if(EOF == c) { if(ret == 0) ret = EOF; n = 0; } else if('\n' == c) { ungetc(c,fp); ret = 2; n = 0; } else if(!isspace(c)) { ret = 2; n = 0; } } *val = v; return(ret); } int skipline(FILE *fp) { int c; while('\n' != (c = getc(fp))) { if(EOF == c) return(EOF); } return(0); } int readmot(char *name) { FILE *fp; unsigned char rectype; unsigned long dlength; unsigned long bufaddr; unsigned char databuf[DATABUFSIZE]; unsigned int dbufc; unsigned char sum; unsigned long lvalue; int c; int ret; if(0 == strcmp("-",name)) /* '-' is stdin */ fp = stdin; else { if(NULL == (fp = fopen(name,"rt"))) return(EF_NOTOPEN); } ret = 0; vmstep(1l); while(1) { /* is S recode ? */ if(EOF == (c = getc(fp))) break; if(toupper(c) != 'S') { if('\n' != c) skipline(fp); continue; } /* what recode type ? */ if(EOF == (c = fgethex(&lvalue,1,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } rectype = (unsigned char)lvalue; /* data length */ if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } dlength = lvalue & 0xffl; sum = (unsigned char)dlength; /* address */ switch(rectype) { case 9: case 1: dlength -= 3l; c = fgethex(&bufaddr,4,fp); sum += (unsigned char)(bufaddr >> 8) & 0xff; sum += (unsigned char)bufaddr & 0xff; break; case 8: case 2: dlength -= 4l; c = fgethex(&bufaddr,6,fp); sum += (unsigned char)(bufaddr >> 16) & 0xff; sum += (unsigned char)(bufaddr >> 8) & 0xff; sum += (unsigned char)bufaddr & 0xff; break; case 7: case 3: dlength -= 5l; c = fgethex(&bufaddr,8,fp); sum += (unsigned char)(bufaddr >> 24) & 0xff; sum += (unsigned char)(bufaddr >> 16) & 0xff; sum += (unsigned char)(bufaddr >> 8) & 0xff; sum += (unsigned char)bufaddr & 0xff; break; case 0: /* header recode */ case 4: /* unknown S recode format */ case 5: case 6: dlength--; bufaddr = 0l; c = 0; break; default: c = 2; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } /* data */ if(dlength & 0x80000000) /* if((long)dlength < 0) */ { ret = EF_BADFMT; skipline(fp); continue; } for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) { if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); break; } databuf[dbufc] = (unsigned char)lvalue; sum += databuf[dbufc]; } if(EOF == c) break; if(c) continue; /* sum */ if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } sum = ~sum; if(sum != (unsigned char)lvalue) { fprintf(stderr,"Check sum error.\n"); fprintf(stderr," Recode address:%08lX",bufaddr); fprintf(stderr," Sum of recode :%02X",sum); fprintf(stderr," Sum byte :%02X",(unsigned char)lvalue); if(ret == 0) ret = EF_SUMERR; } skipline(fp); if((rectype == 1) || (rectype == 2) || (rectype == 3)) { vmaddr(bufaddr); if(1 != vmwriteb(databuf,(int)dlength)) { if((ret == 0) || (ret == EF_SUMERR)) ret = EF_VMEXHST; } } else if((rectype == 9) || (rectype == 8) || (rectype == 7)) break; } if(fp != stdin) fclose(fp); return(ret); } int writemot(char *name) { FILE *fp; unsigned long bufaddr; unsigned long logaddr; unsigned long logadds; unsigned long dlength; unsigned long limit; unsigned char databuf[DATABUFSIZE]; unsigned int dbufc; unsigned char sum; unsigned int c; int ret; if(0 == strcmp("-",name)) /* '-' is stdout */ fp = stdout; else { if(NULL == (fp = fopen(name,"wt"))) return(EF_NOTOPEN); } ret = 0; fprintf(fp,"S0%02X0000",strlen(name) + 3); sum = strlen(name) + 3; for(c = 0;name[c];c++) { fprintf(fp,"%02X",name[c]); sum += name[c]; } sum = ~sum; fprintf(fp,"%02X\n",sum); logaddr = 0l; logadds = 1l; /* logadds allway not match */ limit = vmlast(0l,0xffffffff); while(1) { if(WRITEDATASIZE > (limit - logaddr)) dlength = limit - logaddr + 1l; else dlength = WRITEDATASIZE; if((logaddr & VMADDMASK) != logadds) { if((logaddr & VMADDMASK) == ((logaddr + WRITEDATASIZE) & VMADDMASK)) { if(0 == vmsearch(logaddr)) { logaddr &= VMADDMASK; logaddr += VMMEMSIZE; if(logaddr == 0l) break; logaddr -= (logaddr % WRITEDATASIZE); if(logaddr > limit) break; continue; } } logadds = logaddr & VMADDMASK; } vmaddr(logaddr); vmstep(1l); if(0 == vmreadb(databuf,(int)dlength)) { ret = EF_VMEXHST; break; } for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) { if(0xff != databuf[dbufc]) break; } if(dbufc != (unsigned int)dlength) { bufaddr = logaddr; if((bufaddr + dlength - 1l) < 0x10000l) { fprintf(fp,"S1%02lX%04lX",dlength + 3l,bufaddr); sum = (unsigned char)dlength + 3; } else if((bufaddr + dlength - 1l) < 0x1000000l) { fprintf(fp,"S2%02lX%06lX",dlength + 4l,bufaddr); sum = (unsigned char)dlength + 4; } else { fprintf(fp,"S3%02lX%08lX",dlength + 5l,bufaddr); sum = (unsigned char)dlength + 5; } sum += (unsigned char)((bufaddr >> 24) & 0xffl); sum += (unsigned char)((bufaddr >> 16) & 0xffl); sum += (unsigned char)((bufaddr >> 8) & 0xffl); sum += (unsigned char)(bufaddr & 0xffl); for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) { fprintf(fp,"%02X",databuf[dbufc]); sum += databuf[dbufc]; } sum = ~sum; fprintf(fp,"%02X\n",sum); } logaddr += dlength; if(logaddr - 1l >= limit) break; } fprintf(fp,"S9030000FC\n"); if(fp != stdout) fclose(fp); return(ret); } int readitl(char *name) { FILE *fp; unsigned char rectype; unsigned long dlength; unsigned long highadd; unsigned long bufaddr; unsigned char databuf[DATABUFSIZE]; unsigned int dbufc; unsigned char sum; unsigned long lvalue; int c; int ret; if(0 == strcmp("-",name)) /* '-' is stdin */ fp = stdin; else { if(NULL == (fp = fopen(name,"rt"))) return(EF_NOTOPEN); } ret = 0; vmstep(1l); highadd = 0l; while(1) { /* is HEX recode ? */ if(EOF == (c = getc(fp))) break; if(toupper(c) != ':') { if('\n' != c) skipline(fp); continue; } /* data length */ if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } dlength = lvalue & 0xffl; sum = (unsigned char)dlength; /* address */ c = fgethex(&bufaddr,4,fp); sum += (unsigned char)((bufaddr >> 8) & 0xffl); sum += (unsigned char)(bufaddr & 0xffl); /* recode type */ if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } rectype = (unsigned char)lvalue; sum += rectype; /* data */ for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) { if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); break; } databuf[dbufc] = (unsigned char)lvalue; sum += databuf[dbufc]; } if(EOF == c) break; if(c) continue; /* sum */ if(EOF == (c = fgethex(&lvalue,2,fp))) { ret = EF_BADFMT; break; } if(c) { ret = EF_BADFMT; skipline(fp); continue; } sum = 0 - sum; if(sum != (unsigned char)lvalue) { fprintf(stderr,"Check sum error.\n"); fprintf(stderr," Recode address:%08lX",bufaddr); fprintf(stderr," Sum of recode :%02X",sum); fprintf(stderr," Sum byte :%02X",(unsigned char)lvalue); if(ret == 0) ret = EF_SUMERR; } skipline(fp); if((rectype == 0x01) || (dlength == 0l)) /* end recode */ break; switch(rectype) { case 0x00: /* data recode */ case 0x81: break; case 0x02: /* segment address recode */ if(dlength != 2l) c = 2; else highadd = ((unsigned long)databuf[0] << 12) + ((unsigned long)databuf[1] << 4); break; case 0x03: /* start address recode */ c = 0; break; case 0x04: /* linear address recode */ if(dlength != 2l) c = 2; else highadd = ((unsigned long)databuf[0] << 24) + ((unsigned long)databuf[1] << 16); break; default: c = 2; break; } if(c) { ret = EF_BADFMT; continue; } bufaddr += highadd; if((rectype == 0x00) || (rectype == 0x81)) { vmaddr(bufaddr); if(1 != vmwriteb(databuf,(int)dlength)) { if((ret == 0) || (ret == EF_SUMERR)) ret = EF_VMEXHST; } } } if(fp != stdin) fclose(fp); return(ret); } int writeitl(char *name) { FILE *fp; unsigned long highadd; unsigned long bufaddr; unsigned long logaddr; unsigned long logadds; unsigned long dlength; unsigned long limit; unsigned char databuf[DATABUFSIZE]; unsigned int dbufc; unsigned char sum; int ret; if(0 == strcmp("-",name)) /* '-' is stdout */ fp = stdout; else { if(NULL == (fp = fopen(name,"wt"))) return(EF_NOTOPEN); } ret = 0; logaddr = 0l; logadds = 1l; /* logadds allway not match */ highadd = 0l; limit = vmlast(0l,0xffffffff); while(1) { if(WRITEDATASIZE > (limit - logaddr)) dlength = limit - logaddr + 1l; else dlength = WRITEDATASIZE; if((logaddr & VMADDMASK) != logadds) { if((logaddr & VMADDMASK) == ((logaddr + WRITEDATASIZE) & VMADDMASK)) { if(0 == vmsearch(logaddr)) { logaddr &= VMADDMASK; logaddr += VMMEMSIZE; if(logaddr == 0l) break; logaddr -= (logaddr % WRITEDATASIZE); if(logaddr > limit) break; continue; } } logadds = logaddr & VMADDMASK; } vmaddr(logaddr); vmstep(1l); if(0 == vmreadb(databuf,(int)dlength)) { ret = EF_VMEXHST; break; } for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) { if(0xff != databuf[dbufc]) break; } if(dbufc != (unsigned int)dlength) { bufaddr = logaddr; if((bufaddr & 0xffff0000l) != highadd) { highadd = bufaddr & 0xffff0000l; if(highadd >= 0x00100000l) { fprintf(fp,":02000004%04lX",highadd >> 16); sum = 0x02 + 0x04; sum += (unsigned char)((highadd >> 24) & 0xffl); sum += (unsigned char)((highadd >> 16) & 0xffl); sum = 0 - sum; fprintf(fp,"%02X\n",sum); } else { fprintf(fp,":02000002%04lX",highadd >> 4); sum = 0x02 + 0x02; sum += (unsigned char)((highadd >> 12) & 0xffl); sum += (unsigned char)((highadd >> 4) & 0xffl); sum = 0 - sum; fprintf(fp,"%02X\n",sum); } } fprintf(fp,":%02lX%04lX00",dlength,bufaddr & 0xffffl); sum = (unsigned char)dlength; sum += (unsigned char)((bufaddr >> 8) & 0xffl); sum += (unsigned char)(bufaddr & 0xffl); for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) { fprintf(fp,"%02X",databuf[dbufc]); sum += databuf[dbufc]; } sum = 0 - sum; fprintf(fp,"%02X\n",sum); } logaddr += dlength; if(logaddr - 1l >= limit) break; } fprintf(fp,":00000001FF\n"); if(fp != stdout) fclose(fp); return(ret); } int readbin(char *name) { FILE *fp; unsigned long bufaddr; unsigned long logaddr; unsigned char databuf[DATABUFSIZE]; unsigned int dbufc; int c; int ret; if(NULL == (fp = fopen(name,"rb"))) return(EF_NOTOPEN); ret = 0; vmstep(1l); logaddr = 0l; while(1) { bufaddr = logaddr; /* data */ for(dbufc = 0;dbufc < DATABUFSIZE;dbufc++) { if(EOF == (c = getc(fp))) break; databuf[dbufc] = (unsigned char)c; if(++logaddr == 0l) break; } if(0 == dbufc) break; vmaddr(bufaddr); if(1 != vmwriteb(databuf,dbufc)) ret = EF_VMEXHST; if(logaddr == 0l) break; } fclose(fp); return(ret); } int writebin(char *name) { FILE *fp; unsigned long logaddr; unsigned long logadds; unsigned long last; unsigned long dlength; unsigned char databuf[DATABUFSIZE]; unsigned int dbufc; int ret; if(NULL == (fp = fopen(name,"wb"))) return(EF_NOTOPEN); ret = 0; last = vmlast(0l,0xffffffff); logaddr = 0l; logadds = 1l; /* logadds allway not match */ while(1) { if(WRITEDATASIZE > (last - logaddr)) dlength = last - logaddr + 1l; else dlength = WRITEDATASIZE; if((logaddr & VMADDMASK) != logadds) { if((logaddr & VMADDMASK) == ((logaddr + WRITEDATASIZE) & VMADDMASK)) { if(0 == vmsearch(logaddr)) { logaddr &= VMADDMASK; logaddr += VMMEMSIZE; if(logaddr == 0l) break; logaddr -= (logaddr % WRITEDATASIZE); if(logaddr > last) break; continue; } } logadds = logaddr & VMADDMASK; } vmaddr(logaddr); vmstep(1l); if(0 == vmreadb(databuf,(int)dlength)) { ret = EF_VMEXHST; break; } for(dbufc = 0;dbufc < (unsigned int)dlength;dbufc++) fprintf(fp,"%c",databuf[dbufc]); logaddr += dlength; if(logaddr - 1l >= last) break; } fclose(fp); return(ret); }