kolibrios-gitea/programs/develop/cmm/outobj.cpp

386 lines
12 KiB
C++
Raw Normal View History

#include "tok.h"
void obj_outrecord(int recordtype,unsigned int recordlength,unsigned char *data);
void outeachPUBDEF(struct idrec *ptr);
void obj_outLEDATA(unsigned int segm,unsigned int offset,unsigned int recordlength,
unsigned char *data);
#define MAXNUMEXTNAME 1024;
int *numextname;
int maxnumextname=MAXNUMEXTNAME;
unsigned int lenextstr=0; //<2F><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><E8ADA8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int numextern=0;
int postseg,stackseg;
unsigned int findextname(int extnum)
{
for(unsigned int i=0;i<externnum;i++){
if(numextname[i]==extnum)return i+1;
}
return 0;
}
int MakeObj()
{
unsigned int i;
unsigned int count,sizeblock;
hout=CreateOutPut("obj","wb");
i=strlen(startfileinfo->filename);
string2[0]=(unsigned char)i;
strcpy((char *)&string2[1],startfileinfo->filename);
obj_outrecord(0x80,i+1,&string2[0]);// output the LNAMES
sprintf((char *)&string2[3],"%s %s",compilerstr,__DATE__);
i=strlen((char *)&string2[3]);
*(short *)&string2[0]=0;
string2[2]=(unsigned char)i;
obj_outrecord(0x88,i+3,&string2[0]);// output the LNAMES
for(count=0;count<totalmodule;count++){ //<2F><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E7A0A5><EFBFBD><><E4A0A9><EFBFBD>
*(struct ftime *)&string2[2]=(startfileinfo+count)->time;
strcpy((char *)&string2[7],(startfileinfo+count)->filename);
i=strlen((startfileinfo+count)->filename);
*(short *)&string2[0]=0xE940;
string2[6]=(unsigned char)i;
obj_outrecord(0x88,i+7,&string2[0]);// output the LNAMES
}
count=outptr-startptr; //ࠧ<><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD>
unsigned char *data=output+startptr; //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*(short *)&string2[0]=0xE940;
obj_outrecord(0x88,2,&string2[0]);//<2F><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(!am32){
*(short *)&string2[0]=0xEA00;
string2[2]=1;
string2[3]=(unsigned char)(modelmem==SMALL?9:8);
obj_outrecord(0x88,4,&string2[0]);
}
else{
*(short *)&string2[0]=0xA140;
obj_outrecord(0x88,2,&string2[0]);
}
obj_outrecord(0x96,39,(unsigned char *)"\000\005_TEXT\004CODE\004_BSS\003BSS\006DGROUP\005_DATA\004DATA");
// output the SEGDEF
if(!am32){
string2[0]=(unsigned char)0x28;
*(short *)&string2[1]=(short)outptr;//count;// Set the length of the segment of DATA or CODE
string2[3]=0x02; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> _TEXT
*(short *)&string2[4]=0x0103; //<2F><><EFBFBD><EFBFBD><EFBFBD> CODE Overlay NONE 1
obj_outrecord(0x98,6,string2);
i=2;
if(comfile==file_exe&&modelmem==SMALL){
string2[0]=(unsigned char)0x48;
*(short *)&string2[1]=outptrdata;// Set the length of the segment DATA
string2[3]=0x07; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> _DATA
*(short *)&string2[4]=0x0108; //<2F><><EFBFBD><EFBFBD><EFBFBD> DATA Overlay NONE
obj_outrecord(0x98,6,string2);
i++;
}
postseg=i;
string2[0]=(unsigned char)0x48;
*(short *)&string2[1]=(short)postsize;// Set the length of the segment BSS
string2[3]=0x04; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> _BSS
*(short *)&string2[4]=0x0105; //<2F><><EFBFBD><EFBFBD><EFBFBD> BSS Overlay NONE
obj_outrecord(0x98,6,string2);
i++;
if(comfile==file_exe&&modelmem==SMALL){
obj_outrecord(0x96,6,(unsigned char *)"\005STACK");
string2[0]=0x74;
*(short *)&string2[1]=(short)stacksize;// Set the length of the segment STACK
string2[3]=0x09; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> STACK
*(short *)&string2[4]=0x0109; //<2F><><EFBFBD><EFBFBD><EFBFBD> STACK Overlay NONE
obj_outrecord(0x98,6,string2);
stackseg=i;
}
string2[0]=6; //<2F><><EFBFBD> DGROUP
if(comfile==file_exe&&modelmem==SMALL){
*(short *)&string2[1]=0x2FF;
*(short *)&string2[3]=0x3FF;//postseg*256+255;//0x3FF;
*(short *)&string2[5]=0x4ff;//stackseg*256+255;//0x4FF;
i=7;
}
else{
*(short *)&string2[1]=0x1FF;
// *(short *)&string2[3]=0x2FF;
*(short *)&string2[3]=0x2ff;//postseg*256+255;//0x3FF;
i=5;
}
obj_outrecord(0x9A,i,string2);
}
else{
string2[0]=(unsigned char)0xA9;
*(long *)&string2[1]=(long)outptr;//count;// Set the length of the segment of DATA or CODE
string2[5]=0x02; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> _TEXT
*(short *)&string2[6]=0x0103; //<2F><><EFBFBD><EFBFBD><EFBFBD> CODE Overlay NONE
obj_outrecord(0x99,8,string2);
i=2;
/*
string2[0]=(unsigned char)0xA9;
*(long *)&string2[1]=0;// Set the length of the segment DATA
string2[5]=0x07; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> _DATA
*(short *)&string2[6]=0x0108; //<2F><><EFBFBD><EFBFBD><EFBFBD> DATA Overlay NONE
obj_outrecord(0x99,8,string2);
i++;*/
postseg=i;
string2[0]=(unsigned char)0xA9;
*(long *)&string2[1]=(long)postsize;// Set the length of the segment BSS
string2[5]=0x04; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> _BSS
*(short *)&string2[6]=0x0105; //<2F><><EFBFBD><EFBFBD><EFBFBD> BSS Overlay NONE
obj_outrecord(0x99,8,string2);
i++;
obj_outrecord(0x96,11,(unsigned char *)"\005STACK\004FLAT");//9,10
if(comfile!=file_w32){
string2[0]=0x75;
*(long *)&string2[1]=(long)stacksize;// Set the length of the segment STACK
string2[5]=0x09; //<2F><><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD> STACK
*(short *)&string2[6]=0x0109; //<2F><><EFBFBD><EFBFBD><EFBFBD> STACK Overlay NONE
obj_outrecord(0x99,8,string2);
stackseg=i;
}
string2[0]=10;
obj_outrecord(0x9A,1,string2); //GRPDEF Group: FLAT
string2[0]=6; //<2F><><EFBFBD> DGROUP
i=1;
// *(short *)&string2[i]=0x2FF; //DATA
// i+=2;
*(short *)&string2[i]=postseg*256+255;//0x3FF; //BSS
i+=2;
if(comfile!=file_w32){
*(short *)&string2[i]=stackseg*256+255;//0x4FF
i+=2;
}
obj_outrecord(0x9A,i,string2);
}
// <20><EFBFBD> EXTDEF
while(externnum>maxnumextname)maxnumextname+=MAXNUMEXTNAME;
numextname=(int *)MALLOC(maxnumextname*sizeof(int));
// output the PUBDEF records for each exteral procedures (all procedures)
outeachPUBDEF(treestart);
if(lenextstr!=0)obj_outrecord(0x8c,lenextstr,&string[0]);
// output the data (LEDATA) in 1K chunks as required!
i=0;
char *bufobj=(char *)MALLOC(512*5);
while(i<count){
unsigned int j;
sizeblock=1024;
restart:
for(j=0;j<posts;j++){
if((postbuf+j)->type>=CALL_EXT&&(postbuf+j)->type<=FIX_CODE32&&
(postbuf+j)->loc>=(i+startptr)&&(postbuf+j)->loc<(i+sizeblock+startptr)){
if((postbuf+j)->loc>(i+startptr+sizeblock-(am32==FALSE?2:4))){
sizeblock=(postbuf+j)->loc-i-startptr;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
goto restart;
}
}
}
if((i+sizeblock)>count)sizeblock=count-i;
obj_outLEDATA(1,i+startptr,sizeblock,data+i);
int ofsfix=0;
for(j=0;j<posts;j++){
if((postbuf+j)->loc>=(i+startptr)&&(postbuf+j)->loc<(i+sizeblock+startptr)){
int hold=(postbuf+j)->loc-i-startptr;
if((postbuf+j)->type>=CALL_32I/*POST_VAR*/&&(postbuf+j)->type<=FIX_CODE32){
bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0xC4:0xE4)|(hold/256));
bufobj[ofsfix++]=(unsigned char)(hold%256);
bufobj[ofsfix++]=0x14;
bufobj[ofsfix++]=1;
switch((postbuf+j)->type){
case POST_VAR:
case POST_VAR32:
bufobj[ofsfix++]=postseg;
break;
case FIX_VAR:
case FIX_VAR32:
bufobj[ofsfix++]=(unsigned char)((comfile==file_exe&&modelmem==SMALL)?2:1);
break;
case FIX_CODE:
case FIX_CODE32:
bufobj[ofsfix++]=1;
break;
}
}
if((postbuf+j)->type>=POST_VAR32&&(postbuf+j)->type<=FIX_CODE32){
}
else if((postbuf+j)->type==CALL_EXT){
int numext=findextname((postbuf+j)->num);
if(numext!=0){
bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0x84:0xA4)|(hold/256));
bufobj[ofsfix++]=(unsigned char)(hold%256);
bufobj[ofsfix++]=0x56;
bufobj[ofsfix++]=(unsigned char)numext;
}
}
else if((postbuf+j)->type==EXT_VAR){
int numext=findextname((postbuf+j)->num);
if(numext!=0){
bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0xC4:0xE4)|(hold/256));
bufobj[ofsfix++]=(unsigned char)(hold%256);
bufobj[ofsfix++]=0x16;
bufobj[ofsfix++]=1;
bufobj[ofsfix++]=(unsigned char)numext;
}
}
}
}
if(ofsfix!=0)obj_outrecord(0x9C+am32,ofsfix,(unsigned char *)bufobj);
i+=sizeblock;
}
free(bufobj);
if(comfile==file_exe&&modelmem==SMALL){
i=0;
while(i<outptrdata){
if((i+1024)>outptrdata)obj_outLEDATA(2,i,outptrdata-i,outputdata+i);
else obj_outLEDATA(2,i,1024,outputdata+i);
i+=1024;
}
}
if(sobj!=FALSE){
// output end of OBJ notifier
string2[0]=0;
i=1;
}
else{
count=EntryPoint();
*(short *)&string2[0]=0xC1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2AEA2> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
*(short *)&string2[2]=0x101;
if(count<65536){
*(short *)&string2[4]=(short)count;
i=6;
}
else{
*(long *)&string2[4]=(long)count;
i=8;
}
}
obj_outrecord(i==8?0x8B:0x8A,i,string2);
free(numextname);
runfilesize=ftell(hout);
fclose(hout);
hout=NULL;
return 0;
}
void obj_outLEDATA(unsigned int segm,unsigned int offset,unsigned int recordlength,unsigned char *data)
{
int checksum=0;
int i;
unsigned char buf[8];
buf[3]=(unsigned char)segm;
if(offset>(65536-1024)){
*(short *)&buf[1]=(short)(recordlength+6);
buf[0]=0xA1;
*(long *)&buf[4]=(long)offset;
i=8;
}
else{
*(short *)&buf[1]=(short)(recordlength+4);
buf[0]=0xA0;
*(short *)&buf[4]=(short)offset;
i=6;
}
fwrite(buf,i,1,hout);
for(i--;i>=0;i--)checksum+=buf[i];
for(i=0;(unsigned int)i<recordlength;i++)checksum+=data[i];
fwrite(data,recordlength,1,hout);
checksum=-checksum;
fwrite(&checksum,1,1,hout);
}
void obj_outrecord(int recordtype,unsigned int recordlength,unsigned char *data)
// Outputs an OBJ record.
{
int checksum;
unsigned int i;
recordlength++;
checksum=recordtype;
fwrite(&recordtype,1,1,hout);
checksum+=(recordlength/256);
checksum+=(recordlength&255);
fwrite(&recordlength,2,1,hout);
recordlength--;
for(i=0;i<recordlength;i++)checksum+=data[i];
fwrite(data,recordlength,1,hout);
checksum=-checksum;
fwrite(&checksum,1,1,hout);
}
void outeachPUBDEF(struct idrec *ptr)
{
unsigned int i;
if(ptr!=NULL){
outeachPUBDEF(ptr->right);
if(ptr->rectok==tk_apiproc){
i=0;
for(unsigned int j=0;j<posts;j++){ //<2F><><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EFBFBD><ECA7AE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E6A5A4><EFBFBD>
if((postbuf+j)->num==(unsigned long)ptr->recnumber&&((postbuf+j)->type==CALL_32I||(postbuf+j)->type==CALL_32)){
i++;
(postbuf+j)->type=CALL_EXT;
externnum++;
if(externnum>=maxnumextname){
maxnumextname+=MAXNUMEXTNAME;
numextname=(int *)REALLOC(numextname,maxnumextname*sizeof(int));
}
}
}
if(i)goto nameext;
goto endp;
}
if(externnum!=0&&ptr->rectok==tk_undefproc&&(ptr->flag&f_extern)!=0){
nameext:
numextname[numextern++]=ptr->recnumber;
i=strlen(ptr->recid);
if((lenextstr+i+2)>=STRLEN){
obj_outrecord(0x8c,lenextstr,&string[0]);
lenextstr=0;
}
string[lenextstr++]=(unsigned char)i;
strcpy((char *)&string[lenextstr],ptr->recid);
lenextstr+=i+1;
}
else{
if((ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)&&ptr->recsegm>=NOT_DYNAMIC){
string2[0]=(unsigned char)(am32==0?0:1);
string2[1]=0x01;
}
else if((ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar)||ptr->rectok==tk_structvar){
if((ptr->flag&f_extern))goto nameext;
if(am32){
string2[0]=1;
string2[1]=(unsigned char)(ptr->recpost==0?1:postseg);
}
else if(comfile==file_exe&&modelmem==SMALL){
string2[0]=1;
string2[1]=(unsigned char)(ptr->recpost==0?2:postseg);
}
else{
string2[0]=(unsigned char)(ptr->recpost==0?0:1);
string2[1]=(unsigned char)(ptr->recpost==0?1:postseg);
}
}
else goto endp;
for(i=0;ptr->recid[i]!=0;i++)string2[i+3]=ptr->recid[i];
string2[2]=(unsigned char)i;
if(ptr->recnumber<65536){
*(short *)&string2[i+3]=(short)ptr->recnumber;
string2[i+5]=0x00;
obj_outrecord(0x90,i+6,&string2[0]);
}
else{
*(long *)&string2[i+3]=(long)ptr->recnumber;
string2[i+7]=0x00;
obj_outrecord(0x91,i+8,&string2[0]);
}
}
endp:
outeachPUBDEF(ptr->left);
}
}