Category : C Source Code
Archive   : TCROM2.ZIP
Filename : ROMIZE.C

 
Output of file : ROMIZE.C contained in archive : TCROM2.ZIP

#include
#include
#include

#define sym_tab_size 500
#define ntokens 20 /* max tokens per line */
#define tokensep "\t :+-,[]\n"

#define true 1
#define false 0
#define mybuffsize 4096

/* this program can be compiled in small model */

/* Schema for converting Turbo C assembly output to ROMable code:

Pass 1: build a table of symbols in _DATA segment

(omit "_TEXT" and "_BSS" segment symbols)

Pass 2:
a. Change the "DGROUP" group command to just "_BSS"
b. Add a "CGROUP" with _TEXT,_DATA
c. Change the assume to "assume cs:CGROUP,ds:DGROUP"

d: change group reference for any symbol in "_DATA" segment
from "DGROUP" to "CGROUP"
add a "CGROUP:" reference if none exists

e: change associated ds reference to cs
1. a "mov" before
2. a "push ds" before or after

1/16/89 Updated by the author for Turbo C 2.0

*/

struct sym_table_entry {
char symbol[32];
};

struct sym_table_entry sym_table[sym_tab_size];

int no_symbols;

char ibuff[mybuffsize];
char obuff[mybuffsize];

FILE *asmsource;
FILE *output;


char prev_line[255];
char next_line[255];
char curr_line[255];

/* insert text *c at *r in a string *p
assumes there is enough room to do the insertion */

void strins(char *p,char *r,char *c)
{
int i,m,n;
char work[255];
m = r - p; /* # chars in 1st part of *p */
strcpy(work,p); /* work = all of *p */
work[m] = 0; /* trunc to length up to *r */
strcat(work,c); /* append *c */
strcat(work,r); /* append rest of *p */
strcpy(p,work); /* move back to p *p */
/* printf("strins --%s",p); */
}

struct sym_table_entry *search_sym(char *sym)
{
struct sym_table_entry *p;
int i;

p = sym_table; i = 0;
while ((i < no_symbols) && strcmp((char*)p,sym)) {
p++;
i++;
}
if (i == no_symbols) return (NULL);
else return (p);
}

/* search the line for an occurrence of any symbol in table */

char *sym_in_line(char *theline)
{
int i;
char *p;
i = 0;
while ((i < no_symbols) && (!(p = strstr(theline,sym_table[i].symbol))))
i++;
if (i < no_symbols) return (p);
else return (NULL);
}

void list_symbols(void)
{
int i;
for (i = 0; i < no_symbols; i++)
printf("%s\n",sym_table[i].symbol);
}

void add_symbol(char *sym)
{
/* printf("%s symbol to add\n",sym); */
strcpy(sym_table[no_symbols++].symbol,sym);
}

/* Pass1 -- Read through the text and accumulate a table of
symbols in the _DATA segment -- returns # lines input */

int pass1(void)
{
int i;
int linect;
char *s[ntokens];
char dataseg; /* boolean == in _DATA segment */
char cursegname[20];

no_symbols = 0;
linect = 0;

cursegname[0] = 0; /* no current segment */
dataseg = false;

while (!feof(asmsource)) {
fgets(curr_line,sizeof(curr_line),asmsource);
linect++;

/* printf("%s",curr_line); */
i = 0;
s[i] = strtok(curr_line,tokensep);
while (s[i]) {
/* printf("%s||",s[i]); */
s[++i] = strtok(NULL,tokensep);
}
if (!i) continue; /* 0 - length line */
if (s[0] == ";") continue; /* comment, ignore */
/* printf(" %d tokens\n",i); */
if (i > 1) {
if (!strcmp(s[1],"segment")) {
if (!strcmp(s[0],"_DATA")) {
dataseg = true;
/* printf("Begin _DATA segment \n"); */
}
strcpy(cursegname,s[0]);
continue;
}
}
if (!strcmp(s[1],"ends") && !strcmp(s[0],"_DATA")) {
dataseg = false;
/* printf("End _DATA segment \n"); */
cursegname[0] = 0; /* no current segment */
continue;
}
if (dataseg && !strcmp(s[1],"label")) {
add_symbol(s[0]);
continue;
}
/* extrn not in any segment */
if (!strcmp(s[0],"extrn") && !cursegname[0]) {
add_symbol(s[1]);
continue;
}

} /* while not eof */
list_symbols();
return (linect);
}

/* Pass 2 processing - see above -- returns # lines output */

int pass2(void)
{
int i,j, linect;
struct sym_table_entry *s;
char *t[ntokens];
char *tt[ntokens];
char *r,*u;

char linebuff[255];
char linebuff2[255];

prev_line[0] = 0; /* clear prev_line */

/* Fill the pipeline */
fgets(prev_line,sizeof(prev_line),asmsource);
fgets(curr_line,sizeof(curr_line),asmsource);
fgets(next_line,sizeof(next_line),asmsource);
linect = 0;

do {
/* printf("%s",curr_line); */
i = 0; /* get tokens */
strcpy(linebuff,curr_line);
t[i] = strtok(linebuff,tokensep);
while (t[i]) {
/* printf("%t||",t[i]); */
t[++i] = strtok(NULL,tokensep);
}
if (!strcmp(t[0],"assume")) {
/* substutite new assume statement */
strcpy(curr_line,"\tassume\tcs:CGROUP,ds:DGROUP\n");

/* printf("assume cs:CGROUP,ds:DGROUP\n"); */
}
else if (!strcmp(t[1],"group")) {
strcpy(curr_line,"DGROUP\tgroup\t_BSS\n");
/* insert a CGROUP line */
fputs(prev_line,output);
linect++;
strcpy(prev_line,curr_line);
strcpy(curr_line,"CGROUP\tgroup\t_TEXT,_DATA\n");
linect++;

/* printf("DGROUP\tgroup\t_BSS\n");
printf("CGROUP\tgroup\t_TEXT,_DATA\n"); */

}
else if (!strcmp(t[0],"extrn"));
else if (!strcmp(t[0],"public"));
else if (!strcmp(t[1],"label"));

else if (r = sym_in_line(curr_line)) { /* symbol found in line */
if (u = strstr(curr_line,"DGROUP:")) { /* "DGROUP" found */
*u = 'C'; /* change to CGROUP: */

/* following three lines added for v 2.0. A "dd" statement has
two "DGROUP" references in it */

if (!strcmp(t[0],"dd") && (u = strstr(curr_line,"DGROUP:"))) {
*u = 'C'; /* change to CGROUP: */
}
}
else { /* no group found, insert "CGROUP: in line before symbol */
strins(curr_line,r,"CGROUP:");
}

/* now check for previous line with ds reference */
/* tokenize previous line */

strcpy(linebuff,prev_line);
i = 0;
tt[i] = strtok(linebuff,tokensep);
while (tt[i]) tt[++i] = strtok(NULL,tokensep);
/* see if "ds" present */
i = 0;
while (tt[i] && strcmp(tt[i],"ds")) i++;
if (tt[i]) { /* "ds" found, change to "cs" */
*(prev_line + (tt[i] - linebuff)) = 'c';
/* printf("Previous line %s",prev_line); */
}
else { /* not on previous line, check next line */
strcpy(linebuff,next_line);
i = 0;
tt[i] = strtok(linebuff,tokensep);
while (tt[i]) tt[++i] = strtok(NULL,tokensep);
i = 0;
while (tt[i] && strcmp(tt[i],"ds")) i++;
if (tt[i]) { /* ds found in next line */
*(next_line + (tt[i] - linebuff)) = 'c';
/* printf("Following line %s",next_line); */
}

}

} /* if symbol found in line */

fputs(prev_line,output);
linect++;
strcpy(prev_line,curr_line);
strcpy(curr_line,next_line);
fgets(next_line,sizeof(next_line),asmsource);
} while (!feof(asmsource));
/* empty the pipeline */
fputs(prev_line,output);
fputs(curr_line,output);
linect += 2;
return (linect);
}


int main(int argc, char *argv[])
{
int l;

if (argc < 3) {
printf("Usage: romize input.asm output.asm \n");
return (1);
}

asmsource = fopen(argv[1],"rt");
if (!asmsource) {
printf("Trouble opening input file\n");
return(1);
}
setvbuf(asmsource,ibuff,_IOFBF,mybuffsize);
l = pass1();
fclose(asmsource);
printf("%d Lines input\n",l);

asmsource = fopen(argv[1],"rt");
setvbuf(asmsource,ibuff,_IOFBF,mybuffsize);
output = fopen(argv[2],"wt");
if (!output) {
printf("Trouble opening output\n");
fclose(asmsource);
return(1);
}
setvbuf(output,obuff,_IOFBF,mybuffsize);

l = pass2();
fclose(asmsource);

fclose(output);
printf("%d Lines output\n",l);
return(0);
}