+ ANSI C conversion
This commit is contained in:
parent
0df5d2f50b
commit
75909230c9
403
util/ass/ass00.c
403
util/ass/ass00.c
|
@ -1,5 +1,10 @@
|
|||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "assci.h"
|
||||
#include "asscm.h"
|
||||
#include "assrl.h"
|
||||
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
|
@ -7,17 +12,34 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
char oflag;
|
||||
static int memflg;
|
||||
|
||||
/* Forward declarations. */
|
||||
static siz_t* getsizes(char *);
|
||||
static void getcore(void);
|
||||
static void argument(char *);
|
||||
static void flags(char *);
|
||||
static void skipentry(void);
|
||||
static void enmd_pro(void);
|
||||
static void enmd_glo(void);
|
||||
static void archive(void);
|
||||
static void finish_up(void);
|
||||
static void check_def(void);
|
||||
|
||||
static void c_print(void);
|
||||
static void c_dprint(char *, char*);
|
||||
|
||||
/* External definitions */
|
||||
void pass_3(void);
|
||||
void pass_4(void);
|
||||
void pass_5(void);
|
||||
|
||||
/*
|
||||
** Main routine of EM1-assembler/loader
|
||||
*/
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
* Usage: ass [-[d][p][m][u][U]] [-s(s/m/l/x)] [ [file] [flag] ] ...
|
||||
|
@ -29,10 +51,14 @@ main(argc, argv)
|
|||
register int argno;
|
||||
|
||||
progname = argv[0];
|
||||
for ( cp=argv[0] ; *cp ; ) if ( *cp++ == '/' ) progname= cp;
|
||||
for ( argno=1 ; argno<argc ; argno++ ) {
|
||||
if ( argv[argno][0] == '-' && LC(argv[argno][1]) == 's') {
|
||||
getsizes(&argv[argno][2]);
|
||||
for (cp = argv[0]; *cp;)
|
||||
if (*cp++ == '/')
|
||||
progname = cp;
|
||||
for (argno = 1; argno < argc; argno++)
|
||||
{
|
||||
if (argv[argno][0] == '-' && LC(argv[argno][1]) == 's')
|
||||
{
|
||||
oursize = getsizes(&argv[argno][2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +74,8 @@ main(argc, argv)
|
|||
exit(nerrors != 0);
|
||||
}
|
||||
|
||||
getcore() {
|
||||
static void getcore(void)
|
||||
{
|
||||
register siz_t *p;
|
||||
siz_t bytes;
|
||||
register unsigned n;
|
||||
|
@ -58,125 +85,177 @@ getcore() {
|
|||
* xglobs[] should be located in front of mglobs[], see upd_reloc()
|
||||
*/
|
||||
|
||||
p = oursize; n = 0;
|
||||
p = oursize;
|
||||
n = 0;
|
||||
n += (bytes.n_glab = p->n_glab * (sizeof *xglobs));
|
||||
n += (bytes.n_mlab = p->n_mlab * (sizeof *mglobs));
|
||||
n += (bytes.n_mproc = p->n_mproc * (sizeof *mprocs));
|
||||
n += (bytes.n_xproc = p->n_xproc * (sizeof *xprocs));
|
||||
n += (bytes.n_proc = p->n_proc * (sizeof *proctab));
|
||||
base = getarea(n);
|
||||
zero(base,n);
|
||||
xglobs = gbp_cast base; base += bytes.n_glab;
|
||||
mglobs = gbp_cast base; base += bytes.n_mlab;
|
||||
mprocs = prp_cast base; base += bytes.n_mproc;
|
||||
xprocs = prp_cast base; base += bytes.n_xproc;
|
||||
proctab = ptp_cast base; base += bytes.n_proc;
|
||||
memset(base, 0, n);
|
||||
xglobs = gbp_cast base;
|
||||
base += bytes.n_glab;
|
||||
mglobs = gbp_cast base;
|
||||
base += bytes.n_mlab;
|
||||
mprocs = prp_cast base;
|
||||
base += bytes.n_mproc;
|
||||
xprocs = prp_cast base;
|
||||
base += bytes.n_xproc;
|
||||
proctab = ptp_cast base;
|
||||
base += bytes.n_proc;
|
||||
}
|
||||
|
||||
getsizes(str) char *str; {
|
||||
|
||||
static siz_t* getsizes(char *str)
|
||||
{
|
||||
/*
|
||||
* accepts -ss (small), -sm (medium), -sl (large), -sx (extra large)
|
||||
*/
|
||||
|
||||
switch(LC(*str)) {
|
||||
default:error("bad size option %s",str);
|
||||
case 's': oursize = &sizes[0]; break;
|
||||
case 'm': oursize = &sizes[1]; break;
|
||||
case 'l': oursize = &sizes[2]; break;
|
||||
case 'x': oursize = &sizes[3]; break;
|
||||
switch (LC(*str))
|
||||
{
|
||||
default:
|
||||
error("bad size option %s", str);
|
||||
case 's':
|
||||
return &sizes[0];
|
||||
break;
|
||||
case 'm':
|
||||
return &sizes[1];
|
||||
break;
|
||||
case 'l':
|
||||
return &sizes[2];
|
||||
break;
|
||||
case 'x':
|
||||
return &sizes[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char oflag;
|
||||
|
||||
argument(arg) char *arg; {
|
||||
register w;
|
||||
|
||||
/*
|
||||
* This routine decides what to do with each argument.
|
||||
* It recognises flags and modules.
|
||||
* Furthermore, it knows a library when it sees it and
|
||||
* call archive() to split it apart.
|
||||
*/
|
||||
static void argument(char *arg)
|
||||
{
|
||||
register int w;
|
||||
|
||||
if (oflag) {
|
||||
if (oflag)
|
||||
{
|
||||
eout = arg;
|
||||
oflag = 0;
|
||||
return;
|
||||
}
|
||||
if(*arg == '-') {
|
||||
if (*arg == '-')
|
||||
{
|
||||
flags(arg);
|
||||
return;
|
||||
}
|
||||
curfile = arg; /* for error messages etc. */
|
||||
if ((ifile = fopen(arg,"r")) == 0) {
|
||||
if ((ifile = fopen(arg, "r")) == NULL)
|
||||
{
|
||||
error("can't open %s", arg);
|
||||
return;
|
||||
}
|
||||
inpoff = 2;
|
||||
if ((w = getu16()) == sp_magic)
|
||||
read_compact();
|
||||
else if (w == ARMAG || w == AALMAG) {
|
||||
else if (w == ARMAG || w == AALMAG)
|
||||
{
|
||||
archmode = TRUE;
|
||||
archive();
|
||||
archmode = FALSE;
|
||||
} else
|
||||
}
|
||||
else
|
||||
error("%s: bad format", arg);
|
||||
if (fclose(ifile) == EOF)
|
||||
;
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** process flag arguments
|
||||
*/
|
||||
|
||||
static int memflg ;
|
||||
|
||||
flags(arg)
|
||||
char *arg;
|
||||
static void flags(char *arg)
|
||||
{
|
||||
register char *argp;
|
||||
register on;
|
||||
register int on;
|
||||
|
||||
argp = arg;
|
||||
while (*++argp)
|
||||
{
|
||||
switch (LC(*argp))
|
||||
{
|
||||
case 'd': d_flag++;break;
|
||||
case 'r': r_flag++;break;
|
||||
case 's': return ; /* s-flag is already scanned */
|
||||
case 'd':
|
||||
d_flag++;
|
||||
break;
|
||||
case 'r':
|
||||
r_flag++;
|
||||
break;
|
||||
case 's':
|
||||
return; /* s-flag is already scanned */
|
||||
#ifdef MEMUSE
|
||||
case 'm': memflg++ ; break ;
|
||||
case 'm':
|
||||
memflg++;
|
||||
break;
|
||||
#endif
|
||||
case 'p': ++procflag;break;
|
||||
case 'p':
|
||||
++procflag;
|
||||
break;
|
||||
#ifdef DUMP
|
||||
case 'u': ++c_flag;break;
|
||||
case 'u':
|
||||
++c_flag;
|
||||
break;
|
||||
#endif
|
||||
case 'o': ++oflag; break;
|
||||
case 'w': ++wflag; break;
|
||||
case 'o':
|
||||
++oflag;
|
||||
break;
|
||||
case 'w':
|
||||
++wflag;
|
||||
break;
|
||||
#ifdef JOHAN
|
||||
case 'j': ++jflag; break;
|
||||
case 'j':
|
||||
++jflag;
|
||||
break;
|
||||
#endif
|
||||
case 'U': ++Uflag; break;
|
||||
case 'U':
|
||||
++Uflag;
|
||||
break;
|
||||
case '-':
|
||||
case '+':
|
||||
on = (*argp == '+');
|
||||
while (*++argp) switch(LC(*argp)) {
|
||||
case 't': if (on) intflags |= 01;
|
||||
else intflags &= ~01;
|
||||
while (*++argp)
|
||||
switch (LC(*argp))
|
||||
{
|
||||
case 't':
|
||||
if (on)
|
||||
intflags |= 01;
|
||||
else
|
||||
intflags &= ~01;
|
||||
break;
|
||||
case 'p': if (on) intflags |= 02;
|
||||
else intflags &= ~02;
|
||||
case 'p':
|
||||
if (on)
|
||||
intflags |= 02;
|
||||
else
|
||||
intflags &= ~02;
|
||||
break;
|
||||
case 'f': if (on) intflags |= 04;
|
||||
else intflags &= ~04;
|
||||
case 'f':
|
||||
if (on)
|
||||
intflags |= 04;
|
||||
else
|
||||
intflags &= ~04;
|
||||
break;
|
||||
case 'c': if (on) intflags |= 010;
|
||||
else intflags &= ~010;
|
||||
case 'e': if (on) intflags |= 040;
|
||||
else intflags &= ~040;
|
||||
case 'c':
|
||||
if (on)
|
||||
intflags |= 010;
|
||||
else
|
||||
intflags &= ~010;
|
||||
case 'e':
|
||||
if (on)
|
||||
intflags |= 040;
|
||||
else
|
||||
intflags &= ~040;
|
||||
break;
|
||||
default:
|
||||
error("bad interpreter option %s", argp);
|
||||
|
@ -190,22 +269,32 @@ flags(arg)
|
|||
}
|
||||
}
|
||||
|
||||
do_proc() {
|
||||
void do_proc(void)
|
||||
{
|
||||
/* One procedure has been read and will be processed.
|
||||
*
|
||||
* NOTE: The numbers of the passes, 1 3 4 and 5, are a remainder
|
||||
* of ancient times.
|
||||
*/
|
||||
|
||||
dump(1); if ( memflg>2 )memuse();
|
||||
pass_3(); dump(3);
|
||||
pass_4(); dump(4);
|
||||
pass_5(); if ( memflg>2 ) memuse() ;
|
||||
endproc(); if ( memflg>1 ) memuse() ;
|
||||
dump(1);
|
||||
if (memflg > 2)
|
||||
memuse();
|
||||
pass_3();
|
||||
dump(3);
|
||||
pass_4();
|
||||
dump(4);
|
||||
pass_5();
|
||||
if (memflg > 2)
|
||||
memuse();
|
||||
endproc();
|
||||
if (memflg > 1)
|
||||
memuse();
|
||||
}
|
||||
|
||||
archive() {
|
||||
register i;
|
||||
static void archive(void)
|
||||
{
|
||||
register int i;
|
||||
register char *p;
|
||||
|
||||
/*
|
||||
|
@ -219,21 +308,26 @@ archive() {
|
|||
* This is the only reason.
|
||||
*/
|
||||
|
||||
for(;;) {
|
||||
if (unresolved == 0) { /* no use for this library anymore */
|
||||
for (;;)
|
||||
{
|
||||
if (unresolved == 0)
|
||||
{ /* no use for this library anymore */
|
||||
return;
|
||||
}
|
||||
p = chp_cast &archhdr;
|
||||
if ((i = fgetc(ifile))==EOF ) {
|
||||
if ((i = fgetc(ifile)) == EOF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*p++ = i;
|
||||
for (i = 1; i < sizeof archhdr.ar_name; i++)
|
||||
*p++ = get8();
|
||||
for (i=0;i<8;i++) get8();
|
||||
for (i = 0; i < 8; i++)
|
||||
get8();
|
||||
archhdr.ar_size = ((long) get16() << 16);
|
||||
archhdr.ar_size += getu16();
|
||||
inpoff = 0; libeof = archhdr.ar_size;
|
||||
inpoff = 0;
|
||||
libeof = archhdr.ar_size;
|
||||
/*
|
||||
* UNIX archiveheader is read now, now process the contents
|
||||
* of it. Note that recursive archives are not implemented.
|
||||
|
@ -241,16 +335,19 @@ archive() {
|
|||
* The variable libeof is used by get8() to check
|
||||
* whether or not we try to pass the library-boundary.
|
||||
*/
|
||||
if ( getu16() == sp_magic ) {
|
||||
if (getu16() == sp_magic)
|
||||
{
|
||||
read_compact();
|
||||
} else
|
||||
}
|
||||
else
|
||||
error("bad archive entry");
|
||||
skipentry();
|
||||
libeof = 0;
|
||||
} /* up to the next entry */
|
||||
}
|
||||
|
||||
skipentry() {
|
||||
static void skipentry(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* for some reason the rest of this library entry needs to be
|
||||
|
@ -263,7 +360,8 @@ skipentry() {
|
|||
;
|
||||
}
|
||||
|
||||
init_vars() {
|
||||
void init_vars(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* A small collection of variables is initialized.
|
||||
|
@ -273,33 +371,28 @@ init_vars() {
|
|||
|
||||
}
|
||||
|
||||
init_files() {
|
||||
void init_files(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* The temporary files on which text and data are kept
|
||||
* during assembly are set up here.
|
||||
*/
|
||||
#ifdef CPM
|
||||
unlink("????????.$$$");
|
||||
tfile=fopen("TFILE.$$$", "w");
|
||||
dfile=fopen("DFILE.$$$", "w");
|
||||
rtfile=fopen("RTFILE.$$$", "w");
|
||||
rdfile=fopen("RDFILE.$$$", "w");
|
||||
#else
|
||||
|
||||
/*
|
||||
* The function tmpfil() returns a file-descriptor
|
||||
* of a file that is valid for reading and writing.
|
||||
* It has the nice property of generating truly unique names.
|
||||
*/
|
||||
|
||||
tfile=fdopen(tmpfil(),"w") ;
|
||||
dfile=fdopen(tmpfil(),"w") ;
|
||||
rtfile=fdopen(tmpfil(),"w") ;
|
||||
rdfile=fdopen(tmpfil(),"w") ;
|
||||
#endif
|
||||
tfile = fopen(tmpfil(), "w+");
|
||||
dfile = fopen(tmpfil(), "w+");
|
||||
rtfile = fopen(tmpfil(), "w+");
|
||||
rdfile = fopen(tmpfil(), "w+");
|
||||
}
|
||||
|
||||
initproc() {
|
||||
void initproc(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Called at the start of assembly of every procedure.
|
||||
|
@ -313,31 +406,38 @@ initproc() {
|
|||
pstate.s_curpro = prp_cast 0;
|
||||
pstate.s_fline = lnp_cast 0;
|
||||
pstate.s_fdata = l_data;
|
||||
pstate.s_locl = (locl_t (*)[])
|
||||
getarea(LOCLABSIZE * sizeof ((*(pstate.s_locl))[0]));
|
||||
zero(chp_cast pstate.s_locl,
|
||||
pstate.s_locl = (locl_t (*)[]) getarea(
|
||||
LOCLABSIZE * sizeof((*(pstate.s_locl))[0]));
|
||||
memset(chp_cast pstate.s_locl, 0,
|
||||
LOCLABSIZE * (unsigned) sizeof((*(pstate.s_locl))[0]));
|
||||
if ( memflg>2 ) memuse() ;
|
||||
if (memflg > 2)
|
||||
memuse();
|
||||
}
|
||||
|
||||
endproc() {
|
||||
void endproc(void)
|
||||
{
|
||||
/* Throw the contents of the line and local label table away */
|
||||
register line_t *lnp1;
|
||||
register locl_t *lbhead, *lbp, *lbp_next;
|
||||
register kind ;
|
||||
register int kind;
|
||||
register stat_t *prevstate;
|
||||
|
||||
while ( lnp1= pstate.s_fline ) {
|
||||
while ((lnp1 = pstate.s_fline) != NULL)
|
||||
{
|
||||
pstate.s_fline = lnp1->l_next;
|
||||
kind = lnp1->type1;
|
||||
if ( kind>VALLOW ) kind=VALLOW ;
|
||||
if (kind > VALLOW)
|
||||
kind = VALLOW;
|
||||
freearea((area_t) lnp1, (unsigned) linesize[kind]);
|
||||
}
|
||||
prevstate = pstate.s_prevstat;
|
||||
if ( prevstate!= pst_cast 0 ) {
|
||||
for ( lbhead= *pstate.s_locl;
|
||||
lbhead<&(*pstate.s_locl)[LOCLABSIZE] ; lbhead++ ) {
|
||||
for ( lbp=lbhead->l_chain; lbp!= lbp_cast 0; lbp= lbp_next ) {
|
||||
if (prevstate != pst_cast 0)
|
||||
{
|
||||
for (lbhead = *pstate.s_locl; lbhead < &(*pstate.s_locl)[LOCLABSIZE];
|
||||
lbhead++)
|
||||
{
|
||||
for (lbp = lbhead->l_chain; lbp != lbp_cast 0; lbp = lbp_next)
|
||||
{
|
||||
lbp_next = lbp->l_chain;
|
||||
freearea((area_t) lbp, (unsigned) sizeof *lbp);
|
||||
}
|
||||
|
@ -349,7 +449,8 @@ endproc() {
|
|||
}
|
||||
}
|
||||
|
||||
init_module() {
|
||||
void init_module(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Called at the start of every module.
|
||||
|
@ -360,7 +461,8 @@ init_module() {
|
|||
mod_sizes = 0;
|
||||
}
|
||||
|
||||
end_module() {
|
||||
void end_module(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Finish a module.
|
||||
|
@ -373,10 +475,12 @@ end_module() {
|
|||
dump(100);
|
||||
enmd_pro();
|
||||
enmd_glo();
|
||||
if ( memflg ) memuse() ;
|
||||
if (memflg)
|
||||
memuse();
|
||||
}
|
||||
|
||||
enmd_pro() {
|
||||
static void enmd_pro(void)
|
||||
{
|
||||
register proc_t *p, *limit;
|
||||
|
||||
/*
|
||||
|
@ -385,25 +489,28 @@ enmd_pro() {
|
|||
*/
|
||||
|
||||
limit = &mprocs[oursize->n_mproc];
|
||||
for (p=mprocs; p<limit; p++) {
|
||||
for (p = mprocs; p < limit; p++)
|
||||
{
|
||||
if (p->p_name == 0)
|
||||
continue;
|
||||
if ((p->p_status & DEF) == 0)
|
||||
error("undefined local procedure '%s'", p->p_name);
|
||||
}
|
||||
zero(chp_cast mprocs,(limit-mprocs)* (unsigned)sizeof *mprocs);
|
||||
memset(chp_cast mprocs, 0, (limit - mprocs) * (unsigned ) sizeof *mprocs);
|
||||
|
||||
/* Clobber all flags indicating that external procedures
|
||||
* were used in this module.
|
||||
*/
|
||||
|
||||
limit = &xprocs[oursize->n_xproc];
|
||||
for (p=xprocs; p<limit; p++) {
|
||||
for (p = xprocs; p < limit; p++)
|
||||
{
|
||||
p->p_status &= ~EXT;
|
||||
}
|
||||
}
|
||||
|
||||
enmd_glo() {
|
||||
static void enmd_glo(void)
|
||||
{
|
||||
register glob_t *mg, *xg, *limit;
|
||||
|
||||
/*
|
||||
|
@ -420,7 +527,8 @@ enmd_glo() {
|
|||
*/
|
||||
|
||||
limit = &mglobs[oursize->n_mlab];
|
||||
for ( mg = mglobs; mg < limit; mg++) {
|
||||
for (mg = mglobs; mg < limit; mg++)
|
||||
{
|
||||
if (mg->g_name == 0)
|
||||
continue;
|
||||
if ((mg->g_status & (EXT | DEF)) == 0)
|
||||
|
@ -428,13 +536,15 @@ enmd_glo() {
|
|||
if ((mg->g_status & EXT) == 0)
|
||||
continue;
|
||||
xg = xglolookup(mg->g_name, ENTERING);
|
||||
switch(xg->g_status&(EXT|DEF)) {
|
||||
switch (xg->g_status & (EXT | DEF))
|
||||
{
|
||||
case 0: /* new symbol */
|
||||
if ((mg->g_status & DEF) == 0)
|
||||
++unresolved;
|
||||
break;
|
||||
case EXT: /* already used but not defined */
|
||||
if(mg->g_status&DEF) {
|
||||
if (mg->g_status & DEF)
|
||||
{
|
||||
--unresolved;
|
||||
}
|
||||
break;
|
||||
|
@ -446,10 +556,10 @@ enmd_glo() {
|
|||
mg->g_val.g_gp = xg; /* used by upd_reloc */
|
||||
} /* up to the next symbol */
|
||||
upd_reloc();
|
||||
zero(chp_cast mglobs,(limit-mglobs)*(unsigned) sizeof *mglobs);
|
||||
memset(chp_cast mglobs, 0, (limit - mglobs) * (unsigned ) sizeof *mglobs);
|
||||
}
|
||||
|
||||
finish_up()
|
||||
static void finish_up(void)
|
||||
{
|
||||
/*
|
||||
* Almost done. Check for unresolved references,
|
||||
|
@ -460,41 +570,55 @@ finish_up()
|
|||
c_print();
|
||||
#endif
|
||||
check_def();
|
||||
if ( nerrors==0 ) copyout();
|
||||
if (nerrors == 0)
|
||||
copyout();
|
||||
}
|
||||
|
||||
#ifdef DUMP
|
||||
c_print() {
|
||||
if ( ! c_flag ) return ;
|
||||
static void c_print(void)
|
||||
{
|
||||
if (!c_flag)
|
||||
return;
|
||||
c_dprint("primary", opcnt1);
|
||||
c_dprint("secondary", opcnt2);
|
||||
c_dprint("extra long", opcnt3);
|
||||
}
|
||||
|
||||
c_dprint(str,cnt) char *str,*cnt ; {
|
||||
static void c_dprint(char *str, char* cnt)
|
||||
{
|
||||
register int first, curr;
|
||||
printf("unused %s opcodes\n", str);
|
||||
for ( first= -1 , curr=0 ; curr<=256 ; curr++ ) {
|
||||
if ( curr==256 || cnt[curr] ) {
|
||||
if ( first!= -1 ) {
|
||||
if ( first+1 == curr ) {
|
||||
for (first = -1, curr = 0; curr <= 256; curr++)
|
||||
{
|
||||
if (curr == 256 || cnt[curr])
|
||||
{
|
||||
if (first != -1)
|
||||
{
|
||||
if (first + 1 == curr)
|
||||
{
|
||||
printf("%3d\n", first);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%3d..%3d\n", first, curr - 1);
|
||||
}
|
||||
first = -1;
|
||||
}
|
||||
} else {
|
||||
if ( first== -1 ) first=curr ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first == -1)
|
||||
first = curr;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
check_def() {
|
||||
static void check_def(void)
|
||||
{
|
||||
register proc_t *p;
|
||||
register glob_t *g;
|
||||
register count;
|
||||
register int count;
|
||||
|
||||
/*
|
||||
* Check for unresolved references.
|
||||
|
@ -504,7 +628,8 @@ check_def() {
|
|||
* Every use of the symbols concerned is undefined.
|
||||
*/
|
||||
|
||||
if (unresolved) {
|
||||
if (unresolved)
|
||||
{
|
||||
printf("Unresolved references\n Procedures:\n");
|
||||
count = oursize->n_xproc;
|
||||
for (p = xprocs; count--; p++)
|
||||
|
@ -515,14 +640,16 @@ check_def() {
|
|||
for (g = xglobs; count--; g++)
|
||||
if (g->g_name && (g->g_status & DEF) == 0)
|
||||
printf(" %s\n", glostring(g));
|
||||
if (! Uflag) nerrors++;
|
||||
if (!Uflag)
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
ertrap() { /* trap routine to drain input in case of compile errors */
|
||||
void ertrap(void)
|
||||
{ /* trap routine to drain input in case of compile errors */
|
||||
|
||||
if (fileno(ifile)== 0)
|
||||
if (ifile == stdin)
|
||||
while (fgetc(ifile) != EOF)
|
||||
;
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
|
@ -4,15 +4,12 @@
|
|||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <em_spec.h>
|
||||
#include <as_spec.h>
|
||||
#include <em_flag.h>
|
||||
#include <arch.h>
|
||||
#include <local.h>
|
||||
#include "em_spec.h"
|
||||
#include "as_spec.h"
|
||||
#include "em_flag.h"
|
||||
#include "arch.h"
|
||||
#include "local.h"
|
||||
|
||||
#define RCS_ASS "$Id$"
|
||||
|
||||
|
|
262
util/ass/ass30.c
262
util/ass/ass30.c
|
@ -4,25 +4,29 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "assci.h"
|
||||
#include "asscm.h"
|
||||
#include "ip_spec.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
static char rcs_ip[] = RCS_IP ;
|
||||
#endif
|
||||
|
||||
short opt_line; /* max_line_no - # lines removed from end
|
||||
after perfoming exc's.
|
||||
Used to estimate the distance in # of
|
||||
instructions.
|
||||
*/
|
||||
|
||||
/* Forward declarations. */
|
||||
static int valid(register line_t *);
|
||||
static char *findfit(int, cons_t);
|
||||
static char *findnop(int);
|
||||
|
||||
/*
|
||||
** Determine the exact instruction length & format where possible, and the
|
||||
** the upper and lower limits otherwise. Enter limits in labeltable
|
||||
*/
|
||||
pass_3()
|
||||
void pass_3(void)
|
||||
{
|
||||
register line_t *lnp, *rev_lnp;
|
||||
line_t *tmp_lnp;
|
||||
|
@ -30,15 +34,19 @@ pass_3()
|
|||
int min_l, max_l, min_bytes;
|
||||
short last_line;
|
||||
short hol_err_line;
|
||||
register insno ;
|
||||
register int insno;
|
||||
|
||||
pass = 3;
|
||||
opt_line= line_num ; hol_err_line=0 ;
|
||||
min_bytes = max_bytes = 0; rev_lnp= lnp_cast 0 ;
|
||||
for (lnp = pstate.s_fline ; lnp ; opt_line--, line_num-- ) {
|
||||
opt_line = line_num;
|
||||
hol_err_line = 0;
|
||||
min_bytes = max_bytes = 0;
|
||||
rev_lnp = lnp_cast 0;
|
||||
for (lnp = pstate.s_fline; lnp; opt_line--, line_num--)
|
||||
{
|
||||
pstate.s_fline = lnp;
|
||||
insno = ctrunc(lnp->instr_num);
|
||||
switch( insno ) {
|
||||
switch (insno)
|
||||
{
|
||||
case sp_fpseu:
|
||||
last_line = line_num;
|
||||
line_num = lnp->ad.ad_ln.ln_first;
|
||||
|
@ -52,55 +60,91 @@ pass_3()
|
|||
lbp->l_max = max_bytes;
|
||||
break;
|
||||
default:
|
||||
if ( lnp->type1==CONST && (em_flag[insno]&EM_PAR)==PAR_G ) {
|
||||
if (holbase != 0) {
|
||||
if (lnp->ad.ad_i >= holsize) {
|
||||
if (lnp->type1 == CONST && (em_flag[insno] & EM_PAR) == PAR_G)
|
||||
{
|
||||
if (holbase != 0)
|
||||
{
|
||||
if (lnp->ad.ad_i >= holsize)
|
||||
{
|
||||
hol_err_line = line_num;
|
||||
}
|
||||
lnp->ad.ad_i += holbase;
|
||||
}
|
||||
} else
|
||||
if ( lnp->type1>=VALLOW && (em_flag[insno]&EM_PAR)==PAR_G ) {
|
||||
if (holbase != 0) {
|
||||
}
|
||||
else if (lnp->type1 >= VALLOW && (em_flag[insno] & EM_PAR) == PAR_G)
|
||||
{
|
||||
if (holbase != 0)
|
||||
{
|
||||
pstate.s_fline = lnp->l_next;
|
||||
newline(CONST);
|
||||
pstate.s_fline->instr_num = insno;
|
||||
pstate.s_fline->ad.ad_i =
|
||||
VAL1(lnp->type1) + holbase;
|
||||
freearea((area_t)lnp,
|
||||
(unsigned)linesize[VALLOW]) ;
|
||||
freearea((area_t) lnp, (unsigned) linesize[VALLOW]);
|
||||
lnp = pstate.s_fline;
|
||||
if ( VAL1(lnp->type1) >= holsize) {
|
||||
if ( VAL1(lnp->type1) >= holsize)
|
||||
{
|
||||
hol_err_line = line_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !valid(lnp) ) fatal("Invalid operand") ;
|
||||
if (!valid(lnp))
|
||||
fatal("Invalid operand");
|
||||
|
||||
determine_props(lnp, &min_l, &max_l);
|
||||
min_bytes += min_l; max_bytes += max_l;
|
||||
min_bytes += min_l;
|
||||
max_bytes += max_l;
|
||||
break;
|
||||
}
|
||||
tmp_lnp = lnp->l_next;
|
||||
lnp->l_next= rev_lnp ; rev_lnp= lnp ;
|
||||
lnp->l_next = rev_lnp;
|
||||
rev_lnp = lnp;
|
||||
lnp = tmp_lnp;
|
||||
}
|
||||
pstate.s_fline = rev_lnp;
|
||||
if ( hol_err_line ) {
|
||||
if (hol_err_line)
|
||||
{
|
||||
line_num = hol_err_line;
|
||||
werror("address exceeds holsize");
|
||||
}
|
||||
}
|
||||
|
||||
int oplength(int flag)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
cnt = 1;
|
||||
if (flag & OPESC)
|
||||
cnt++;
|
||||
switch (flag & OPTYPE)
|
||||
{
|
||||
case OPNO:
|
||||
case OPMINI:
|
||||
break;
|
||||
case OP8:
|
||||
case OPSHORT:
|
||||
cnt++;
|
||||
break;
|
||||
case OP16U:
|
||||
case OP16:
|
||||
cnt += 2;
|
||||
break;
|
||||
case OP32:
|
||||
cnt += 5;
|
||||
break;
|
||||
case OP64:
|
||||
cnt += 9;
|
||||
break;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Determine the format that should be used for each instruction,
|
||||
** depending on its offsets
|
||||
*/
|
||||
|
||||
determine_props(lnp, min_len, max_len)
|
||||
line_t *lnp;
|
||||
int *min_len, *max_len;
|
||||
void determine_props(line_t *lnp, int *min_len, int *max_len)
|
||||
{
|
||||
cons_t val;
|
||||
register int insno;
|
||||
|
@ -109,8 +153,10 @@ determine_props(lnp, min_len, max_len)
|
|||
|
||||
insno = ctrunc(lnp->instr_num);
|
||||
val = parval(lnp, &defined);
|
||||
if ( !defined ) {
|
||||
switch(em_flag[insno]&EM_PAR) {
|
||||
if (!defined)
|
||||
{
|
||||
switch (em_flag[insno] & EM_PAR)
|
||||
{
|
||||
case PAR_NO:
|
||||
case PAR_W:
|
||||
f_off = findnop(insno);
|
||||
|
@ -128,7 +174,8 @@ determine_props(lnp, min_len, max_len)
|
|||
case PAR_B:
|
||||
f_off = findfit(insno, (cons_t) 0);
|
||||
l_off = findfit(insno, val);
|
||||
if ( f_off != l_off ) {
|
||||
if (f_off != l_off)
|
||||
{
|
||||
*min_len = oplength(*f_off);
|
||||
*max_len = oplength(*l_off);
|
||||
lnp->opoff = NO_OFF;
|
||||
|
@ -136,24 +183,28 @@ determine_props(lnp, min_len, max_len)
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
f_off = findfit(insno, val);
|
||||
}
|
||||
lnp->opoff = f_off;
|
||||
*min_len = *max_len = oplength(*f_off);
|
||||
}
|
||||
|
||||
char *findfit(instr,val) int instr ; cons_t val ; {
|
||||
static char *findfit(int instr, cons_t val)
|
||||
{
|
||||
register char *currc, *endc;
|
||||
int found, flags, number;
|
||||
char *opc;
|
||||
|
||||
endc = opindex[instr + 1];
|
||||
for ( currc=opindex[instr], found=0 ;
|
||||
!found && currc<endc ; currc++ ) {
|
||||
for (currc = opindex[instr], found = 0; !found && currc < endc; currc++)
|
||||
{
|
||||
opc = currc;
|
||||
flags = ctrunc(*currc++);
|
||||
switch ( flags&OPTYPE ) {
|
||||
switch (flags & OPTYPE)
|
||||
{
|
||||
case OPNO:
|
||||
continue;
|
||||
case OPMINI:
|
||||
|
@ -162,16 +213,20 @@ char *findfit(instr,val) int instr ; cons_t val ; {
|
|||
}
|
||||
found = opfit(flags, number, val, em_flag[instr] & EM_PAR);
|
||||
}
|
||||
if ( !found ) fatal("Cannot find interpreter opcode") ;
|
||||
if (!found)
|
||||
fatal("Cannot find interpreter opcode");
|
||||
return opc;
|
||||
}
|
||||
|
||||
char *findnop(instr) int instr ; {
|
||||
static char* findnop(int instr)
|
||||
{
|
||||
register char *currc, *endc;
|
||||
|
||||
endc = opindex[instr + 1];
|
||||
for ( currc=opindex[instr] ; currc<endc ; currc++ ) {
|
||||
switch ( ctrunc(*currc)&OPTYPE ) {
|
||||
for (currc = opindex[instr]; currc < endc; currc++)
|
||||
{
|
||||
switch ( ctrunc(*currc) & OPTYPE)
|
||||
{
|
||||
case OPNO:
|
||||
return currc;
|
||||
case OPSHORT:
|
||||
|
@ -182,71 +237,62 @@ char *findnop(instr) int instr ; {
|
|||
}
|
||||
fatal("Cannot find interpreter opcode");
|
||||
/* NOTREACHED */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int opfit(flag,number,val,i_flag)
|
||||
int i_flag,flag,number ; cons_t val ; {
|
||||
int opfit(int flag, int number, cons_t val, int i_flag)
|
||||
{
|
||||
/* Number is invalid if flag does not contain MINI or SHORT */
|
||||
switch ( flag&OPRANGE ) {
|
||||
switch (flag & OPRANGE)
|
||||
{
|
||||
case OP_POS:
|
||||
if ( val<0 ) return 0 ;
|
||||
if (val < 0)
|
||||
return 0;
|
||||
break;
|
||||
case OP_NEG:
|
||||
if ( val>=0 ) return 0 ;
|
||||
if (val >= 0)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if ( flag&OPWORD ) {
|
||||
if ( val%wordsize ) return 0 ;
|
||||
if (flag & OPWORD)
|
||||
{
|
||||
if (val % wordsize)
|
||||
return 0;
|
||||
val /= wordsize;
|
||||
}
|
||||
if ( flag&OPNZ ) {
|
||||
if ( val==0 ) return 0 ;
|
||||
if (flag & OPNZ)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
val--;
|
||||
}
|
||||
switch ( flag&OPTYPE ) {
|
||||
switch (flag & OPTYPE)
|
||||
{
|
||||
case OPMINI:
|
||||
if ( val<0 ) val = -1-val ;
|
||||
if (val < 0)
|
||||
val = -1 - val;
|
||||
return val >= 0 && val < number;
|
||||
case OPSHORT:
|
||||
if ( val<0 ) val = -1-val ;
|
||||
if (val < 0)
|
||||
val = -1 - val;
|
||||
return val >= 0 && val < number * 256;
|
||||
case OP16U:
|
||||
return val>=0 && val<=65535L &&
|
||||
( i_flag!=PAR_G || val<=maxadr ) ;
|
||||
return val >= 0 && val <= 65535L && (i_flag != PAR_G || val <= maxadr);
|
||||
case OP16:
|
||||
return val >= -32768 && val <= 32767;
|
||||
case OP32:
|
||||
return TRUE;
|
||||
default:
|
||||
fatal("illegal OPTYPE value");
|
||||
return -1;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
int oplength(flag) int flag ; {
|
||||
int cnt ;
|
||||
|
||||
cnt=1 ;
|
||||
if ( flag&OPESC ) cnt++ ;
|
||||
switch( flag&OPTYPE ) {
|
||||
case OPNO :
|
||||
case OPMINI : break ;
|
||||
case OP8 :
|
||||
case OPSHORT : cnt++ ; break ;
|
||||
case OP16U:
|
||||
case OP16 : cnt+=2 ; break ;
|
||||
case OP32 : cnt+=5 ; break ;
|
||||
case OP64 : cnt+=9 ; break ;
|
||||
}
|
||||
return cnt ;
|
||||
}
|
||||
|
||||
/*
|
||||
** return estimation of value of parameter
|
||||
*/
|
||||
cons_t parval(lnp,defined)
|
||||
line_t *lnp;
|
||||
char *defined;
|
||||
cons_t parval(line_t *lnp, char *defined)
|
||||
{
|
||||
register int type;
|
||||
register locl_t *lbp;
|
||||
|
@ -255,8 +301,10 @@ cons_t parval(lnp,defined)
|
|||
|
||||
*defined = TRUE;
|
||||
type = lnp->type1;
|
||||
switch(type) {
|
||||
default: if ( type>=VALLOW && type<=VALHIGH )
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
if (type >= VALLOW && type <= VALHIGH)
|
||||
return VAL1(type);
|
||||
error("bad type during parval");
|
||||
break;
|
||||
|
@ -264,27 +312,35 @@ cons_t parval(lnp,defined)
|
|||
return (lnp->ad.ad_i);
|
||||
case GLOSYM:
|
||||
case GLOOFF:
|
||||
if ( type!=GLOOFF) {
|
||||
if (type != GLOOFF)
|
||||
{
|
||||
gbp = lnp->ad.ad_gp;
|
||||
offs = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
gbp = lnp->ad.ad_df.df_gp;
|
||||
offs = lnp->ad.ad_df.df_i;
|
||||
}
|
||||
if (gbp->g_status & DEF)
|
||||
return (gbp->g_val.g_addr + offs);
|
||||
else {
|
||||
else
|
||||
{
|
||||
*defined = FALSE;
|
||||
return offs;
|
||||
}
|
||||
case LOCSYM:
|
||||
lbp = lnp->ad.ad_lp;
|
||||
switch(pass) {
|
||||
default:error("bad pass in parval");
|
||||
switch (pass)
|
||||
{
|
||||
default:
|
||||
error("bad pass in parval");
|
||||
case 3:
|
||||
*defined = FALSE;
|
||||
switch(lbp->l_defined) {
|
||||
default : fatal("Illegal local label") ;
|
||||
switch (lbp->l_defined)
|
||||
{
|
||||
default:
|
||||
fatal("Illegal local label");
|
||||
case NO:
|
||||
error("Undefined local label");
|
||||
lbp->l_defined = NOTPRESENT;
|
||||
|
@ -298,10 +354,12 @@ cons_t parval(lnp,defined)
|
|||
*/
|
||||
return (lbp->l_min - opt_line - 1) * maxinsl;
|
||||
}
|
||||
case 4: if(lbp->l_defined == YES)
|
||||
case 4:
|
||||
if (lbp->l_defined == YES)
|
||||
return (lbp->l_min - prog_size - maxinsl);
|
||||
return max_bytes - lbp->l_max - prog_size;
|
||||
case 5: if (lbp->l_defined == YES )
|
||||
case 5:
|
||||
if (lbp->l_defined == YES)
|
||||
return lbp->l_min;
|
||||
*defined = FALSE;
|
||||
break;
|
||||
|
@ -315,27 +373,37 @@ cons_t parval(lnp,defined)
|
|||
}
|
||||
return (0);
|
||||
}
|
||||
int valid(lnp) register line_t *lnp ; {
|
||||
|
||||
static int valid(register line_t *lnp)
|
||||
{
|
||||
cons_t val;
|
||||
int type;
|
||||
|
||||
type = lnp->type1;
|
||||
if ( type>=VALLOW && type<=VALHIGH ) {
|
||||
if (type >= VALLOW && type <= VALHIGH)
|
||||
{
|
||||
val = VAL1(type);
|
||||
type = CONST;
|
||||
} else if ( type==CONST ) val = lnp->ad.ad_i ;
|
||||
switch ( em_flag[ctrunc(lnp->instr_num)]&EM_PAR ) {
|
||||
}
|
||||
else if (type == CONST)
|
||||
val = lnp->ad.ad_i;
|
||||
switch (em_flag[ctrunc(lnp->instr_num)] & EM_PAR)
|
||||
{
|
||||
case PAR_NO:
|
||||
return type == MISSING;
|
||||
case PAR_C:
|
||||
if ( type!=CONST ) return FALSE;
|
||||
if ( val>maxint && val<=maxunsig ) {
|
||||
if (type != CONST)
|
||||
return FALSE;
|
||||
if (val > maxint && val <= maxunsig)
|
||||
{
|
||||
lnp->ad.ad_i = val - maxunsig - 1;
|
||||
}
|
||||
return TRUE;
|
||||
case PAR_D:
|
||||
if ( type!=CONST ) return FALSE;
|
||||
if ( val>maxdint && val<=maxdunsig ) {
|
||||
if (type != CONST)
|
||||
return FALSE;
|
||||
if (val > maxdint && val <= maxdunsig)
|
||||
{
|
||||
lnp->ad.ad_i = val - maxdunsig - 1;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -347,14 +415,15 @@ int valid(lnp) register line_t *lnp ; {
|
|||
case PAR_G:
|
||||
return type == CONST || type == GLOSYM || type == GLOOFF;
|
||||
case PAR_W:
|
||||
if ( type==MISSING ) return TRUE ;
|
||||
if (type == MISSING)
|
||||
return TRUE;
|
||||
case PAR_S:
|
||||
return type == CONST && val > 0 && val % wordsize == 0;
|
||||
case PAR_Z:
|
||||
return type == CONST && val >= 0 && val % wordsize == 0;
|
||||
case PAR_O:
|
||||
return type==CONST && val>=0 &&
|
||||
( val >= wordsize ? val%wordsize : wordsize%val ) == 0 ;
|
||||
return type == CONST && val >= 0
|
||||
&& (val >= wordsize ? val % wordsize : wordsize % val) == 0;
|
||||
case PAR_P:
|
||||
return type == PROCNAME;
|
||||
case PAR_B:
|
||||
|
@ -363,6 +432,7 @@ int valid(lnp) register line_t *lnp ; {
|
|||
return type == CONST && val >= 0 && val <= 3;
|
||||
default:
|
||||
fatal("Unknown parameter type");
|
||||
return -1;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,13 @@
|
|||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Make scans to do final assignment of instruction sizes & formats
|
||||
** to those not already done. assign final values to labels
|
||||
*/
|
||||
pass_4()
|
||||
void pass_4(void)
|
||||
{
|
||||
register line_t *lnp;
|
||||
register locl_t *lbp;
|
||||
|
|
|
@ -6,19 +6,21 @@
|
|||
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "assrl.h"
|
||||
#include "ip_spec.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Pass 5 of EM1 assembler/loader
|
||||
** Fix reloc tables
|
||||
** Write out code
|
||||
*/
|
||||
|
||||
pass_5() {
|
||||
static void patchcase(void);
|
||||
|
||||
|
||||
|
||||
void pass_5(void)
|
||||
{
|
||||
register line_t *lnp;
|
||||
cons_t off1;
|
||||
char defined ;
|
||||
|
@ -78,14 +80,15 @@ pass_5() {
|
|||
|
||||
} /* end pass_5 */
|
||||
|
||||
genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
|
||||
char *currc ;
|
||||
register flag ;
|
||||
char opc ;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Real code generation.
|
||||
*/
|
||||
void genop(char *startc,cons_t value,int i_flag)
|
||||
{
|
||||
char *currc ;
|
||||
register int flag ;
|
||||
char opc ;
|
||||
|
||||
currc= startc ;
|
||||
flag = ctrunc(*currc++);
|
||||
|
@ -161,11 +164,12 @@ genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
|
|||
}
|
||||
}
|
||||
|
||||
patchcase() {
|
||||
static void patchcase(void)
|
||||
{
|
||||
register relc_t *r;
|
||||
register locl_t *k;
|
||||
|
||||
if ( r= pstate.s_fdata ) {
|
||||
if ( (r= pstate.s_fdata) ) {
|
||||
r= r->r_next ;
|
||||
} else {
|
||||
r= f_data ;
|
||||
|
|
156
util/ass/ass60.c
156
util/ass/ass60.c
|
@ -8,21 +8,23 @@
|
|||
#include "assex.h"
|
||||
#include "ip_spec.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
#ifdef DUMP
|
||||
static char *typestr[] =
|
||||
{ "missing", "const", "procname", "glosym", "locsym", "glosym+off", "pseudo" };
|
||||
static char *labstr[] = {"EMPTY","no","yes","seen","notpresent"};
|
||||
static char formstr[] = { 'm','s','-','1','2','4','8' };
|
||||
static char *r_data[] = { "null","glob","head","loc","adr" };
|
||||
static char *labstr[] =
|
||||
{ "EMPTY", "no", "yes", "seen", "notpresent" };
|
||||
static char formstr[] =
|
||||
{ 'm', 's', '-', '1', '2', '4', '8' };
|
||||
static char *r_data[] =
|
||||
{ "null", "glob", "head", "loc", "adr" };
|
||||
|
||||
cons_t nicepr(typ,ap) addr_u *ap; {
|
||||
cons_t nicepr(int typ, addr_u *ap)
|
||||
{
|
||||
register proc_t *pl;
|
||||
|
||||
switch (typ) {
|
||||
switch (typ)
|
||||
{
|
||||
case CONST:
|
||||
return (ap->ad_i);
|
||||
case LOCSYM:
|
||||
|
@ -32,37 +34,47 @@ cons_t nicepr(typ,ap) addr_u *ap; {
|
|||
case GLOSYM:
|
||||
return (ap->ad_gp - mglobs);
|
||||
case PROCNAME:
|
||||
pl = ap->ad_pp;;
|
||||
pl = ap->ad_pp;
|
||||
;
|
||||
if (pl->p_status & EXT)
|
||||
return ((pl - xprocs) + 1000);
|
||||
else
|
||||
return (pl - mprocs);
|
||||
default:
|
||||
if ( typ>=VALLOW && typ<=VALHIGH ) return VAL1(typ) ;
|
||||
if (typ >= VALLOW && typ <= VALHIGH)
|
||||
return VAL1(typ);
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *pflags(flg) int flg ; {
|
||||
char *pflags(int flg)
|
||||
{
|
||||
static char res[9];
|
||||
register char *cp;
|
||||
|
||||
cp = res;
|
||||
if ( flg&OPESC ) *cp++ = 'e' ;
|
||||
switch ( flg&OPRANGE ) {
|
||||
case OP_NEG : *cp++ = 'N' ; break ;
|
||||
case OP_POS : *cp++ = 'P' ; break ;
|
||||
if (flg & OPESC)
|
||||
*cp++ = 'e';
|
||||
switch (flg & OPRANGE)
|
||||
{
|
||||
case OP_NEG:
|
||||
*cp++ = 'N';
|
||||
break;
|
||||
case OP_POS:
|
||||
*cp++ = 'P';
|
||||
break;
|
||||
}
|
||||
if ( flg&OPWORD ) *cp++ = 'w' ;
|
||||
if ( flg&OPNZ ) *cp++ = 'o' ;
|
||||
if (flg & OPWORD)
|
||||
*cp++ = 'w';
|
||||
if (flg & OPNZ)
|
||||
*cp++ = 'o';
|
||||
*cp++ = formstr[flg & OPTYPE];
|
||||
*cp++ = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
dump(n)
|
||||
void dump(int n)
|
||||
{
|
||||
register glob_t *gb;
|
||||
register line_t *ln;
|
||||
|
@ -73,24 +85,29 @@ dump(n)
|
|||
int insno;
|
||||
extern char em_mnem[][4];
|
||||
|
||||
if (d_flag==0) return;
|
||||
if ( (n==0 && d_flag) || (n==4 && d_flag>=2) || (n<100 && d_flag>=3) ) {
|
||||
if (d_flag == 0)
|
||||
return;
|
||||
if ((n == 0 && d_flag) || (n == 4 && d_flag >= 2)
|
||||
|| (n < 100 && d_flag >= 3))
|
||||
{
|
||||
printf("\nEM1-assembler ***** pass %1d complete:\n", n);
|
||||
printf("current size %ld\n", prog_size);
|
||||
printf(" %9.9s%9.9s%14.14s%8.8s%8.8s\n", "instr_nr",
|
||||
"type1","addr1","length","format");
|
||||
printf(" %9.9s%9.9s%14.14s%8.8s%8.8s\n", "instr_nr", "type1", "addr1",
|
||||
"length", "format");
|
||||
for (ln = pstate.s_fline; ln;
|
||||
ln = ln->l_next, n>=3 || n==0 ? i++ : i-- ) {
|
||||
ln = ln->l_next, n >= 3 || n == 0 ? i++ : i--)
|
||||
{
|
||||
insno = ctrunc(ln->instr_num);
|
||||
if ( insno==sp_fpseu ) {
|
||||
if (insno == sp_fpseu)
|
||||
{
|
||||
i = ln->ad.ad_ln.ln_first;
|
||||
continue;
|
||||
}
|
||||
printf("%4d ", i);
|
||||
switch(insno) {
|
||||
switch (insno)
|
||||
{
|
||||
default:
|
||||
printf(
|
||||
" %3.3s",em_mnem[insno]) ;
|
||||
printf(" %3.3s", em_mnem[insno]);
|
||||
break;
|
||||
case sp_ilb1:
|
||||
printf("l ");
|
||||
|
@ -103,76 +120,87 @@ if ( (n==0 && d_flag) || (n==4 && d_flag>=2) || (n<100 && d_flag>=3) ) {
|
|||
typestr[ln->type1 < VALLOW ? ln->type1 : CONST],
|
||||
nicepr(ln->type1, &ln->ad));
|
||||
if (ln->opoff != NO_OFF)
|
||||
printf("%5d %.6s",
|
||||
oplength(*(ln->opoff)),pflags(*(ln->opoff)));
|
||||
printf("%5d %.6s", oplength(*(ln->opoff)),
|
||||
pflags(*(ln->opoff)));
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n %8s%8s%8s%8s%8s\n", "labnum", "labid", "minval", "maxval",
|
||||
"defined");
|
||||
for ( i = 0, lbhead= *pstate.s_locl ; i<LOCLABSIZE ; lbhead++,i++) {
|
||||
if ( lbhead->l_defined!=EMPTY ) printf("%4d\n",i);
|
||||
for (lbp= lbhead; lbp != lbp_cast 0; lbp= lbp->l_chain) {
|
||||
for (i = 0, lbhead = *pstate.s_locl; i < LOCLABSIZE; lbhead++, i++)
|
||||
{
|
||||
if (lbhead->l_defined != EMPTY)
|
||||
printf("%4d\n", i);
|
||||
for (lbp = lbhead; lbp != lbp_cast 0; lbp = lbp->l_chain)
|
||||
{
|
||||
if (lbp->l_defined != EMPTY)
|
||||
printf(" %8d%8d%8d%8d %-s\n",
|
||||
lbp->l_hinum * LOCLABSIZE + i,
|
||||
int_cast lbp,lbp->l_min,
|
||||
lbp->l_max, labstr[lbp->l_defined]);
|
||||
int_cast lbp, lbp->l_min, lbp->l_max,
|
||||
labstr[(unsigned char)lbp->l_defined]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ( (n==0 || n>=100) && d_flag) || (n<=1 && d_flag>=2) ) {
|
||||
if ( n==0 || n==100 ) {
|
||||
if (((n == 0 || n >= 100) && d_flag) || (n <= 1 && d_flag >= 2))
|
||||
{
|
||||
if (n == 0 || n == 100)
|
||||
{
|
||||
printf("File %s", curfile);
|
||||
if ( archmode ) printf("(%.14s)",archhdr.ar_name);
|
||||
if (archmode)
|
||||
printf("(%.14s)", archhdr.ar_name);
|
||||
printf(" :\n\n");
|
||||
}
|
||||
printf("Local data labels:\n");
|
||||
printf(
|
||||
"\n\t%8.8s %8.8s %8.8s\n","g_name","g_status","g_addr");
|
||||
printf("\n\t%8.8s %8.8s %8.8s\n", "g_name", "g_status", "g_addr");
|
||||
for (gb = mglobs, i = 0; gb < &mglobs[oursize->n_mlab]; gb++, i++)
|
||||
if (gb->g_name[0] != 0) {
|
||||
if (gb->g_name[0] != 0)
|
||||
{
|
||||
printf("%5d\t%8.6s", i, gb->g_name);
|
||||
printf(" %8o %8ld\n", gb->g_status, gb->g_val.g_addr);
|
||||
}
|
||||
printf("\n\nGlobal data labels\n");
|
||||
printf("\n\t%8.8s %8.8s %8.8s\n",
|
||||
"g_name","g_status","g_addr");
|
||||
printf("\n\t%8.8s %8.8s %8.8s\n", "g_name", "g_status", "g_addr");
|
||||
for (gb = xglobs, i = 0; gb < &xglobs[oursize->n_glab]; gb++, i++)
|
||||
if (gb->g_name != 0) {
|
||||
if (gb->g_name != 0)
|
||||
{
|
||||
printf("%5d\t%8.6s", i, gb->g_name);
|
||||
printf(" %8o %8ld\n", gb->g_status, gb->g_val.g_addr);
|
||||
}
|
||||
printf("\n\nLocal procedures\n");
|
||||
printf("\n\t%8.8s%8s%8s\t%8s%8s\n",
|
||||
"name","status","num","off","locals");
|
||||
printf("\n\t%8.8s%8s%8s\t%8s%8s\n", "name", "status", "num", "off",
|
||||
"locals");
|
||||
for (pl = mprocs; pl < &mprocs[oursize->n_mproc]; pl++)
|
||||
if (pl->p_name) {
|
||||
printf("%4d\t%-8s%8o%8d",
|
||||
pl-mprocs,pl->p_name,pl->p_status,pl->p_num);
|
||||
if (pl->p_name)
|
||||
{
|
||||
printf("%4d\t%-8s%8o%8d", pl - mprocs, pl->p_name, pl->p_status,
|
||||
pl->p_num);
|
||||
if (pl->p_status & DEF)
|
||||
printf("\t%8ld%8ld", proctab[pl->p_num].pr_off,
|
||||
proctab[pl->p_num].pr_loc);
|
||||
printf("\n");
|
||||
}
|
||||
printf("\nGlobal procedures\n");
|
||||
printf("\n\t%8s%8s%8s\t%8s%8s\n",
|
||||
"name","status","num","off","locals");
|
||||
printf("\n\t%8s%8s%8s\t%8s%8s\n", "name", "status", "num", "off",
|
||||
"locals");
|
||||
for (pl = xprocs; pl < &xprocs[oursize->n_xproc]; pl++)
|
||||
if (pl->p_name) {
|
||||
printf("%4d\t%-8s%8o%8d",
|
||||
pl-xprocs,pl->p_name,pl->p_status,pl->p_num);
|
||||
if (pl->p_name)
|
||||
{
|
||||
printf("%4d\t%-8s%8o%8d", pl - xprocs, pl->p_name, pl->p_status,
|
||||
pl->p_num);
|
||||
if (pl->p_status & DEF)
|
||||
printf("\t%8ld%8ld", proctab[pl->p_num].pr_off,
|
||||
proctab[pl->p_num].pr_loc);
|
||||
printf("\n");
|
||||
}
|
||||
if ( r_flag ) {
|
||||
if (r_flag)
|
||||
{
|
||||
register relc_t *rl;
|
||||
printf("\nData relocation\n");
|
||||
printf("\n\t%10s %10s %10s\n", "offset", "type", "value");
|
||||
for ( rl=f_data ; rl ; rl= rl->r_next ) {
|
||||
for (rl = f_data; rl; rl = rl->r_next)
|
||||
{
|
||||
printf("\t%10ld %10s ", rl->r_off, r_data[rl->r_typ]);
|
||||
switch(rl->r_typ) {
|
||||
switch (rl->r_typ)
|
||||
{
|
||||
case RELADR:
|
||||
case RELHEAD:
|
||||
printf("%10ld\n", rl->r_val.rel_i);
|
||||
|
@ -184,21 +212,23 @@ if ( ( (n==0 || n>=100) && d_flag) || (n<=1 && d_flag>=2) ) {
|
|||
printf("%10d\n", rl->r_val.rel_lp);
|
||||
break;
|
||||
case RELNULL:
|
||||
printf("\n"); break ;
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n\nText relocation\n");
|
||||
printf("\n\t%10s %10s %10s\n", "offset", "flags", "value");
|
||||
for ( rl=f_text; rl ; rl= rl->r_next ) {
|
||||
printf("\t%10ld %10s ",
|
||||
rl->r_off,pflags(opchoice[rl->r_typ&~RELMNS])) ;
|
||||
for (rl = f_text; rl; rl = rl->r_next)
|
||||
{
|
||||
printf("\t%10ld %10s ", rl->r_off,
|
||||
pflags(opchoice[rl->r_typ & ~RELMNS]));
|
||||
if (rl->r_typ & RELMNS)
|
||||
printf("%10ld\n", rl->r_val.rel_i);
|
||||
else printf("\n") ;
|
||||
else
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
#include "asscm.h"
|
||||
|
||||
/*
|
||||
** utilities of EM1-assembler/loader
|
||||
|
@ -17,15 +16,16 @@ static char rcs_id[] = "$Id$" ;
|
|||
|
||||
static int globstep;
|
||||
|
||||
|
||||
/*
|
||||
* glohash returns an index in table and leaves a stepsize in globstep
|
||||
*
|
||||
*/
|
||||
|
||||
static int glohash(aname,size) char *aname; {
|
||||
static int glohash(char *aname ,int size)
|
||||
{
|
||||
register char *p;
|
||||
register i;
|
||||
register sum;
|
||||
register int i;
|
||||
register int sum;
|
||||
|
||||
/*
|
||||
* Computes a hash-value from a string.
|
||||
|
@ -44,17 +44,19 @@ static int glohash(aname,size) char *aname; {
|
|||
* return index in labeltable
|
||||
*/
|
||||
|
||||
glob_t *glo2lookup(name,status) char *name; {
|
||||
|
||||
glob_t *glo2lookup(char *name ,int status)
|
||||
{
|
||||
return(glolookup(name,status,mglobs,oursize->n_mlab));
|
||||
}
|
||||
|
||||
glob_t *xglolookup(name,status) char *name; {
|
||||
glob_t *xglolookup(char *name,int status)
|
||||
{
|
||||
|
||||
return(glolookup(name,status,xglobs,oursize->n_glab));
|
||||
}
|
||||
|
||||
static void findext(g) glob_t *g ; {
|
||||
static void findext(glob_t *g)
|
||||
{
|
||||
glob_t *x;
|
||||
|
||||
x = xglolookup(g->g_name,ENTERING);
|
||||
|
@ -65,19 +67,10 @@ static void findext(g) glob_t *g ; {
|
|||
g->g_status |= EXT;
|
||||
}
|
||||
|
||||
glob_t *glolookup(name,status,table,size)
|
||||
char *name; /* name */
|
||||
int status; /* kind of lookup */
|
||||
glob_t *table; /* which table to use */
|
||||
int size; /* size for hash */
|
||||
{
|
||||
register glob_t *g;
|
||||
register rem,j;
|
||||
int new;
|
||||
|
||||
/*
|
||||
* lookup global symbol name in specified table.
|
||||
* Various actions are taken depending on status.
|
||||
* Various actions are taken depending on status
|
||||
* parameter.
|
||||
*
|
||||
* DEFINING:
|
||||
* Lookup or enter the symbol, check for mult. def.
|
||||
|
@ -92,6 +85,12 @@ int size; /* size for hash */
|
|||
* ENTERING:
|
||||
* Lookup or enter the symbol, don't check
|
||||
*/
|
||||
glob_t *glolookup(char *name,int status,glob_t *table, int size)
|
||||
{
|
||||
register glob_t *g;
|
||||
register int rem,j;
|
||||
int new;
|
||||
|
||||
|
||||
rem = glohash(name,size);
|
||||
j = 0; new=0;
|
||||
|
@ -150,9 +149,18 @@ int size; /* size for hash */
|
|||
return(g);
|
||||
}
|
||||
|
||||
locl_t *loclookup(an,status) {
|
||||
/*
|
||||
* lookup local label by number and return the
|
||||
* label definition if found.
|
||||
*
|
||||
* DEFINING:
|
||||
* Lookup or enter the symbol, check for mult. def.
|
||||
*
|
||||
*/
|
||||
locl_t *loclookup(unsigned int an,int status)
|
||||
{
|
||||
register locl_t *lbp,*l_lbp;
|
||||
register unsigned num;
|
||||
register unsigned int num;
|
||||
char hinum;
|
||||
|
||||
if ( !pstate.s_locl ) fatal("label outside procedure");
|
||||
|
@ -188,10 +196,6 @@ locl_t *loclookup(an,status) {
|
|||
return(lbp);
|
||||
}
|
||||
|
||||
proc_t *prolookup(name,status) char *name; {
|
||||
register proc_t *p;
|
||||
register pstat;
|
||||
|
||||
/*
|
||||
* Look up a procedure name according to status
|
||||
*
|
||||
|
@ -208,6 +212,11 @@ proc_t *prolookup(name,status) char *name; {
|
|||
* The EXT bit in this table indicates the the name is used
|
||||
* as external in this module.
|
||||
*/
|
||||
proc_t *prolookup(char *name,int status)
|
||||
{
|
||||
register proc_t *p= NULL;
|
||||
register int pstat = 0;
|
||||
|
||||
|
||||
switch(status) {
|
||||
case PRO_OCC:
|
||||
|
@ -281,18 +290,15 @@ proc_t *prolookup(name,status) char *name; {
|
|||
return(enterproc(name,pstat,p));
|
||||
}
|
||||
|
||||
proc_t *searchproc(name,table,size)
|
||||
char *name;
|
||||
proc_t *table;
|
||||
int size;
|
||||
{
|
||||
register proc_t *p;
|
||||
register rem,j;
|
||||
|
||||
/*
|
||||
* return a pointer into table to the place where the procedure
|
||||
* name is or should be if in the table.
|
||||
*/
|
||||
proc_t *searchproc(char *name,proc_t *table,int size)
|
||||
{
|
||||
register proc_t *p;
|
||||
register int rem,j;
|
||||
|
||||
|
||||
rem = glohash(name,size);
|
||||
j = 0;
|
||||
|
@ -307,12 +313,6 @@ proc_t *searchproc(name,table,size)
|
|||
return(p);
|
||||
}
|
||||
|
||||
proc_t *enterproc(name,status,place)
|
||||
char *name;
|
||||
char status;
|
||||
proc_t *place; {
|
||||
register proc_t *p;
|
||||
|
||||
/*
|
||||
* Enter the procedure name into the table at place place.
|
||||
* Place had better be computed by searchproc().
|
||||
|
@ -325,6 +325,9 @@ proc_t *place; {
|
|||
* Two local procedures with the same name in different
|
||||
* modules have different numbers.
|
||||
*/
|
||||
proc_t *enterproc(char *name,int status,proc_t *place)
|
||||
{
|
||||
register proc_t *p;
|
||||
|
||||
p=place;
|
||||
p->p_name = (char *) getarea((unsigned) (strlen(name) + 1));
|
||||
|
|
180
util/ass/ass80.c
180
util/ass/ass80.c
|
@ -6,28 +6,19 @@
|
|||
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include <em_path.h>
|
||||
#include "assrl.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "system.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* this file contains several library routines.
|
||||
*/
|
||||
|
||||
zero(area,length) char *area; unsigned length ; {
|
||||
register char *p;
|
||||
register n;
|
||||
/*
|
||||
* Clear area of length bytes.
|
||||
*/
|
||||
if ((n=length)==0)
|
||||
return;
|
||||
p = area;
|
||||
do *p++=0; while (--n);
|
||||
}
|
||||
static char filename[L_tmpnam];
|
||||
|
||||
|
||||
/* VARARGS1 */
|
||||
static void pr_error(const char* string1, va_list ap) {
|
||||
|
@ -60,7 +51,8 @@ void error(const char* string1, ...)
|
|||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void werror(const char* string1, ...) {
|
||||
void werror(const char* string1, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if ( wflag ) return ;
|
||||
|
||||
|
@ -69,57 +61,44 @@ void werror(const char* string1, ...) {
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
fatal(s) char *s; {
|
||||
void fatal(char *s)
|
||||
{
|
||||
/*
|
||||
* handle fatal errors
|
||||
*/
|
||||
error("Fatal error: %s",s);
|
||||
dump(0);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef CPM
|
||||
FILE *frewind(f) FILE *f ; {
|
||||
/* Rewind a file open for writing and open it for reading */
|
||||
/* Assumption, file descriptor is r/w */
|
||||
register FILE *tmp ;
|
||||
tmp=fdopen(dup(fileno(f)),"r");
|
||||
fclose(f);
|
||||
rewind(tmp);
|
||||
return tmp ;
|
||||
}
|
||||
#endif
|
||||
|
||||
int xgetc(af) register FILE *af; {
|
||||
|
||||
int xgetc(register FILE *af)
|
||||
{
|
||||
register int nextc;
|
||||
/*
|
||||
* read next character; fatal if there isn't one
|
||||
*/
|
||||
nextc=fgetc(af) ;
|
||||
if ( feof(af) )
|
||||
fatal("unexpected end of file");
|
||||
return nextc ;
|
||||
}
|
||||
|
||||
xputc(c,af) register FILE *af; {
|
||||
/* output one character and scream if it gives an error */
|
||||
void xputc(int c,register FILE *af)
|
||||
{
|
||||
fputc(c,af) ;
|
||||
if ( ferror(af) ) fatal("write error") ;
|
||||
}
|
||||
|
||||
|
||||
putblk(stream,from,amount)
|
||||
register FILE *stream; register char *from ; register int amount ; {
|
||||
|
||||
void putblk(register FILE *stream,register char *from, register int amount)
|
||||
{
|
||||
for ( ; amount-- ; from++ ) {
|
||||
fputc(*from,stream) ;
|
||||
if ( ferror(stream) ) fatal("write error") ;
|
||||
}
|
||||
}
|
||||
|
||||
int getblk(stream,from,amount)
|
||||
register FILE *stream; register char *from ; register int amount ; {
|
||||
|
||||
int getblk(register FILE *stream, register char *from, register int amount)
|
||||
{
|
||||
for ( ; amount-- ; from++ ) {
|
||||
*from = fgetc(stream) ;
|
||||
if ( feof(stream) ) return 1 ;
|
||||
|
@ -127,7 +106,8 @@ int getblk(stream,from,amount)
|
|||
return 0 ;
|
||||
}
|
||||
|
||||
xput16(w,f) FILE *f; {
|
||||
void xput16(int w,FILE *f)
|
||||
{
|
||||
/*
|
||||
* two times xputc
|
||||
*/
|
||||
|
@ -135,19 +115,22 @@ xput16(w,f) FILE *f; {
|
|||
xputc(w>>8,f);
|
||||
}
|
||||
|
||||
xputarb(l,w,f) int l ; cons_t w ; FILE *f ; {
|
||||
void xputarb(int l,cons_t w, FILE* f)
|
||||
{
|
||||
while ( l-- ) {
|
||||
xputc( int_cast w,f) ;
|
||||
w >>=8 ;
|
||||
}
|
||||
}
|
||||
|
||||
put8(n) {
|
||||
void put8(int n)
|
||||
{
|
||||
xputc(n,tfile);
|
||||
textoff++;
|
||||
}
|
||||
|
||||
put16(n) {
|
||||
void put16(int n)
|
||||
{
|
||||
/*
|
||||
* note reversed order of bytes.
|
||||
* this is done for faster interpretation.
|
||||
|
@ -157,16 +140,19 @@ put16(n) {
|
|||
textoff += 2;
|
||||
}
|
||||
|
||||
put32(n) cons_t n ; {
|
||||
void put32(cons_t n)
|
||||
{
|
||||
put16( int_cast (n>>16)) ;
|
||||
put16( int_cast n) ;
|
||||
}
|
||||
|
||||
put64(n) cons_t n ; {
|
||||
void put64(cons_t n)
|
||||
{
|
||||
fatal("put64 called") ;
|
||||
}
|
||||
|
||||
int xget8() {
|
||||
int xget8(void)
|
||||
{
|
||||
/*
|
||||
* Read one byte from ifile.
|
||||
*/
|
||||
|
@ -176,7 +162,8 @@ int xget8() {
|
|||
return fgetc(ifile) ;
|
||||
}
|
||||
|
||||
unsigned get8() {
|
||||
unsigned int get8(void)
|
||||
{
|
||||
register int nextc;
|
||||
/*
|
||||
* Read one byte from ifile.
|
||||
|
@ -191,16 +178,17 @@ unsigned get8() {
|
|||
return nextc ;
|
||||
}
|
||||
|
||||
cons_t xgetarb(l,f) int l; FILE *f ; {
|
||||
cons_t xgetarb(int l,FILE *f)
|
||||
{
|
||||
cons_t val ;
|
||||
register int shift ;
|
||||
int c;
|
||||
|
||||
shift=0 ; val=0 ;
|
||||
while ( l-- ) {
|
||||
// val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
|
||||
// Bug here: shifts with too large shift counts
|
||||
// get unspecified results. --Ceriel
|
||||
/* val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
|
||||
Bug here: shifts with too large shift counts
|
||||
get unspecified results. --Ceriel */
|
||||
c = ctrunc(xgetc(f));
|
||||
if (shift < 8 * sizeof(cons_t)) {
|
||||
val += ((cons_t)c)<<shift ;
|
||||
|
@ -216,7 +204,8 @@ cons_t xgetarb(l,f) int l; FILE *f ; {
|
|||
return val ;
|
||||
}
|
||||
|
||||
ext8(b) {
|
||||
void ext8(int b)
|
||||
{
|
||||
/*
|
||||
* Handle one byte of data.
|
||||
*/
|
||||
|
@ -224,55 +213,56 @@ ext8(b) {
|
|||
xputc(b,dfile);
|
||||
}
|
||||
|
||||
extword(w) cons_t w ; {
|
||||
void extword(cons_t w)
|
||||
{
|
||||
/* Assemble the word constant w.
|
||||
* NOTE: The bytes are written low to high.
|
||||
*/
|
||||
register i ;
|
||||
register int i ;
|
||||
for ( i=wordsize ; i-- ; ) {
|
||||
ext8( int_cast w) ;
|
||||
w >>= 8 ;
|
||||
}
|
||||
}
|
||||
|
||||
extarb(size,value) int size ; long value ; {
|
||||
void extarb(int size, long value)
|
||||
{
|
||||
/* Assemble the 'size' constant value.
|
||||
* The bytes are again written low to high.
|
||||
*/
|
||||
register i ;
|
||||
register int i ;
|
||||
for ( i=size ; i-- ; ) {
|
||||
ext8( int_cast value ) ;
|
||||
value >>=8 ;
|
||||
}
|
||||
}
|
||||
|
||||
extadr(a) cons_t a ; {
|
||||
/* Assemble the word constant a.
|
||||
void extadr(cons_t a)
|
||||
{
|
||||
/* Assemble the pointer constant a.
|
||||
* NOTE: The bytes are written low to high.
|
||||
*/
|
||||
register i ;
|
||||
register int i ;
|
||||
for ( i=ptrsize ; i-- ; ) {
|
||||
ext8( int_cast a) ;
|
||||
a >>= 8 ;
|
||||
}
|
||||
}
|
||||
|
||||
xputa(a,f) cons_t a ; FILE *f ; {
|
||||
/* Assemble the pointer constant a.
|
||||
* NOTE: The bytes are written low to high.
|
||||
*/
|
||||
register i ;
|
||||
void xputa(cons_t a,FILE* f)
|
||||
{
|
||||
|
||||
register int i ;
|
||||
for ( i=ptrsize ; i-- ; ) {
|
||||
xputc( int_cast a,f) ;
|
||||
a >>= 8 ;
|
||||
}
|
||||
}
|
||||
|
||||
cons_t xgeta(f) FILE *f ; {
|
||||
/* Read the pointer constant a.
|
||||
* NOTE: The bytes were written low to high.
|
||||
*/
|
||||
register i, shift ;
|
||||
cons_t xgeta(FILE* f)
|
||||
{
|
||||
|
||||
register int i, shift ;
|
||||
cons_t val ;
|
||||
val = 0 ; shift=0 ;
|
||||
for ( i=ptrsize ; i-- ; ) {
|
||||
|
@ -282,14 +272,16 @@ cons_t xgeta(f) FILE *f ; {
|
|||
return val ;
|
||||
}
|
||||
|
||||
int icount(size) {
|
||||
int icount(int size)
|
||||
{
|
||||
int amount ;
|
||||
amount=(dataoff-lastoff)/size ;
|
||||
if ( amount>MAXBYTE) fatal("Descriptor overflow");
|
||||
return amount ;
|
||||
}
|
||||
|
||||
set_mode(mode) {
|
||||
void set_mode(int mode)
|
||||
{
|
||||
|
||||
if (datamode==mode) { /* in right mode already */
|
||||
switch ( datamode ) {
|
||||
|
@ -389,40 +381,12 @@ set_mode(mode) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CPM
|
||||
int tmpfil() {
|
||||
register char *fname, *cpname ;
|
||||
static char sfname[] = "tmp.00000";
|
||||
register fildes,pid;
|
||||
static char name[80] = TMP_DIR ;
|
||||
int count;
|
||||
/*
|
||||
* This procedure returns a file-descriptor of a temporary
|
||||
* file valid for reading and writing.
|
||||
* After closing the tmpfil-descriptor the file is lost
|
||||
* Calling this routine frees the program from generating uniqe names.
|
||||
*/
|
||||
fname = sfname+4;
|
||||
count = 10;
|
||||
pid = getpid();
|
||||
while (pid!=0) {
|
||||
*fname++ = (pid&07) + '0';
|
||||
pid >>= 3;
|
||||
|
||||
char* tmpfil(void)
|
||||
{
|
||||
if (sys_tmpnam(filename)==NULL)
|
||||
{
|
||||
fatal("Cannot create temporary filename.");
|
||||
}
|
||||
*fname = 0;
|
||||
for ( fname=name ; *fname ; fname++ ) ;
|
||||
cpname=sfname ;
|
||||
while ( *fname++ = *cpname++ ) ;
|
||||
do {
|
||||
fname = name;
|
||||
if ((fildes = creat(fname, 0600)) < 0)
|
||||
if ((fildes = creat(fname=sfname, 0600)) < 0)
|
||||
return(-1);
|
||||
if (close(fildes) < 0)
|
||||
;
|
||||
} while((fildes = open(fname, 2)) < 0 && count--);
|
||||
if (unlink(fname) < 0)
|
||||
;
|
||||
return(fildes);
|
||||
return filename;
|
||||
}
|
||||
#endif
|
||||
|
|
739
util/ass/assci.c
739
util/ass/assci.c
File diff suppressed because it is too large
Load diff
20
util/ass/assci.h
Normal file
20
util/ass/assci.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (c) 2019 ACK Project.
|
||||
* See the copyright notice in the ACK home directory,
|
||||
* in the file "Copyright".
|
||||
*
|
||||
* Created on: 2019-03-12
|
||||
*
|
||||
*/
|
||||
#ifndef ASSCI_H_
|
||||
#define ASSCI_H_
|
||||
|
||||
|
||||
/*
|
||||
* read module in compact EM1 code and fill in the table in memory
|
||||
* with all the specified data as a linked list.
|
||||
*/
|
||||
void read_compact(void);
|
||||
void newline(int type);
|
||||
void align(int size);
|
||||
|
||||
#endif /* ASSCI_H_ */
|
|
@ -19,31 +19,31 @@
|
|||
*/
|
||||
|
||||
#include "ass00.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
#include "assex.h"
|
||||
#include "asscm.h"
|
||||
|
||||
#ifdef MEMUSE
|
||||
static unsigned m_used = 0;
|
||||
static unsigned m_free = 0;
|
||||
#endif
|
||||
|
||||
struct freeblock {
|
||||
struct freeblock
|
||||
{
|
||||
struct freeblock *f_next;
|
||||
unsigned f_size;
|
||||
};
|
||||
|
||||
static struct freeblock freexx[2] = {
|
||||
static struct freeblock freexx[2] =
|
||||
{
|
||||
{ freexx, 0 },
|
||||
{ freexx+1, 0 }
|
||||
} ;
|
||||
{ freexx + 1, 0 } };
|
||||
|
||||
#define freehead freexx[1]
|
||||
|
||||
#define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
|
||||
|
||||
area_t getarea(size) unsigned size ; {
|
||||
area_t getarea(unsigned int size)
|
||||
{
|
||||
register struct freeblock *c_ptr, *l_ptr;
|
||||
register char *ptr;
|
||||
unsigned rqsize;
|
||||
|
@ -53,26 +53,32 @@ area_t getarea(size) unsigned size ; {
|
|||
m_used += size;
|
||||
m_free -= size;
|
||||
#endif
|
||||
for(;;) {
|
||||
for (;;)
|
||||
{
|
||||
for (l_ptr = &freehead, c_ptr= freehead.f_next;
|
||||
c_ptr!= &freehead ; c_ptr = c_ptr->f_next ) {
|
||||
if ( size==c_ptr->f_size ) {
|
||||
c_ptr!= &freehead; c_ptr = c_ptr->f_next )
|
||||
{
|
||||
if ( size==c_ptr->f_size )
|
||||
{
|
||||
l_ptr->f_next= c_ptr->f_next;
|
||||
return (area_t) c_ptr;
|
||||
}
|
||||
if ( size+sizeof freehead <= c_ptr->f_size ) {
|
||||
if ( size+sizeof freehead <= c_ptr->f_size )
|
||||
{
|
||||
c_ptr->f_size -= size;
|
||||
return (area_t) ((char *) c_ptr + c_ptr->f_size);
|
||||
}
|
||||
l_ptr = c_ptr;
|
||||
}
|
||||
rqsize = size<CHUNK ? CHUNK : size;
|
||||
for(;;){
|
||||
for(;;)
|
||||
{
|
||||
ptr = malloc( rqsize );
|
||||
if ( ptr ) break; /* request succesfull */
|
||||
rqsize /= 2;
|
||||
rqsize -= rqsize%sizeof (int);
|
||||
if ( rqsize < sizeof freehead ) {
|
||||
if ( rqsize < sizeof freehead )
|
||||
{
|
||||
fatal("Out of memory");
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +90,8 @@ area_t getarea(size) unsigned size ; {
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
freearea(ptr,size) register area_t ptr ; unsigned size ; {
|
||||
void freearea(register area_t ptr, unsigned int size)
|
||||
{
|
||||
register struct freeblock *c_ptr, *l_ptr;
|
||||
|
||||
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
|
||||
|
@ -93,7 +100,8 @@ freearea(ptr,size) register area_t ptr ; unsigned size ; {
|
|||
m_used -= size;
|
||||
#endif
|
||||
for (l_ptr = &freehead, c_ptr=freehead.f_next;
|
||||
c_ptr!= &freehead ; c_ptr= c_ptr->f_next ) {
|
||||
c_ptr!= &freehead; c_ptr= c_ptr->f_next )
|
||||
{
|
||||
if ( (area_t)c_ptr>ptr ) break;
|
||||
l_ptr= c_ptr;
|
||||
}
|
||||
|
@ -101,15 +109,21 @@ freearea(ptr,size) register area_t ptr ; unsigned size ; {
|
|||
/* Beware they may both point to freehead */
|
||||
|
||||
#ifdef MEMUSE
|
||||
if ( ((char *)l_ptr)+l_ptr->f_size> (char *)ptr && (char *)l_ptr<=(char *)ptr )
|
||||
if (((char *) l_ptr) + l_ptr->f_size > (char *) ptr
|
||||
&& (char *) l_ptr <= (char *) ptr)
|
||||
fatal("Double freed");
|
||||
if ( ((char *)ptr)+size > (char *)c_ptr && (char *)ptr<=(char *)c_ptr )
|
||||
if (((char *) ptr) + size > (char *) c_ptr
|
||||
&& (char *) ptr <= (char *) c_ptr)
|
||||
fatal("Frreed double");
|
||||
#endif
|
||||
/* Is the block before this one adjacent ? */
|
||||
if ( ((char *)l_ptr) + l_ptr->f_size == (char *) ptr ) {
|
||||
l_ptr->f_size += size ; /* yes */
|
||||
} else {
|
||||
if (((char *) l_ptr) + l_ptr->f_size == (char *) ptr)
|
||||
{
|
||||
l_ptr->f_size += size;
|
||||
/* yes */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No, create an entry */
|
||||
((struct freeblock *) ptr)->f_next = c_ptr;
|
||||
((struct freeblock *) ptr)->f_size = size;
|
||||
|
@ -117,7 +131,8 @@ freearea(ptr,size) register area_t ptr ; unsigned size ; {
|
|||
l_ptr = (struct freeblock *) ptr;
|
||||
}
|
||||
/* Are the two entries adjacent ? */
|
||||
if ( (char *)l_ptr + l_ptr->f_size == (char *) c_ptr ) {
|
||||
if ((char *) l_ptr + l_ptr->f_size == (char *) c_ptr)
|
||||
{
|
||||
/* the two entries are adjacent */
|
||||
l_ptr->f_next = c_ptr->f_next;
|
||||
l_ptr->f_size += c_ptr->f_size;
|
||||
|
@ -125,7 +140,8 @@ freearea(ptr,size) register area_t ptr ; unsigned size ; {
|
|||
}
|
||||
|
||||
#ifdef MEMUSE
|
||||
memuse() {
|
||||
void memuse(void)
|
||||
{
|
||||
printf("Free %7u, Used %7u, Total %7u\n", m_free, m_used, m_free + m_used);
|
||||
}
|
||||
#endif
|
||||
|
|
22
util/ass/asscm.h
Normal file
22
util/ass/asscm.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* Copyright (c) 2019 ACK Project.
|
||||
* See the copyright notice in the ACK home directory,
|
||||
* in the file "Copyright".
|
||||
*
|
||||
* Created on: 2019-03-12
|
||||
*
|
||||
*/
|
||||
#ifndef ASSCM_H_
|
||||
#define ASSCM_H_
|
||||
|
||||
/* Allocates an area of "size" bytes in memory
|
||||
* and returns a pointer to this area.
|
||||
*/
|
||||
area_t getarea(unsigned int size);
|
||||
/* Frees an area of memory of "size" bytes. */
|
||||
void freearea(register area_t ptr, unsigned int size);
|
||||
|
||||
#ifdef MEMUSE
|
||||
void memuse(void);
|
||||
#endif
|
||||
|
||||
#endif /* ASSCM_H_ */
|
|
@ -5,11 +5,6 @@
|
|||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
static char rcs_ass[]= RCS_ASS ;
|
||||
static char rcs_ex[] = RCS_EX ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global data
|
||||
|
|
145
util/ass/assex.h
145
util/ass/assex.h
|
@ -6,7 +6,7 @@
|
|||
* global data
|
||||
*/
|
||||
|
||||
#define RCS_EX "$Id$"
|
||||
#include <stdio.h>
|
||||
|
||||
extern int wordsize;
|
||||
extern int ptrsize;
|
||||
|
@ -122,31 +122,126 @@ extern char *opindex[] ;
|
|||
extern char opchoice[] ;
|
||||
extern int maxinsl ;
|
||||
|
||||
/*
|
||||
* types of value returning routines
|
||||
/* Generate temporary filename. Fatal error in case of error. */
|
||||
extern char *tmpfil(void);
|
||||
|
||||
|
||||
/* Read next byte from "af" file, fatal error if there isn't one. */
|
||||
extern int xgetc(register FILE *af);
|
||||
/* Read a value of length "l" bytes from file "f",
|
||||
* fatal error if cannot be read.
|
||||
*/
|
||||
#ifndef CPM
|
||||
extern int tmpfil();
|
||||
extern FILE *frewind();
|
||||
#endif
|
||||
extern int xgetc();
|
||||
extern unsigned get8();
|
||||
extern int get16();
|
||||
extern cons_t get32();
|
||||
extern cons_t xgeta();
|
||||
extern cons_t parval();
|
||||
extern cons_t valsize();
|
||||
extern cons_t xgetarb();
|
||||
extern cons_t xgetarb(int l,FILE *f);
|
||||
/* Read the pointer constant a from file "f".
|
||||
* NOTE: The bytes were written low to high (little-endian).
|
||||
*/
|
||||
extern cons_t xgeta(FILE* f);
|
||||
|
||||
|
||||
|
||||
/* Output one byte into file "af" and fatal error if it gives an error */
|
||||
extern void xputc(int c,register FILE *af);
|
||||
/* Output a 16-bit value into file "f" in little-endian, fatal error if it gives an error. */
|
||||
extern void xput16(int w,FILE *f);
|
||||
/* Output a value of "l" bytes into file "f" and fatal error if it gives an error. */
|
||||
extern void xputarb(int l,cons_t w, FILE* f);
|
||||
/* Assemble the pointer constant a into file "f".
|
||||
* NOTE: The bytes are written low to high (little-endian).
|
||||
*/
|
||||
extern void xputa(cons_t a,FILE* f);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Write a byte value into the code temporary file. */
|
||||
extern void put8(int n);
|
||||
/* Write a 16-bit value into the code temporary file. */
|
||||
extern void put16(int n);
|
||||
/* Write a 32-bit value into the code temporary file. */
|
||||
extern void put32(cons_t n);
|
||||
/* Write a 64-bit value into the code temporary file. */
|
||||
extern void put64(cons_t n);
|
||||
|
||||
|
||||
/* Read a byte from the input file, return EOF upon error of EOF */
|
||||
extern int xget8(void);
|
||||
/* Read a byte from the input file, fatal error upon error or EOF. */
|
||||
extern unsigned int get8(void);
|
||||
/* Read a signed 16-bit value from the input file. Raise
|
||||
* a fatal error upon error or end of stream.
|
||||
*/
|
||||
extern int get16(void);
|
||||
/* Read an unsigned 16-bit value from the input file. Raise
|
||||
* a fatal error upon error or end of stream.
|
||||
*/
|
||||
extern int getu16(void);
|
||||
/* Read a 32-bit value from the input file. Raise
|
||||
* a fatal error upon error or end of stream.
|
||||
*/
|
||||
extern cons_t get32(void);
|
||||
|
||||
|
||||
|
||||
/* Write a byte to the data file. */
|
||||
extern void ext8(int b);
|
||||
/* Write a 16-bit value to the data file.
|
||||
* The value is written from low to high (little-endian)
|
||||
*/
|
||||
extern void extword(cons_t w);
|
||||
/* Write "value" of "size" bytes to the data file. The bytes
|
||||
* are written low to high.
|
||||
*/
|
||||
extern void extarb(int size, long value);
|
||||
/* Write pointer "a". The bytes are
|
||||
* written from low to high to the data file.
|
||||
*/
|
||||
extern void extadr(cons_t a);
|
||||
|
||||
|
||||
|
||||
/* Returns the opcode length in bytes */
|
||||
extern int oplength(int);
|
||||
extern void genop(char *,cons_t,int );
|
||||
|
||||
extern void putblk(register FILE *stream,register char *from, register int amount);
|
||||
extern int getblk(register FILE *stream, register char *from, register int amount);
|
||||
|
||||
|
||||
extern void set_mode(int mode);
|
||||
|
||||
/* Dump current information to screen if dump flag is enabled. */
|
||||
void dump(int n);
|
||||
|
||||
/*
|
||||
extern char *findnop();
|
||||
extern char *findfit();
|
||||
extern glob_t *glolookup();
|
||||
extern glob_t *glo2lookup();
|
||||
extern glob_t *xglolookup();
|
||||
extern locl_t *loclookup();
|
||||
extern proc_t *prolookup();
|
||||
extern proc_t *enterproc();
|
||||
extern proc_t *searchproc();
|
||||
extern relc_t *text_reloc();
|
||||
extern relc_t *data_reloc();
|
||||
extern area_t getarea();
|
||||
|
||||
*/
|
||||
extern glob_t *glolookup(char *name,int status,glob_t *table, int size);
|
||||
extern proc_t *searchproc(char *name,proc_t *table,int size);
|
||||
extern glob_t *glo2lookup(char *name ,int status);
|
||||
extern glob_t *xglolookup(char *name,int status);
|
||||
extern proc_t *prolookup(char *name,int status);
|
||||
extern locl_t *loclookup(unsigned int an,int status);
|
||||
extern proc_t *enterproc(char *name,int status,proc_t *place);
|
||||
extern cons_t parval(line_t *lnp,char *defined);
|
||||
|
||||
|
||||
extern void determine_props(line_t *lnp, int *min_len, int *max_len);
|
||||
extern int opfit(int flag,int number,cons_t val,int i_flag);
|
||||
|
||||
extern void initproc(void);
|
||||
extern void endproc(void);
|
||||
extern void init_files(void);
|
||||
extern void init_module(void);
|
||||
extern void end_module(void);
|
||||
extern void do_proc(void);
|
||||
extern void ertrap(void);
|
||||
extern void init_vars(void);
|
||||
|
||||
extern void error(const char* string1, ...);
|
||||
extern void werror(const char* string1, ...);
|
||||
extern void fatal(char *s);
|
||||
|
||||
|
||||
|
|
184
util/ass/assrl.c
184
util/ass/assrl.c
|
@ -4,12 +4,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "asscm.h"
|
||||
#include "assrl.h"
|
||||
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
#define COPYFINAL 1
|
||||
#define COPYTEMP 0
|
||||
|
@ -18,10 +19,12 @@ static char rcs_id[] = "$Id$" ;
|
|||
* collection of routines to deal with relocation business
|
||||
*/
|
||||
|
||||
void dataprocess();
|
||||
void textprocess();
|
||||
relc_t *
|
||||
text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
||||
|
||||
static void dataprocess(FILE *, FILE *);
|
||||
static void textprocess(FILE *, FILE *);
|
||||
|
||||
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ)
|
||||
{
|
||||
|
||||
/*
|
||||
* prepare the relocation that has to be done at text-offset off
|
||||
|
@ -36,9 +39,12 @@ text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
|||
register relc_t *nxtextreloc;
|
||||
|
||||
nxtextreloc = rlp_cast getarea(sizeof *nxtextreloc);
|
||||
if ( !f_text ) {
|
||||
if (!f_text)
|
||||
{
|
||||
f_text = nxtextreloc;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
l_text->r_next = nxtextreloc;
|
||||
}
|
||||
nxtextreloc->r_next = rlp_cast 0;
|
||||
|
@ -49,8 +55,8 @@ text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
|||
return (nxtextreloc);
|
||||
}
|
||||
|
||||
relc_t *
|
||||
data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; {
|
||||
relc_t * data_reloc(char *arg ,FOFFSET off, int typ)
|
||||
{
|
||||
|
||||
/*
|
||||
* Same as above.
|
||||
|
@ -59,9 +65,12 @@ data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; {
|
|||
register relc_t *nxdatareloc;
|
||||
|
||||
nxdatareloc = rlp_cast getarea(sizeof *nxdatareloc);
|
||||
if ( !f_data ) {
|
||||
if (!f_data)
|
||||
{
|
||||
f_data = nxdatareloc;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
l_data->r_next = nxdatareloc;
|
||||
}
|
||||
nxdatareloc->r_next = rlp_cast 0;
|
||||
|
@ -72,8 +81,9 @@ data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; {
|
|||
return (nxdatareloc);
|
||||
}
|
||||
|
||||
copyout() {
|
||||
register i;
|
||||
void copyout(void)
|
||||
{
|
||||
register int i;
|
||||
int remtext;
|
||||
|
||||
/*
|
||||
|
@ -114,17 +124,15 @@ copyout() {
|
|||
*/
|
||||
|
||||
remtext = textbytes % wordsize;
|
||||
if ( remtext != 0 ) remtext = wordsize-remtext ;
|
||||
if (remtext != 0)
|
||||
remtext = wordsize - remtext;
|
||||
|
||||
if ((ifile = fopen(eout, "w")) == 0)
|
||||
fatal("can't create e.out");
|
||||
#ifdef CPM
|
||||
fclose(tfile); tfile=fopen("TFILE.$$$", "r");
|
||||
fclose(dfile); dfile=fopen("DFILE.$$$", "r");
|
||||
#else
|
||||
tfile=frewind(tfile);
|
||||
dfile=frewind(dfile);
|
||||
#endif
|
||||
|
||||
rewind(tfile);
|
||||
rewind(dfile);
|
||||
|
||||
xput16(as_magic, ifile);
|
||||
xput16(intflags, ifile);
|
||||
xput16(unresolved, ifile);
|
||||
|
@ -136,99 +144,110 @@ copyout() {
|
|||
xputa(textbytes + remtext, ifile);
|
||||
xputa((cons_t) datablocks, ifile);
|
||||
xputa((cons_t) procnum, ifile);
|
||||
xputa((cons_t)searchproc(MAIN,xprocs,oursize->n_xproc)->p_num,
|
||||
ifile);
|
||||
xputa((cons_t) searchproc(MAIN, xprocs, oursize->n_xproc)->p_num, ifile);
|
||||
xputa((cons_t) sourcelines, ifile);
|
||||
xputa((cons_t) databytes, ifile);
|
||||
xputa((cons_t) 0, ifile);
|
||||
xputa((cons_t) 0, ifile);
|
||||
|
||||
textprocess(tfile, ifile);
|
||||
while ( remtext-- ) xputc(0,ifile) ;
|
||||
while (remtext--)
|
||||
xputc(0, ifile);
|
||||
|
||||
dataprocess(dfile, ifile);
|
||||
for (i=0;i<procnum;i++) {
|
||||
for (i = 0; i < procnum; i++)
|
||||
{
|
||||
xputarb(ptrsize, proctab[i].pr_loc, ifile);
|
||||
xputarb(ptrsize, proctab[i].pr_off, ifile);
|
||||
}
|
||||
if ( fclose(ifile)==EOF ) ;
|
||||
if (fclose(ifile) == EOF)
|
||||
;
|
||||
}
|
||||
|
||||
void dataprocess(f1,f2) FILE *f1,*f2; {
|
||||
static void dataprocess(FILE *f1, FILE *outf)
|
||||
{
|
||||
relc_t datareloc;
|
||||
FOFFSET i;
|
||||
register ieof ;
|
||||
register int ieof;
|
||||
|
||||
#ifdef CPM
|
||||
fclose(rdfile); rdfile=fopen("RDFILE.$$$", "r");
|
||||
#else
|
||||
rdfile=frewind(rdfile) ;
|
||||
#endif
|
||||
rewind(rdfile);
|
||||
ieof = getblk(rdfile, (char *) (&datareloc.r_off),
|
||||
sizeof datareloc - sizeof datareloc.r_next);
|
||||
for (i=0 ; i<dataoff && !ieof ; i++) {
|
||||
if (i==datareloc.r_off) {
|
||||
switch(datareloc.r_typ) {
|
||||
for (i = 0; i < dataoff && !ieof; i++)
|
||||
{
|
||||
if (i == datareloc.r_off)
|
||||
{
|
||||
switch (datareloc.r_typ)
|
||||
{
|
||||
case RELADR:
|
||||
xputa(xgeta(f1)+datareloc.r_val.rel_i,f2) ;
|
||||
xputa(xgeta(f1) + datareloc.r_val.rel_i, outf);
|
||||
i += ptrsize - 1;
|
||||
break;
|
||||
case RELGLO:
|
||||
if (datareloc.r_val.rel_gp->g_status&DEF) {
|
||||
xputa(xgeta(f1)+
|
||||
datareloc.r_val.rel_gp->g_val.g_addr,
|
||||
f2);
|
||||
if (datareloc.r_val.rel_gp->g_status & DEF)
|
||||
{
|
||||
xputa(xgeta(f1) + datareloc.r_val.rel_gp->g_val.g_addr, outf);
|
||||
i += ptrsize - 1;
|
||||
break;
|
||||
}
|
||||
if (unresolved == 0)
|
||||
fatal("Definition botch");
|
||||
case RELHEAD:
|
||||
xputc((int)(xgetc(f1)+datareloc.r_val.rel_i),
|
||||
f2);
|
||||
xputc((int) (xgetc(f1) + datareloc.r_val.rel_i), outf);
|
||||
break;
|
||||
default:
|
||||
fatal("Bad r_typ in dataprocess");
|
||||
}
|
||||
ieof = getblk(rdfile, (char *) (&datareloc.r_off),
|
||||
sizeof datareloc - sizeof datareloc.r_next);
|
||||
} else
|
||||
xputc(xgetc(f1),f2);
|
||||
}
|
||||
for ( ; i<dataoff ; i++ ) xputc(xgetc(f1),f2) ;
|
||||
else
|
||||
xputc(xgetc(f1), outf);
|
||||
}
|
||||
for (; i < dataoff; i++)
|
||||
xputc(xgetc(f1), outf);
|
||||
if (!ieof && !getblk(rdfile, (char *) &datareloc, 1))
|
||||
fatal("data relocation botch");
|
||||
}
|
||||
|
||||
void textprocess(f1,f2) FILE *f1,*f2; {
|
||||
static void textprocess(FILE *f1, FILE *outf)
|
||||
{
|
||||
relc_t textreloc;
|
||||
cons_t n;
|
||||
FOFFSET i;
|
||||
FILE *otfile;
|
||||
int insl ; register int ieof ;
|
||||
int insl;
|
||||
register int ieof;
|
||||
char *op_curr;
|
||||
register FOFFSET keep;
|
||||
|
||||
#ifdef CPM
|
||||
fclose(rtfile); rtfile=fopen("RTFILE.$$$", "r");
|
||||
#else
|
||||
rtfile=frewind(rtfile) ;
|
||||
#endif
|
||||
keep = textoff ; textoff=0 ; otfile=tfile ; tfile=f2 ;
|
||||
rewind(rtfile);
|
||||
keep = textoff;
|
||||
textoff = 0;
|
||||
otfile = tfile;
|
||||
tfile = outf;
|
||||
/* This redirects the output of genop */
|
||||
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
|
||||
sizeof textreloc - sizeof textreloc.r_next);
|
||||
for(i=0;i<keep && !ieof ;i++) {
|
||||
if( i == textreloc.r_off ) {
|
||||
if (textreloc.r_typ&RELMNS) {
|
||||
for (i = 0; i < keep && !ieof; i++)
|
||||
{
|
||||
if (i == textreloc.r_off)
|
||||
{
|
||||
if (textreloc.r_typ & RELMNS)
|
||||
{
|
||||
n = textreloc.r_val.rel_i;
|
||||
} else {
|
||||
if (textreloc.r_val.rel_gp->g_status&DEF) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (textreloc.r_val.rel_gp->g_status & DEF)
|
||||
{
|
||||
n = textreloc.r_val.rel_gp->g_val.g_addr;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unresolved == 0)
|
||||
fatal("Definition botch");
|
||||
xputc(xgetc(f1),f2) ;
|
||||
xputc(xgetc(f1), outf);
|
||||
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
|
||||
sizeof textreloc - sizeof textreloc.r_next);
|
||||
continue;
|
||||
|
@ -240,18 +259,22 @@ void textprocess(f1,f2) FILE *f1,*f2; {
|
|||
i += insl - 1;
|
||||
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
|
||||
sizeof textreloc - sizeof textreloc.r_next);
|
||||
} else {
|
||||
xputc(xgetc(f1),f2) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
xputc(xgetc(f1), outf);
|
||||
}
|
||||
}
|
||||
for ( ; i<keep ; i++ ) xputc(xgetc(f1),f2) ;
|
||||
for (; i < keep; i++)
|
||||
xputc(xgetc(f1), outf);
|
||||
if (!ieof && !getblk(rtfile, (char *) &textreloc, 1))
|
||||
fatal("text relocation botch");
|
||||
textoff = keep;
|
||||
tfile = otfile;
|
||||
}
|
||||
|
||||
upd_reloc() {
|
||||
void upd_reloc(void)
|
||||
{
|
||||
register relc_t *p;
|
||||
register glob_t *gbp;
|
||||
|
||||
|
@ -264,28 +287,37 @@ upd_reloc() {
|
|||
* see also getcore()
|
||||
*/
|
||||
|
||||
while ( p= f_text ) {
|
||||
while ( (p = f_text) != NULL)
|
||||
{
|
||||
gbp = p->r_val.rel_gp;
|
||||
if( gbp->g_status&DEF ) {
|
||||
if (gbp->g_status & DEF)
|
||||
{
|
||||
p->r_typ |= RELMNS;
|
||||
p->r_val.rel_i = gbp->g_val.g_addr;
|
||||
} else
|
||||
}
|
||||
else
|
||||
p->r_val.rel_gp = gbp->g_val.g_gp;
|
||||
putblk(rtfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
|
||||
f_text= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
|
||||
f_text = p->r_next;
|
||||
freearea((area_t) p, sizeof *p);
|
||||
}
|
||||
|
||||
while( p= f_data ) {
|
||||
if (p->r_typ == RELGLO) {
|
||||
while ( (p = f_data) != NULL)
|
||||
{
|
||||
if (p->r_typ == RELGLO)
|
||||
{
|
||||
gbp = p->r_val.rel_gp;
|
||||
if(gbp->g_status&DEF) {
|
||||
if (gbp->g_status & DEF)
|
||||
{
|
||||
p->r_typ = RELADR;
|
||||
p->r_val.rel_i = gbp->g_val.g_addr;
|
||||
} else
|
||||
}
|
||||
else
|
||||
p->r_val.rel_gp = gbp->g_val.g_gp;
|
||||
}
|
||||
putblk(rdfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
|
||||
f_data= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
|
||||
f_data = p->r_next;
|
||||
freearea((area_t) p, sizeof *p);
|
||||
}
|
||||
l_data = rlp_cast 0;
|
||||
}
|
||||
|
|
21
util/ass/assrl.h
Normal file
21
util/ass/assrl.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Copyright (c) 2019 ACK Project.
|
||||
* See the copyright notice in the ACK home directory,
|
||||
* in the file "Copyright".
|
||||
*
|
||||
* Created on: 2019-03-13
|
||||
*
|
||||
*/
|
||||
#ifndef ASSRL_H_
|
||||
#define ASSRL_H_
|
||||
|
||||
/* Generates an e.out file from the the temporary code file "tfile" and
|
||||
* data temporary "dfile" file. Output the data to "ifile".
|
||||
*/
|
||||
void copyout(void);
|
||||
/* Update the relocation entries and place them into "rtfile" and "rdfile". */
|
||||
void upd_reloc(void);
|
||||
|
||||
relc_t * data_reloc(char *arg ,FOFFSET off, int typ);
|
||||
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ);
|
||||
|
||||
#endif /* ASSRL_H_ */
|
|
@ -36,7 +36,7 @@ cprogram {
|
|||
"modules/src/em_data+lib",
|
||||
--"modules/src/data+lib",
|
||||
--"modules/src/object+lib",
|
||||
--"modules/src/system+lib",
|
||||
"modules/src/system+lib",
|
||||
"./ass*.h",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ produced code the only messages to expect are "Out of memory"
|
|||
or of the
|
||||
form: Overflow in XXXX. The latter can usually be cured by giving
|
||||
a -sx flag,
|
||||
the former means the program is too big, dimishing
|
||||
the former means the program is too big, diminishing
|
||||
the size of very large procedures can sometimes help.
|
||||
The most likely errors, however, are unresolved references,
|
||||
probably caused by the omission of a library argument.
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
|
||||
#include "ip_spec.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <em_spec.h>
|
||||
#include <em_flag.h>
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
/* This program reads the human readable interpreter specification
|
||||
and produces a efficient machine representation that can be
|
||||
translated by a C-compiler.
|
||||
|
@ -35,64 +34,100 @@ char esca[] = "escape" ;
|
|||
|
||||
extern char em_flag[];
|
||||
|
||||
main(argc,argv) char **argv ; {
|
||||
if ( argc>1 ) {
|
||||
if ( freopen(argv[1],"r",stdin)==NULL) {
|
||||
|
||||
/* Forward declarations */
|
||||
static int readchar(void);
|
||||
static void pushback(int);
|
||||
static void readin(void);
|
||||
static char *ident(void);
|
||||
static int getmnem(char *);
|
||||
static void writeout(void);
|
||||
static void checkall(void);
|
||||
static void chkc(int, int, int);
|
||||
static void ckop(int, int, int, int);
|
||||
static int oplength(struct opform *);
|
||||
static void check(int);
|
||||
static int decflag(char *);
|
||||
int compare(const void *, const void *);
|
||||
|
||||
static void error(char *format, ...);
|
||||
static void mess(char *format, ...);
|
||||
static void fatal(char *format, ...);
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
if (freopen(argv[1], "r", stdin) == NULL)
|
||||
{
|
||||
fatal("Cannot open %s", argv[1]);
|
||||
}
|
||||
}
|
||||
if ( argc>2 ) {
|
||||
if ( freopen(argv[2],"w",stdout)==NULL) {
|
||||
if (argc > 2)
|
||||
{
|
||||
if (freopen(argv[2], "w", stdout) == NULL)
|
||||
{
|
||||
fatal("Cannot create %s", argv[2]);
|
||||
}
|
||||
}
|
||||
if ( argc>3 ) {
|
||||
if (argc > 3)
|
||||
{
|
||||
fatal("%s [ file [ file ] ]", argv[0]);
|
||||
}
|
||||
atend = 0;
|
||||
readin();
|
||||
atend = 1;
|
||||
checkall();
|
||||
if ( nerror==0 ) {
|
||||
if (nerror == 0)
|
||||
{
|
||||
writeout();
|
||||
}
|
||||
exit(nerror);
|
||||
}
|
||||
|
||||
readin() {
|
||||
static void readin(void)
|
||||
{
|
||||
register struct opform *nextform;
|
||||
char *ident();
|
||||
char *firstid;
|
||||
register maxl ;
|
||||
register int maxl;
|
||||
|
||||
maxl = 0;
|
||||
for ( nextform=intable ;
|
||||
!feof(stdin) && nextform<&intable[NOTAB] ; ) {
|
||||
for (nextform = intable; !feof(stdin) && nextform < &intable[NOTAB];)
|
||||
{
|
||||
firstid = ident();
|
||||
if ( *firstid=='\n' || feof(stdin) ) continue ;
|
||||
if (*firstid == '\n' || feof(stdin))
|
||||
continue;
|
||||
lastform = nextform;
|
||||
nextform->i_opcode = getmnem(firstid);
|
||||
nextform->i_flag = decflag(ident());
|
||||
switch ( nextform->i_flag&OPTYPE ) {
|
||||
switch (nextform->i_flag & OPTYPE)
|
||||
{
|
||||
case OPMINI:
|
||||
case OPSHORT:
|
||||
nextform->i_num = atoi(ident());
|
||||
break;
|
||||
}
|
||||
nextform->i_low = atoi(ident());
|
||||
if ( *ident()!='\n' ) {
|
||||
if (*ident() != '\n')
|
||||
{
|
||||
int c;
|
||||
error("End of line expected");
|
||||
while ( (c=readchar())!='\n' && c!=EOF ) ;
|
||||
while ((c = readchar()) != '\n' && c != EOF)
|
||||
;
|
||||
}
|
||||
if ( oplength(nextform)>maxl ) maxl=oplength(nextform) ;
|
||||
if (oplength(nextform) > maxl)
|
||||
maxl = oplength(nextform);
|
||||
nextform++;
|
||||
}
|
||||
if ( !feof(stdin) ) fatal("Internal table too small") ;
|
||||
if (!feof(stdin))
|
||||
fatal("Internal table too small");
|
||||
maxinsl = maxl;
|
||||
}
|
||||
|
||||
char *ident() {
|
||||
static char *ident(void)
|
||||
{
|
||||
/* skip spaces and tabs, anything up to space,tab or eof is
|
||||
a identifier.
|
||||
Anything from # to end-of-line is an end-of-line.
|
||||
|
@ -103,63 +138,96 @@ char *ident() {
|
|||
register int c;
|
||||
register char *cc;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
c = readchar();
|
||||
} while (c == ' ' || c == '\t');
|
||||
for ( cc=array ; cc<&array[(sizeof array) - 1] ; cc++ ) {
|
||||
if ( c=='#' ) {
|
||||
do {
|
||||
for (cc = array; cc < &array[(sizeof array) - 1]; cc++)
|
||||
{
|
||||
if (c == '#')
|
||||
{
|
||||
do
|
||||
{
|
||||
c = readchar();
|
||||
} while (c != '\n' && c != EOF);
|
||||
}
|
||||
*cc = c;
|
||||
if ( c=='\n' && cc==array ) break ;
|
||||
if (c == '\n' && cc == array)
|
||||
break;
|
||||
c = readchar();
|
||||
if ( c=='\n' ) {
|
||||
if (c == '\n')
|
||||
{
|
||||
pushback(c);
|
||||
break;
|
||||
}
|
||||
if ( c==' ' || c=='\t' || c==EOF ) break ;
|
||||
if (c == ' ' || c == '\t' || c == EOF)
|
||||
break;
|
||||
}
|
||||
*++cc = 0;
|
||||
return array;
|
||||
}
|
||||
|
||||
int getmnem(str) char *str ; {
|
||||
static int getmnem(char *str)
|
||||
{
|
||||
char (*ptr)[4];
|
||||
|
||||
for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem-sp_fmnem][0] ; ptr++ ) {
|
||||
if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ;
|
||||
for (ptr = em_mnem; *ptr <= &em_mnem[sp_lmnem - sp_fmnem][0]; ptr++)
|
||||
{
|
||||
if (strcmp(*ptr, str) == 0)
|
||||
return (ptr - em_mnem);
|
||||
}
|
||||
error("Illegal mnemonic");
|
||||
return 0;
|
||||
}
|
||||
|
||||
error(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
|
||||
if ( !atend ) fprintf(stderr,"line %d: ",line) ;
|
||||
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
|
||||
/* VARARGS1 */
|
||||
static void error(char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
if (!atend)
|
||||
fprintf(stderr, "line %d: ", line);
|
||||
va_start(argptr, format);
|
||||
vfprintf(stderr, format, argptr);
|
||||
va_end(argptr);
|
||||
fprintf(stderr, "\n");
|
||||
nerror++;
|
||||
}
|
||||
|
||||
mess(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
|
||||
if ( !atend ) fprintf(stderr,"line %d: ",line) ;
|
||||
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
|
||||
/* VARARGS1 */
|
||||
static void mess(char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
if (!atend)
|
||||
fprintf(stderr, "line %d: ", line);
|
||||
va_start(argptr, format);
|
||||
vfprintf(stderr, format, argptr);
|
||||
va_end(argptr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fatal(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
|
||||
error(str,a1,a2,a3,a4,a5,a6) ;
|
||||
exit(1) ;
|
||||
/* VARARGS1 */
|
||||
static void fatal(char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
if (!atend)
|
||||
fprintf(stderr, "line %d: ", line);
|
||||
va_start(argptr, format);
|
||||
vfprintf(stderr, format, argptr);
|
||||
va_end(argptr);
|
||||
fprintf(stderr, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define ILLGL -1
|
||||
|
||||
check(val) int val ; {
|
||||
if ( val!=ILLGL ) error("Illegal flag combination") ;
|
||||
static void check(int val)
|
||||
{
|
||||
if (val != ILLGL)
|
||||
error("Illegal flag combination");
|
||||
}
|
||||
|
||||
int decflag(str) char *str ; {
|
||||
static int decflag(char *str)
|
||||
{
|
||||
int type;
|
||||
int escape;
|
||||
int range;
|
||||
|
@ -167,83 +235,128 @@ int decflag(str) char *str ; {
|
|||
int notzero;
|
||||
|
||||
type = escape = range = wordm = notzero = ILLGL;
|
||||
while ( *str ) switch ( *str++ ) {
|
||||
while (*str)
|
||||
switch (*str++)
|
||||
{
|
||||
case 'm':
|
||||
check(type) ; type=OPMINI ; break ;
|
||||
check(type);
|
||||
type = OPMINI;
|
||||
break;
|
||||
case 's':
|
||||
check(type) ; type=OPSHORT ; break ;
|
||||
check(type);
|
||||
type = OPSHORT;
|
||||
break;
|
||||
case '-':
|
||||
check(type) ; type=OPNO ; break ;
|
||||
check(type);
|
||||
type = OPNO;
|
||||
break;
|
||||
case '1':
|
||||
check(type) ; type=OP8 ; break ;
|
||||
check(type);
|
||||
type = OP8;
|
||||
break;
|
||||
case '2':
|
||||
check(type) ; type=OP16 ; break ;
|
||||
check(type);
|
||||
type = OP16;
|
||||
break;
|
||||
case '4':
|
||||
check(type) ; type=OP32 ; break ;
|
||||
check(type);
|
||||
type = OP32;
|
||||
break;
|
||||
case '8':
|
||||
check(type) ; type=OP64 ; break ;
|
||||
check(type);
|
||||
type = OP64;
|
||||
break;
|
||||
case 'u':
|
||||
check(type) ; type=OP16U ; break ;
|
||||
check(type);
|
||||
type = OP16U;
|
||||
break;
|
||||
case 'e':
|
||||
check(escape) ; escape=0 ; break ;
|
||||
check(escape);
|
||||
escape = 0;
|
||||
break;
|
||||
case 'N':
|
||||
check(range) ; range= 2 ; break ;
|
||||
check(range);
|
||||
range = 2;
|
||||
break;
|
||||
case 'P':
|
||||
check(range) ; range= 1 ; break ;
|
||||
check(range);
|
||||
range = 1;
|
||||
break;
|
||||
case 'w':
|
||||
check(wordm) ; wordm=0 ; break ;
|
||||
check(wordm);
|
||||
wordm = 0;
|
||||
break;
|
||||
case 'o':
|
||||
check(notzero) ; notzero=0 ; break ;
|
||||
check(notzero);
|
||||
notzero = 0;
|
||||
break;
|
||||
default:
|
||||
error("Unknown flag");
|
||||
}
|
||||
if ( type==ILLGL ) error("Type must be specified") ;
|
||||
switch ( type ) {
|
||||
if (type == ILLGL)
|
||||
error("Type must be specified");
|
||||
switch (type)
|
||||
{
|
||||
case OP64:
|
||||
case OP32:
|
||||
if ( escape!=ILLGL ) error("Conflicting escapes") ;
|
||||
if (escape != ILLGL)
|
||||
error("Conflicting escapes");
|
||||
escape = ILLGL;
|
||||
case OP16:
|
||||
case OP16U:
|
||||
case OP8:
|
||||
case OPSHORT:
|
||||
case OPNO:
|
||||
if ( notzero!=ILLGL ) mess("Improbable OPNZ") ;
|
||||
if ( type==OPNO && range!=ILLGL ) {
|
||||
if (notzero != ILLGL)
|
||||
mess("Improbable OPNZ");
|
||||
if (type == OPNO && range != ILLGL)
|
||||
{
|
||||
mess("No operand in range");
|
||||
}
|
||||
}
|
||||
if ( escape!=ILLGL ) type|=OPESC ;
|
||||
if ( wordm!=ILLGL ) type|=OPWORD ;
|
||||
switch ( range) {
|
||||
case ILLGL : type|=OP_BOTH ;
|
||||
if (escape != ILLGL)
|
||||
type |= OPESC;
|
||||
if (wordm != ILLGL)
|
||||
type |= OPWORD;
|
||||
switch (range)
|
||||
{
|
||||
case ILLGL:
|
||||
type |= OP_BOTH;
|
||||
if (type == OPMINI || type == OPSHORT)
|
||||
error("Minies and shorties must have P or N");
|
||||
break;
|
||||
case 1 : type|=OP_POS ; break ;
|
||||
case 2 : type|=OP_NEG ; break ;
|
||||
case 1:
|
||||
type |= OP_POS;
|
||||
break;
|
||||
case 2:
|
||||
type |= OP_NEG;
|
||||
break;
|
||||
}
|
||||
if ( notzero!=ILLGL ) type|=OPNZ ;
|
||||
if (notzero != ILLGL)
|
||||
type |= OPNZ;
|
||||
return type;
|
||||
}
|
||||
|
||||
writeout() {
|
||||
static void writeout(void)
|
||||
{
|
||||
register struct opform *next;
|
||||
int elem[sp_lmnem - sp_fmnem + 1 + 1];
|
||||
/* for each op points to first of descr. */
|
||||
register int i, currop;
|
||||
int nch;
|
||||
int compare() ;
|
||||
|
||||
qsort(intable, (lastform - intable) + 1, sizeof intable[0], compare);
|
||||
|
||||
printf("int\tmaxinsl\t= %d ;\n", maxinsl);
|
||||
currop= -1 ; nch=0 ;
|
||||
currop = -1;
|
||||
nch = 0;
|
||||
printf("char opchoice[] = {\n");
|
||||
for (next=intable ; next<=lastform ; next++ ) {
|
||||
if ( (next->i_opcode&0377)!=currop ) {
|
||||
for ( currop++ ;
|
||||
currop<(next->i_opcode&0377) ; currop++ ) {
|
||||
for (next = intable; next <= lastform; next++)
|
||||
{
|
||||
if ((next->i_opcode & 0377) != currop)
|
||||
{
|
||||
for (currop++; currop < (next->i_opcode & 0377); currop++)
|
||||
{
|
||||
elem[currop] = nch;
|
||||
error("Missing opcode %s", em_mnem[currop]);
|
||||
}
|
||||
|
@ -251,46 +364,67 @@ writeout() {
|
|||
}
|
||||
printf("%d, %d,", next->i_flag & 0377, next->i_low & 0377);
|
||||
nch += 2;
|
||||
switch ( next->i_flag&OPTYPE ) {
|
||||
switch (next->i_flag & OPTYPE)
|
||||
{
|
||||
case OPMINI:
|
||||
case OPSHORT:
|
||||
printf("%d,",next->i_num&0377) ; nch++ ;
|
||||
printf("%d,", next->i_num & 0377);
|
||||
nch++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
for ( currop++ ; currop<=sp_lmnem-sp_fmnem ; currop++ ) {
|
||||
for (currop++; currop <= sp_lmnem - sp_fmnem; currop++)
|
||||
{
|
||||
elem[currop] = nch;
|
||||
error("Missing opcode %s", em_mnem[currop]);
|
||||
}
|
||||
elem[sp_lmnem - sp_fmnem + 1] = nch;
|
||||
printf("0 } ;\n\nchar *opindex[] = {\n");
|
||||
for ( i=0 ; i<=sp_lmnem-sp_fmnem+1 ; i++ ) {
|
||||
for (i = 0; i <= sp_lmnem - sp_fmnem + 1; i++)
|
||||
{
|
||||
printf(" &opchoice[%d], /* %d = %s */\n", elem[i], i, em_mnem[i]);
|
||||
}
|
||||
printf("} ;\n");
|
||||
}
|
||||
|
||||
int compare(a,b) struct opform *a,*b ; {
|
||||
if ( a->i_opcode!=b->i_opcode ) {
|
||||
int compare(const void *a1, const void *b1)
|
||||
{
|
||||
struct opform *a = (struct opform *)(a1);
|
||||
struct opform *b = (struct opform *)(b1);
|
||||
|
||||
if (a->i_opcode != b->i_opcode)
|
||||
{
|
||||
return (a->i_opcode & 0377) - (b->i_opcode & 0377);
|
||||
}
|
||||
return oplength(a) - oplength(b);
|
||||
}
|
||||
|
||||
int oplength(a) struct opform *a ; {
|
||||
static int oplength(struct opform *a)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
cnt = 1;
|
||||
if ( a->i_flag&OPESC ) cnt++ ;
|
||||
switch( a->i_flag&OPTYPE ) {
|
||||
if (a->i_flag & OPESC)
|
||||
cnt++;
|
||||
switch (a->i_flag & OPTYPE)
|
||||
{
|
||||
case OPNO:
|
||||
case OPMINI : break ;
|
||||
case OPMINI:
|
||||
break;
|
||||
case OP8:
|
||||
case OPSHORT : cnt++ ; break ;
|
||||
case OPSHORT:
|
||||
cnt++;
|
||||
break;
|
||||
case OP16U:
|
||||
case OP16 : cnt+=2 ; break ;
|
||||
case OP32 : cnt+=5 ; break ;
|
||||
case OP64 : cnt+=9 ; break ;
|
||||
case OP16:
|
||||
cnt += 2;
|
||||
break;
|
||||
case OP32:
|
||||
cnt += 5;
|
||||
break;
|
||||
case OP64:
|
||||
cnt += 9;
|
||||
break;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
@ -306,31 +440,40 @@ int ecodes[256],codes[256],lcodes[256] ;
|
|||
|
||||
char negc[NMNEM], zc[NMNEM], posc[NMNEM];
|
||||
|
||||
checkall() {
|
||||
register i,flag ;
|
||||
static void checkall(void)
|
||||
{
|
||||
register int i, flag;
|
||||
register struct opform *next;
|
||||
int opc, low;
|
||||
|
||||
for ( i=0 ; i<NMNEM ; i++ ) negc[i]=zc[i]=posc[i]=0 ;
|
||||
for ( i=0 ; i<256 ; i++ ) lcodes[i]= codes[i]= ecodes[i]= -1 ;
|
||||
for (i = 0; i < NMNEM; i++)
|
||||
negc[i] = zc[i] = posc[i] = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
lcodes[i] = codes[i] = ecodes[i] = -1;
|
||||
codes[254] = codes[255] = ESCAP;
|
||||
|
||||
atend=0 ; line=0 ;
|
||||
for ( next=intable ; next<=lastform ; next++ ) {
|
||||
atend = 0;
|
||||
line = 0;
|
||||
for (next = intable; next <= lastform; next++)
|
||||
{
|
||||
line++;
|
||||
flag = next->i_flag & 0377;
|
||||
opc = next->i_opcode & 0377;
|
||||
low = next->i_low & 0377;
|
||||
chkc(flag, low, opc);
|
||||
switch(flag&OPTYPE) {
|
||||
case OPNO : zc[opc]++ ; break ;
|
||||
switch (flag & OPTYPE)
|
||||
{
|
||||
case OPNO:
|
||||
zc[opc]++;
|
||||
break;
|
||||
case OPMINI:
|
||||
case OPSHORT:
|
||||
for ( i=1 ; i<((next->i_num)&0377) ; i++ ) {
|
||||
for (i = 1; i < ((next->i_num) & 0377); i++)
|
||||
{
|
||||
chkc(flag, low + i, opc);
|
||||
}
|
||||
if ( !(em_flag[opc]&PAR_G) &&
|
||||
(flag&OPRANGE)==OP_BOTH) {
|
||||
if (!(em_flag[opc] & PAR_G) && (flag & OPRANGE) == OP_BOTH)
|
||||
{
|
||||
mess("Mini's and shorties should have P or N");
|
||||
}
|
||||
break;
|
||||
|
@ -353,11 +496,15 @@ checkall() {
|
|||
}
|
||||
}
|
||||
atend = 1;
|
||||
for ( i=0 ; i<256 ; i++ ) if ( codes[i]== -1 ) {
|
||||
for (i = 0; i < 256; i++)
|
||||
if (codes[i] == -1)
|
||||
{
|
||||
mess("interpreter opcode %d not used", i);
|
||||
}
|
||||
for ( opc=0 ; opc<NMNEM ; opc++ ) {
|
||||
switch(em_flag[opc]&EM_PAR) {
|
||||
for (opc = 0; opc < NMNEM; opc++)
|
||||
{
|
||||
switch (em_flag[opc] & EM_PAR)
|
||||
{
|
||||
case PAR_NO:
|
||||
ckop(opc, MUST, FORB, FORB);
|
||||
break;
|
||||
|
@ -391,56 +538,75 @@ checkall() {
|
|||
}
|
||||
}
|
||||
|
||||
chkc(flag,icode,emc) {
|
||||
if ( flag&OPESC ) {
|
||||
if ( ecodes[icode]!=-1 ) {
|
||||
mess("Escaped opcode %d used by %s and %s",
|
||||
icode,ename(emc),ename(ecodes[icode])) ;
|
||||
static void chkc(int flag, int icode, int emc)
|
||||
{
|
||||
if (flag & OPESC)
|
||||
{
|
||||
if (ecodes[icode] != -1)
|
||||
{
|
||||
mess("Escaped opcode %d used by %s and %s", icode, ename(emc),
|
||||
ename(ecodes[icode]));
|
||||
}
|
||||
ecodes[icode] = emc;
|
||||
} else switch ( flag&OPTYPE ) {
|
||||
}
|
||||
else
|
||||
switch (flag & OPTYPE)
|
||||
{
|
||||
default:
|
||||
if ( codes[icode]!=-1 ) {
|
||||
mess("Opcode %d used by %s and %s",
|
||||
icode,ename(emc),ename(codes[icode])) ;
|
||||
if (codes[icode] != -1)
|
||||
{
|
||||
mess("Opcode %d used by %s and %s", icode, ename(emc),
|
||||
ename(codes[icode]));
|
||||
}
|
||||
codes[icode] = emc;
|
||||
break;
|
||||
case OP32:
|
||||
case OP64:
|
||||
if ( lcodes[icode]!=-1 ) {
|
||||
mess("Long opcode %d used by %s and %s",
|
||||
icode,ename(emc),ename(codes[icode])) ;
|
||||
if (lcodes[icode] != -1)
|
||||
{
|
||||
mess("Long opcode %d used by %s and %s", icode, ename(emc),
|
||||
ename(codes[icode]));
|
||||
}
|
||||
lcodes[icode] = emc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ckop(emc,zf,pf,nf) {
|
||||
if ( zc[emc]>1 ) mess("More then one OPNO for %s",ename(emc)) ;
|
||||
if ( posc[emc]>1 ) mess("More then one OP16(pos) for %s",ename(emc)) ;
|
||||
if ( negc[emc]>1 ) mess("More then one OP16(neg) for %s",ename(emc)) ;
|
||||
switch(zf) {
|
||||
static void ckop(int emc, int zf, int pf, int nf)
|
||||
{
|
||||
if (zc[emc] > 1)
|
||||
mess("More then one OPNO for %s", ename(emc));
|
||||
if (posc[emc] > 1)
|
||||
mess("More then one OP16(pos) for %s", ename(emc));
|
||||
if (negc[emc] > 1)
|
||||
mess("More then one OP16(neg) for %s", ename(emc));
|
||||
switch (zf)
|
||||
{
|
||||
case MUST:
|
||||
if ( zc[emc]==0 ) mess("No OPNO for %s",ename(emc)) ;
|
||||
if (zc[emc] == 0)
|
||||
mess("No OPNO for %s", ename(emc));
|
||||
break;
|
||||
case FORB:
|
||||
if ( zc[emc]==1 ) mess("Forbidden OPNO for %s",ename(emc)) ;
|
||||
if (zc[emc] == 1)
|
||||
mess("Forbidden OPNO for %s", ename(emc));
|
||||
break;
|
||||
}
|
||||
switch(pf) {
|
||||
switch (pf)
|
||||
{
|
||||
case MUST:
|
||||
if ( posc[emc]==0 ) mess("No OP16(pos) for %s",ename(emc)) ;
|
||||
if (posc[emc] == 0)
|
||||
mess("No OP16(pos) for %s", ename(emc));
|
||||
break;
|
||||
case FORB:
|
||||
if (posc[emc] == 1)
|
||||
mess("Forbidden OP16(pos) for %s", ename(emc));
|
||||
break;
|
||||
}
|
||||
switch(nf) {
|
||||
switch (nf)
|
||||
{
|
||||
case MUST:
|
||||
if ( negc[emc]==0 ) mess("No OP16(neg) for %s",ename(emc)) ;
|
||||
if (negc[emc] == 0)
|
||||
mess("No OP16(neg) for %s", ename(emc));
|
||||
break;
|
||||
case FORB:
|
||||
if (negc[emc] == 1)
|
||||
|
@ -452,25 +618,34 @@ ckop(emc,zf,pf,nf) {
|
|||
static int pushchar;
|
||||
static int pushf;
|
||||
|
||||
int readchar() {
|
||||
static int readchar(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( pushf ) {
|
||||
if (pushf)
|
||||
{
|
||||
pushf = 0;
|
||||
c = pushchar;
|
||||
} else {
|
||||
if ( feof(stdin) ) return EOF ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (feof(stdin))
|
||||
return EOF;
|
||||
c = getc(stdin);
|
||||
}
|
||||
if ( c=='\n' ) line++ ;
|
||||
if (c == '\n')
|
||||
line++;
|
||||
return c;
|
||||
}
|
||||
|
||||
pushback(c) {
|
||||
if ( pushf ) {
|
||||
static void pushback(int c)
|
||||
{
|
||||
if (pushf)
|
||||
{
|
||||
fatal("Double pushback");
|
||||
}
|
||||
pushf++;
|
||||
pushchar = c;
|
||||
if ( c=='\n' ) line-- ;
|
||||
if (c == '\n')
|
||||
line--;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue