📄 objieee.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <dos.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "gen68.h"
#include "diag.h"
#include "lists.h"
#define DEBUG_VERSION 3.1
#define LDPERLINE 32
extern FILELIST *incfiles;
extern VIRTUAL_LIST *virtualFirst;
extern int prm_debug;
extern FILE *outputFile;
extern char version[];
extern char *infile;
extern EMIT_TAB segs[MAX_SEGS];
extern LIST *libincludes;
extern LINEBUF *linelist;
extern HASHREC **gsyms;
extern LIST *localfuncs, *localdata;
extern int prm_bss;
extern int outcode_base_address;
extern int anyusedfloat;
static int firstVirtualSeg;
static int segxlattab[MAX_SEGS];
static int dgroupVal;
static int extSize, extIndex, pubIndex;
static int checksum = 0;
static int options = 1; // signed addr
static int bitspermau = 8;
static int maus = 4;
static int bigendchar = 'M';
static char *segnames[] =
{
0, "code", "data", "bss", "const", "string", "cstartup", "crundown",
"cppinit", "cppexit", "codefix", "datafix", "lines", "types", "symbols",
"browse"
};
static char *segchars[] =
{
0, "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C"
};
static void emit_record(char *format, ...)
{
char buffer[256];
int i, l;
va_list ap;
va_start(ap, format);
vsprintf(buffer, format, ap);
l = strlen(buffer);
for (i = 0; i < l; i++)
if (buffer[i] > 31)
checksum += buffer[i];
va_end(ap);
oprintf(outputFile, "%s", buffer);
}
//-------------------------------------------------------------------------
static void emit_cs(int toclear)
{
if (toclear)
{
emit_record("CS.\r\n");
}
else
{
checksum += 'C';
checksum += 'S';
emit_record("CS%02X.\r\n", checksum &127);
}
checksum = 0;
}
//-------------------------------------------------------------------------
static void link_header(char *name)
{
struct date thedate;
struct time thetime;
char fpspec = 'I';
getdate(&thedate);
gettime(&thetime);
if (anyusedfloat)
fpspec = 'F';
emit_record("MB%cCC68K,%02X%s.\r\n", fpspec, strlen(name), name);
emit_record("CO104,08%08lX.\r\n", options);
emit_record("AD%x,%x,%c.\r\n", bitspermau, maus, bigendchar);
emit_record("DT%04d%02d%02d%02d%02d%02d.\r\n", thedate.da_year,
thedate.da_mon, thedate.da_day, thetime.ti_hour, thetime.ti_min,
thetime.ti_sec);
emit_record("CO101,07ENDHEAD.\r\n");
}
//-------------------------------------------------------------------------
static void link_trailer(void)
{
emit_record("ME.\r\n");
} void link_FileTime(char *file)
{
#ifdef XXXXX
unsigned short time, date;
char buf[256];
int fd;
*(short*)buf = 0xe900;
if (file)
{
if (_dos_open(file, 0, &fd))
{
time = 0;
date = 0;
}
else
{
_dos_getftime(fd, &date, &time);
_dos_close(fd);
}
*(short*)(buf + 2) = time;
*(short*)(buf + 4) = date;
memcpy(buf + 7, file, strlen(file));
buf[6] = strlen(file);
emit_record(COMENT, buf, 7+buf[6]);
}
else
emit_record(COMENT, buf, 2);
#endif
}
//-------------------------------------------------------------------------
void link_DebugMarker(void){}
void link_LibMod(void)
{
#ifdef XXXXX
if (libincludes)
{
while (libincludes)
{
char buf[256], *p;
p = strrchr(libincludes->data, '\\');
if (p)
p++;
else
p = libincludes->data;
buf[0] = 0xa3;
buf[1] = strlen(p);
strcpy(buf + 2, p);
emit_record(COMENT, buf, buf[1] + 2);
libincludes = libincludes->link;
}
}
#endif
}
//-------------------------------------------------------------------------
void link_Segs(void)
{
char buf[512];
int i;
VIRTUAL_LIST *v = virtualFirst;
firstVirtualSeg = 1;
for (i = 1; i < MAX_SEGS; i++)
{
if (segxlattab[i])
{
emit_record("ST%X,%s,%02X%s.\r\n", segxlattab[i], segchars[i],
strlen(segnames[i]), segnames[i]);
emit_record("SA%X,%x.\r\n", segxlattab[i], 4);
emit_record("ASS%X,%lX.\r\n", segxlattab[i], segs[i].curlast);
firstVirtualSeg++;
}
}
i = firstVirtualSeg;
while (v)
{
v->sp->value.i = i - firstVirtualSeg;
putsym(buf + 1, v->sp, v->sp->name);
buf[0] = '@';
emit_record("ST%X,%s,E,%02X%s.\r\n", i, v->data ? segchars[dataseg]:
segchars[codeseg], strlen(buf), buf);
emit_record("SA%X,%x.\r\n", i, 4);
emit_record("ASS%X,%lX.\r\n", i++, v->seg->curlast);
v = v->next;
}
}
//-------------------------------------------------------------------------
void link_putext(SYM *sp)
{
char buf[512];
putsym(buf, sp, sp->name);
sp->value.i = extIndex++;
emit_record("NX%X,%02X%s.\r\n", sp->value.i, strlen(buf), buf);
#ifdef XXXXX
if (prm_debug)
if (r->datatype &TY_TYPE)
emit_record("ATX%X,T%lX.\r\n", r->id, r->datatype &~TY_TYPE);
else
if (r->datatype &TY_NAME)
emit_record("ATX%X,I%lX.\r\n", r->id, r->datatype &~TY_NAME)
;
else
emit_record("ATX%X,%lX.\r\n", r->id, r->datatype);
q = q->link;
}
#endif
}
//-------------------------------------------------------------------------
void link_ExtDefs(void)
{
int i;
SYM *sp;
LIST *lf = localfuncs;
extIndex = 1;
extSize = 0;
for (i = 0; i < HASHTABLESIZE; i++)
{
if ((sp = (SYM*)gsyms[i]) != 0)
{
while (sp)
{
if (sp->storage_class == sc_externalfunc && sp->mainsym
->extflag && !(sp->tp->cflags &DF_INTRINS))
{
link_putext(sp);
}
if (sp->storage_class == sc_external && sp->mainsym->extflag)
{
link_putext(sp);
}
if (sp->storage_class == sc_defunc)
{
SYM *sp1 = sp->tp->lst.head;
while (sp1)
{
if (sp1->storage_class == sc_externalfunc && sp1
->mainsym->extflag && !(sp1->tp->cflags &DF_INTRINS)
)
{
link_putext(sp1);
}
sp1 = sp1->next;
}
}
sp = sp->next;
}
}
}
while (lf)
{
sp = lf->data;
if (sp->storage_class == sc_externalfunc && sp->mainsym->extflag && !
(sp->tp->cflags &DF_INTRINS))
{
link_putext(sp);
}
lf = lf->link;
}
lf = localdata;
while (lf)
{
sp = lf->data;
if (sp->mainsym->extflag)
link_putext(sp);
lf = lf->link;
}
}
//-------------------------------------------------------------------------
void link_putimport(SYM *sp)
{
#ifdef XXXXX
char buf[512], obuf[512];
int l, l1;
putsym(buf, sp, sp->name);
l = strlen(buf);
*(short*)obuf = 0xa000;
obuf[2] = 1; // import
obuf[3] = 0; // import by name
obuf[4] = l;
strcpy(obuf + 5, buf);
obuf[5+l] = l1 = strlen(sp->importfile);
strcpy(obuf + 6+l, sp->importfile);
obuf[6+l + l1] = l;
strcpy(obuf + 7+l + l1, buf);
emit_record(COMENT, obuf, 7+2 * l + l1);
#endif
}
//-------------------------------------------------------------------------
void link_Imports(void)
{
SYM *sp;
int i;
for (i = 0; i < HASHTABLESIZE; i++)
{
if ((sp = (SYM*)gsyms[i]) != 0)
{
while (sp)
{
if (sp->mainsym->importable && sp->importfile)
{
link_putimport(sp);
}
sp = sp->next;
}
}
}
}
//-------------------------------------------------------------------------
int link_getseg(SYM *sp)
{
if (!sp->tp)
return dataseg;
switch (sp->storage_class)
{
case sc_member:
if (sp->value.classdata.gdeclare)
sp = sp->value.classdata.gdeclare;
else
if (sp->tp->type != bt_func && sp->tp->type != bt_ifunc)
DIAG("link_getseg - no static member initializer");
// fall through
case sc_static:
case sc_global:
if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
if (sp->gennedvirtfunc)
return sp->value.i + firstVirtualSeg;
else
return codeseg;
/* fall through */
case sc_external:
if (sp->tp->cflags &DF_CONST)
return constseg;
else
if (sp->init || !prm_bss)
return dataseg;
else
return bssxseg;
case sc_externalfunc:
case sc_label:
if (sp->gennedvirtfunc)
return sp->value.i + firstVirtualSeg;
else
return codeseg;
case sc_type:
if (!strncmp(sp->name, "@$xt", 4))
{
return sp->value.i;
}
default:
DIAG("Unknown segment type in link_GetSeg");
return codeseg;
}
// also fix the value.i field of local funcs...
}
//-------------------------------------------------------------------------
void link_putpub(SYM *sp)
{
char buf[512], obuf[512];
int seg, group, pos;
if (sp->mainsym->gennedvirtfunc)
return ;
if (sp->value.classdata.templatedata)
return ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -