diff --git a/WEGA/src/cmd/pburn/pb.file.c b/WEGA/src/cmd/pburn/pb.file.c new file mode 100644 index 0000000..e7d6f97 --- /dev/null +++ b/WEGA/src/cmd/pburn/pb.file.c @@ -0,0 +1,424 @@ +/************************************************************************ +* * +* pburn - prom programmer * +* * +* pb1.file.c : wega p8000 16-bit-teil * +* c-quelle * +* * +************************************************************************/ + +/* the valid magic numbers for the a.out are defined below: */ + +#define S_MAGIC1 0xE607 /* segmented executable */ +#define S_MAGIC3 0xE611 /* segemented separate I & D */ +#define S_MAGIC4 0xE605 /* segmented overlay */ +#define N_MAGIC1 0xE707 /* nonsegmented executable */ +#define N_MAGIC3 0xE711 /* nonsegmented separate I & D */ +#define N_MAGIC4 0xE705 /* nonsegmented overlay */ +#define X_MAGIC1 0xE507 /* 8-bit executable */ +#define X_MAGIC3 0xE511 /* 8-bit separate I & D */ +#define X_MAGIC4 0xE505 /* 8-bit overlay */ + +/* valid flags in the s_flags field are defined as follow: */ + +#define SF_STRIP 0x0001 /* relocation info has been stripped */ +#define SF_OPREP 0x0002 /* module changed by OPREP program */ +#define SF_Z8 0x0004 /* u8 program */ +#define SF_Z80 0x0008 /* u880 program */ +#define SF_SEND 0x0010 /* module created by SEND */ +#define SF_7FSTK 0x0020 /* stack resides in segment 0x7f */ + +/* these definitions apply to the sg_atr field in the segment table */ + +#define SG_CODE 0x0001 /* segment contains code */ +#define SG_DATA 0x0002 /* contains initialized data */ +#define SG_BSS 0x0004 /* contains uninitialized data */ +#define SG_STACK 0x0008 /* the segment grows downward */ +#define SG_OCODE 0x0010 /* code section is offset */ +#define SG_ODATA 0x0020 /* data section is offset */ +#define SG_OBSS 0x0040 /* bss section is offset */ +#define SG_BOUND 0x0080 /* segment number bound to this section */ + +#define rmode 0 /* read mode */ +#define wmode 1 /* write mode */ +#define true 1 +#define false 0 +#define fil "\n\nfile" +#define to "to" + +/* identifier file + --------------- */ +extern char namef[50], namee1[20], bre, sect; +extern int kenns, kennfo; +extern unsigned segnr, begadrf, begadre1, begadre2, entryf, lange1, lange2, langf, prlang; +extern int answer, next; + +/* identifier error + ---------------- */ +extern int error; +extern int warning; +extern int eof; + +/* the object module header structure is as defined below for a.out object file format */ + +struct st1 +{ + int s_magic; /* magic number */ + long s_imsize; /* size of memory image section */ + long s_bss; /* size of bss section */ + unsigned s_segt; /* size of segment table section */ + unsigned s_syms; /* size of symbol table section */ + long s_entry; /* entry point address */ + unsigned s_flag; /* flags word */ + unsigned s_codesz; /* 8-bit padded code size */ + unsigned s_lines; /* number of line table entries */ +}; +struct st1 s_exec; + +/* the segment table is an array of the following structure. Each*/ +/* entry relates to one segment in the program. For file types */ +/* with magic number S_MAGIC1 there is a maximum of 128 such */ +/* entries. For file types S_MAGIC3 there is a maximum of */ +/* 256 entries. For the remaining file types there is always 1 */ +/* entry in the segment table */ + +struct st2 +{ + unsigned char sg_segno; /* segment number */ + unsigned char sg_coff; /* offset/256 for code section */ + unsigned char sg_doff; /* offset/256 for data section */ + unsigned char sg_boff; /* offset/256 for bss section */ + unsigned sg_code; /* size of the code portion */ + unsigned sg_data; /* size of the data portion */ + unsigned sg_bss; /* size of the bss portion */ + int sg_atr; /* attributes */ + long sg_unused; /* unused */ +}; +struct st2 segt, bsegt; + +int fd,fd1; /* file deskriptor */ +unsigned nbytes; /* read n bytes */ +unsigned n_read; /* tatsaechlich gelesene bytes */ +unsigned n_write; /* tatsaechlich geschriebene bytes */ +int offset256; /* offset/256 */ +int zsegt, zhl1, zhl2; +unsigned adr, len; +int cfd, cfd1; +long aoffset, hoffset, boffset, offset; +char progbuf[0x4000]; +char *peprombuf; +char *pprogbuf; +char eprombuf[0x4000]; +/* open filename + ------------- */ + +openfile() +{ + fd=open (namef,rmode); + cfd=1; + if (fd==-1) {error=3; outerr(); return;} + nbytes=24; + n_read=read (fd,&s_exec,nbytes); + if (n_read!=nbytes||n_read==0) {error=8; outerr(); return;} + if (s_exec.s_magic!=S_MAGIC1&&s_exec.s_magic!=S_MAGIC3&&s_exec.s_magic!=S_MAGIC4&& + s_exec.s_magic!=N_MAGIC1&&s_exec.s_magic!=N_MAGIC3&&s_exec.s_magic!=N_MAGIC4&& + s_exec.s_magic!=X_MAGIC1&&s_exec.s_magic!=X_MAGIC3&&s_exec.s_magic!=X_MAGIC4) + {error=5; outerr(); return;} + nbytes=16; + zsegt=s_exec.s_segt; + zhl1=0; + zhl2=0; + boffset=24; + + do + { + n_read=read (fd,&bsegt,nbytes); + if (n_read!=nbytes||n_read==0) {error=8; outerr(); return;} + if (zhl2==0) {if (segnr==bsegt.sg_segno) {zhl2=1; + segt.sg_segno=bsegt.sg_segno; + segt.sg_coff=bsegt.sg_coff; + segt.sg_doff=bsegt.sg_doff; + segt.sg_boff=bsegt.sg_boff; + segt.sg_code=bsegt.sg_code; + segt.sg_data=bsegt.sg_data; + segt.sg_bss=bsegt.sg_bss; + segt.sg_atr=bsegt.sg_atr; + segt.sg_unused=bsegt.sg_unused;}} + hoffset=16; + boffset=boffset+hoffset; + if (zhl2==0) {hoffset=bsegt.sg_code; + boffset=boffset+hoffset; + hoffset=bsegt.sg_data; + boffset=boffset+hoffset;} + zsegt=zsegt-16; + }while (zsegt!=0); + if (zhl2==0) {error=6; outerr(); return;} + if (sect=='d') {if (s_exec.s_magic!=S_MAGIC3&&s_exec.s_magic!=N_MAGIC3) + {error=7; outerr(); return;} + if (kennfo==0) {begadrf=segt.sg_doff; + begadrf=begadrf << 8;}} + else {if (kennfo==0) {eof=segt.sg_atr & 0x0003; + if (eof==2) begadrf=segt.sg_doff; + else begadrf=segt.sg_coff; + begadrf=begadrf << 8;}} +} + + +/* read file + --------- */ + +readfile () +{ +int bwarning, beof; + for (zhl2=0;zhl2<0x4000;zhl2++) progbuf[zhl2]=0xff; + for (zhl2=0;zhl2<0x4000;zhl2++) eprombuf[zhl2]=0xff; + bwarning=true, beof=true; + offset=boffset; +if (s_exec.s_magic==X_MAGIC3||s_exec.s_magic==N_MAGIC3||s_exec.s_magic==S_MAGIC3) + /* separate I & D */ +{ + if (sect=='i') /* instruction */ + {if ((segt.sg_atr & 1)>0) + {adr=segt.sg_coff; len=segt.sg_code;} + else {warning=1; outwar(); return;}} + else /* data */ + {if ((segt.sg_atr & 2)>0) + {adr=segt.sg_doff; len=segt.sg_data; + aoffset=segt.sg_code;offset=offset+aoffset;} + else {warning=2; outwar(); return;}} +} +else /* executable and overlay */ +{ + eof=segt.sg_atr & 0x0003; + if (eof==0) {warning=3; outwar(); return;} + if (eof==1) {adr=segt.sg_coff; len=segt.sg_code;} + if (eof==2) {adr=segt.sg_doff; len=segt.sg_data;} + if (eof==3) {if (segt.sg_coff==segt.sg_doff) + {adr=segt.sg_coff+segt.sg_doff; + len=segt.sg_code+segt.sg_data;} + else {if (segt.sg_coff0;pprogbuf++,peprombuf=peprombuf+zhl1,nbytes--) + *pprogbuf= *peprombuf;} + + + aoffset=segt.sg_code; + offset=boffset+aoffset; + adr=segt.sg_doff; len=segt.sg_data;} + else + {adr=segt.sg_doff; len=segt.sg_data; + aoffset=segt.sg_code; + offset=offset+aoffset; + sfile(); + bwarning=warning; beof=eof; + if (warning==false&&eof==false) + {lseek (fd,offset,0); + n_read=read (fd,peprombuf,nbytes); + if (n_read==0) + {eof=true; return;} + + switch (bre) + { + case 's': zhl1=1; break; + case 'h': zhl1=2; nbytes=nbytes/2; break; + case 'l': zhl1=2; nbytes=nbytes/2; peprombuf++; break; + } + for (;nbytes>0;pprogbuf++,peprombuf=peprombuf+zhl1,nbytes--) + *pprogbuf= *peprombuf;} + offset=boffset; + adr=segt.sg_coff; len=segt.sg_code;}} + } +} + sfile(); + if (eof==false&&warning==false) + {lseek (fd,offset,0); + n_read=read (fd,peprombuf,nbytes); + if (n_read==0) + {eof=true; return;} + + switch (bre) + { + case 's': zhl1=1; break; + case 'h': zhl1=2; nbytes=nbytes/2; break; + case 'l': zhl1=2; nbytes=nbytes/2; peprombuf++; break; + } + for (;nbytes>0;pprogbuf++,peprombuf=peprombuf+zhl1,nbytes--) + *pprogbuf= *peprombuf;} + + + if (bwarning==true&&warning==true) {warning=3; outwar(); return;} + if (beof==true&&eof==true) {eof=true; return;} + else eof=false; + +for (warning=3,pprogbuf=progbuf,beof=lange1;beof!=0;pprogbuf++,beof--) + {if (*pprogbuf!=0xff) {warning=0;break;}} +if (warning==3) {outwar(); return;} + +if (s_exec.s_magic==X_MAGIC1||s_exec.s_magic==X_MAGIC3||s_exec.s_magic==X_MAGIC4) + {if (bre=='l'||bre=='h') + {warning=4; outwar(); return;}} + else {if (bre=='s') + {warning=5; outwar(); return;}} + +} + + + /* bestimmung seek-adresse */ + +sfile() +{ + eof=false; warning=false; + adr=adr << 8; + if (begadrf=(adr+len)) + nbytes=len; + else nbytes=begadrf+langf-adr;}} + else + {if (begadrf>=(adr+len)) + eof=true; + else + {peprombuf= &eprombuf[0]; + pprogbuf= &progbuf[0]; + aoffset=begadrf; + offset=offset+aoffset; + aoffset=adr; + offset=offset-aoffset; + if ((begadrf+langf)>(adr+len)) + nbytes=adr+len-begadrf; + else nbytes=langf;}} +} + +/* prom to file + ------------ */ + +promfile() +{ +unsigned offs; + + if (next==false) { + fd1=open (namef,wmode); + cfd1=1; + if (fd1!= -1) {warning=6; outwar(); + if (warning==true) return;} + } + printf ("%s %s %s %s\n",fil,namee1,to,namef); + if (next==false) { + fd1=creat (namef,0755); + if (fd1== -1) {error=3; outerr(); return;} + s_exec.s_imsize=0; + segt.sg_code=0; + segt.sg_data=0; + segt.sg_atr=0; + s_exec.s_bss=0; + s_exec.s_segt=0x10; + s_exec.s_syms=0; + s_exec.s_entry=entryf & 0x0000ffff; + s_exec.s_flag=0x0001; + s_exec.s_codesz=0; + s_exec.s_lines=0; + + segt.sg_segno=segnr; + segt.sg_atr=0; + offs=begadrf; + offs=offs >> 8; + offset256=begadrf & 0xff00; + if ((begadrf & 0x00ff) > 0) {offs++; offset256=offset256+0x0100; + if (sect=='i') {warning=7; outwar();} + else {warning=8; outwar();}} + if (sect=='i') {segt.sg_coff=offs & 0x00ff; segt.sg_doff=0; + segt.sg_atr=segt.sg_atr | 0x0001; + if (bre=='s') s_exec.s_magic=X_MAGIC1; + else {if (kenns==0) s_exec.s_magic=N_MAGIC1; + else s_exec.s_magic=S_MAGIC1;}} + else {segt.sg_doff=offs & 0x00ff; segt.sg_coff=0; + segt.sg_atr=segt.sg_atr | 0x0002; + if (bre=='s') s_exec.s_magic=X_MAGIC3; + else {if (kenns==0) s_exec.s_magic=N_MAGIC3; + else s_exec.s_magic=S_MAGIC3;}} + if (begadrf>0) {if (sect=='i') segt.sg_atr=segt.sg_atr | 0x0010; + else segt.sg_atr=segt.sg_atr | 0x0020;} + segt.sg_boff=0; + segt.sg_bss=0; + segt.sg_unused=0; + + offset=40; + } +/* next prom */ + + nbytes=lange1; + begadre2=begadre1+begadre1; pprogbuf= &progbuf[0]; + switch (bre) + { + case 's': hoffset=prlang; zhl1=1; + for (zhl2=0;zhl2<0x4000;zhl2++) + eprombuf[zhl2]=0xff; + peprombuf= &eprombuf[begadre1]; + break; + case 'l': lange2=prlang; zhl1=2; + for (zhl2=0;zhl2<0x4000;zhl2++) + eprombuf[zhl2]=0xff; + peprombuf= &eprombuf[begadre2]; + peprombuf++; + break; + case 'h': zhl1=2; + peprombuf= &eprombuf[begadre2]; + if (lange2 > prlang) {hoffset=lange2; + prlang=lange2;} + else hoffset=prlang; + hoffset=hoffset+hoffset; + prlang=prlang+prlang; + break; + } + for (;nbytes>0;pprogbuf++,peprombuf=peprombuf+zhl1,nbytes--) + *peprombuf= *pprogbuf; + switch (bre) + { + case 's': break; + case 'l': bre='h'; return; + case 'h': bre='l'; begadrf=begadrf+prlang; break; + } + + lseek (fd1, offset, 0); + offset=offset + hoffset; + n_write=write (fd1,eprombuf,prlang); + if (n_write != prlang) {error=9; outerr(); return;} + + aoffset=prlang; + s_exec.s_imsize=s_exec.s_imsize + aoffset; + if (sect=='i') segt.sg_code=segt.sg_code + prlang; + else segt.sg_data=segt.sg_data + prlang; +} + +header_file() +{ + lseek (fd1, 0L, 0); + + nbytes=24; + n_write=write (fd1,&s_exec,nbytes); + if (n_write != nbytes) {error=9; outerr(); return;} + + nbytes=16; + n_write=write (fd1,&segt,nbytes); + if (n_write != nbytes) {error=9; outerr(); return;} + + close (fd1); +}