mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
935 lines
17 KiB
C
935 lines
17 KiB
C
/*
|
|
Copyright 1981
|
|
Alcyon Corporation
|
|
8716 Production Ave.
|
|
San Diego, Ca. 92121
|
|
*/
|
|
|
|
/* Pass 1 and pass 2 directive handling routines */
|
|
/* code to handle conditional assembly directives */
|
|
|
|
#include "as68.h"
|
|
#include "cout.h"
|
|
|
|
long lseek();
|
|
int p1gi();
|
|
int p2gi();
|
|
int igrst();
|
|
|
|
/*directive to define an opcode*/
|
|
hopd()
|
|
{
|
|
|
|
if(!lbt[0]) {
|
|
xerr(4); /*no label*/
|
|
return;
|
|
}
|
|
setname(); /*move label into main table*/
|
|
if((lblpt=lemt(oirt,TRUE))!=lmte) {
|
|
xerr(5); /*opcode redefined*/
|
|
return;
|
|
}
|
|
mmte(); /*make main table entry*/
|
|
expr(&p1gi); /*get instruction format*/
|
|
if(itype!=ITCN || ival<0 || ival>OPFF) {
|
|
xerr(18); /*illegal format specifier*/
|
|
return;
|
|
}
|
|
lblpt->flags =| ival|SYIN; /*remember format*/
|
|
if(fchr != ',') { /*field separator*/
|
|
xerr(10);
|
|
return;
|
|
}
|
|
expr(&p1gi); /*get opcode value*/
|
|
if(itype != ITCN) {
|
|
xerr(17); /*not a constant*/
|
|
return;
|
|
}
|
|
lblpt->vl1 = ival; /*put value in main table*/
|
|
igrst(); /*ignore rest of statement-comment*/
|
|
}
|
|
|
|
/* equate directive*/
|
|
hequ()
|
|
{
|
|
if(lbt[0] == 0) {
|
|
xerr(4); /*no label*/
|
|
return;
|
|
}
|
|
setname();
|
|
if((lblpt=lemt(sirt,FALSE))!=lmte) { /*aready there*/
|
|
if(lbt[0] == '~') { /*local symbol*/
|
|
lblpt = lmte;
|
|
mmte();
|
|
}
|
|
}
|
|
else
|
|
mmte();
|
|
if(lblpt->flags&SYXR) {
|
|
xerr(29);
|
|
return;
|
|
}
|
|
lblpt->flags =| SYDF|SYEQ; /*defined & equate*/
|
|
equflg = 1;
|
|
modelen = 4;
|
|
expr(&p1gi);
|
|
equflg = 0;
|
|
if(itype == ITSY && ival.ptrw2->flags&SYER) {
|
|
lblpt->flags =| SYER; /*equated register*/
|
|
ival = ival.ptrw2->vl1;
|
|
}
|
|
else if(itype != ITCN) {
|
|
xerr(7); /*not a constant*/
|
|
return;
|
|
}
|
|
if (inoffset && reloc != ABS) { /* [vlh] */
|
|
xerr(11);
|
|
return;
|
|
}
|
|
if(initflg) /*doing symbol table initialization*/
|
|
lblpt->flags =| SYIN; /*internal symbol*/
|
|
lblpt->vl1 = ival;
|
|
if(reloc == DATA) /*check relocation*/
|
|
{
|
|
lblpt->flags =| SYRA; /*DATA relocatable*/
|
|
}
|
|
else if(reloc == TEXT)
|
|
lblpt->flags =| SYRO; /*TEXT relocatable*/
|
|
else if(reloc == BSS)
|
|
lblpt->flags =| SYBS; /*BSS relocatable*/
|
|
else if(fchr==',' && (fchr=gchr())=='r')
|
|
lblpt->flags =| SYER; /*equated register*/
|
|
if (refpc) /*[vlh] flag directive is pc relative */
|
|
lblpt->flags =| SYPC;
|
|
igrst();
|
|
}
|
|
|
|
/* process dsect directive*/
|
|
hdsect()
|
|
{
|
|
dorlst(DATA);
|
|
}
|
|
|
|
dorlst(xrtyp)
|
|
{
|
|
inoffset = 0; /* [vlh] offset mode terminated my sect directive */
|
|
chkeven(); /* May need to make pc even */
|
|
dlabl(); /*define label on old base if there is one*/
|
|
savelc[rlflg] = loctr; /*save old base relocation*/
|
|
rlflg = xrtyp;
|
|
loctr = savelc[xrtyp]; /*set new base relocation ctr*/
|
|
opitb();
|
|
stbuf[0].itrl = itwc;
|
|
wostb();
|
|
igrst();
|
|
}
|
|
|
|
/*process psect directive*/
|
|
hpsect()
|
|
{
|
|
dorlst(TEXT);
|
|
}
|
|
|
|
hbss()
|
|
{
|
|
dorlst(BSS);
|
|
}
|
|
|
|
/*make pc even*/
|
|
heven()
|
|
{
|
|
modelen = 2; /*Try to figure this one out...*/
|
|
if(loctr&1) { /*have to make it even*/
|
|
dorlst(rlflg);
|
|
}
|
|
else {
|
|
igrst();
|
|
}
|
|
}
|
|
|
|
/*process globl directive*/
|
|
hent()
|
|
{
|
|
while(1) {
|
|
gterm(TRUE); /*get entry symbol*/
|
|
if(itype!=ITSY) { /*error if not symbol*/
|
|
xerr(28);
|
|
return;
|
|
}
|
|
if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
|
|
mmte(); /*not there, make new entry*/
|
|
else
|
|
if(lblpt->flags&SYER) /*already there*/
|
|
uerr(29);
|
|
lblpt->flags =| SYGL; /*symbol is an entry*/
|
|
if(lblpt->flags&SYXR) { /*been thru hext code*/
|
|
lblpt->flags =& ~(SYXR|SYDF); /*reset for init of .comm*/
|
|
}
|
|
if (inoffset && reloc != ABS) { /* [vlh] */
|
|
xerr(11);
|
|
return;
|
|
}
|
|
if(fchr == ',') /*skip ',' between entries*/
|
|
fchr = gchr();
|
|
else {
|
|
igrst(); /*statement finished*/
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*process comm directive*/
|
|
hext()
|
|
{
|
|
gterm(TRUE); /*get external symbol*/
|
|
if(itype!=ITSY) { /*error if not symbol*/
|
|
xerr(28);
|
|
return;
|
|
}
|
|
if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
|
|
mmte(); /*not there, make new entry*/
|
|
else
|
|
if(lblpt->flags&SYDF && (lblpt->flags&SYXR)==0) /*already there*/
|
|
uerr(29);
|
|
lblpt->flags =| SYXR | SYDF; /*symbol is an external*/
|
|
mkextidx(lblpt); /*put into external table*/
|
|
if(fchr == ',') { /*skip ',' between operands*/
|
|
fchr = gchr();
|
|
gterm(TRUE);
|
|
if(itype != ITCN) {
|
|
xerr(17);
|
|
return;
|
|
}
|
|
lblpt->vl1.wd1 = ival; /* # bytes of storage required*/
|
|
}
|
|
else
|
|
lblpt->vl1.wd1 = 1; /* default # bytes*/
|
|
igrst();
|
|
}
|
|
|
|
mkextidx(p)
|
|
struct symtab *p;
|
|
{
|
|
|
|
if(extindx >= EXTSZ) { /*check for overflow of external symbol tbl*/
|
|
rpterr("overflow of external table\n");
|
|
endit();
|
|
}
|
|
p->vl1.wd2 = pexti - extbl; /* external symbol index #*/
|
|
*pexti++ = p; /*save external in external table*/
|
|
extindx++;
|
|
}
|
|
|
|
/* end statement*/
|
|
hend()
|
|
{
|
|
register short i;
|
|
register int j;
|
|
|
|
inoffset = 0; /*[vlh] turn off inoffset mode*/
|
|
lblpt = 0; /*no label*/
|
|
opitb(); /*output beginning of statement*/
|
|
igrst(); /* [vlh] ignore operands */
|
|
stbuf[0].itrl = itwc; /*number of it entries*/
|
|
wostb(); /*write out statement buffer*/
|
|
for(i=0; i<ITBSZ; i++)
|
|
doitwr(0);
|
|
if(initflg) {
|
|
putsymtab();
|
|
printf("68000 assembler initialized\n");
|
|
endit();
|
|
}
|
|
if((fchr=gchr())!=EOF) {
|
|
rpterr("end statement not at end of source\n");
|
|
}
|
|
savelc[rlflg] = loctr; /*last location on current reloc base*/
|
|
fixunds(); /*make golbals and maybe undefineds external*/
|
|
if(!didorg) /*did not assign to location counter*/
|
|
pass1a(); /*resolve short branches*/
|
|
pass2(); /*assembler pass 2*/
|
|
}
|
|
|
|
/* define storage given number of bytes*/
|
|
hds()
|
|
{
|
|
dlabl(); /*define label maybe*/
|
|
if (!inoffset) /* [vlh] */
|
|
opitb(); /*output it for beginning of statement*/
|
|
refpc = 0;
|
|
expr(&p1gi);
|
|
if(itype!=ITCN) {
|
|
xerr(17); /*must be constant*/
|
|
return;
|
|
}
|
|
if(reloc != ABS) {
|
|
xerr(9); /*must be absolute*/
|
|
return;
|
|
}
|
|
if (!inoffset) { /* [vlh] don't generate it if in offset */
|
|
opitoo(); /*output one operand*/
|
|
stbuf[0].itrl = itwc;
|
|
wostb(); /*write out statement buffer*/
|
|
loctr =+ (ival*modelen);
|
|
}
|
|
igrst();
|
|
}
|
|
|
|
/* make pc even if necessary for .dc and .ds */
|
|
chkeven()
|
|
{
|
|
register char *pi;
|
|
|
|
if(modelen>1 && loctr&1) {
|
|
pi = opcpt;
|
|
opcpt = evenptr;
|
|
opitb();
|
|
stbuf[0].itrl = itwc;
|
|
wostb();
|
|
opcpt = pi;
|
|
loctr++;
|
|
}
|
|
}
|
|
|
|
/* define byte directive*/
|
|
hdc()
|
|
{
|
|
chkeven();
|
|
hdata(modelen);
|
|
}
|
|
|
|
/*
|
|
* define bytes or words of data
|
|
* call with:
|
|
* 1 => defining bytes
|
|
* 2 => defining words
|
|
* 4 => defining long words
|
|
*/
|
|
hdata(mul)
|
|
{
|
|
dlabl(); /*define label*/
|
|
opitb(); /*beginning of statement*/
|
|
numops = 0; /*initialize count for number of operands*/
|
|
opito(); /*output it for operands*/
|
|
stbuf[0].itrl = itwc; /* # of it entries*/
|
|
wostb(); /*write out statement buffer*/
|
|
loctr =+ numops*mul; /* count by bytes or words*/
|
|
}
|
|
|
|
/* handle org statement*/
|
|
horg()
|
|
{
|
|
register i;
|
|
|
|
if(rlflg==TEXT && loctr!=0)
|
|
didorg++; /*can't do branch optimization as separate pass now*/
|
|
expr(&p1gi); /*value of new relocation counter*/
|
|
if(reloc != rlflg && reloc != ABS) {
|
|
xerr(27);
|
|
return;
|
|
}
|
|
if(ival < loctr) {
|
|
xerr(40); /*trying to go backwards*/
|
|
return;
|
|
}
|
|
opcpt = orgptr; /*org directive for pass 2*/
|
|
opitb();
|
|
opitoo();
|
|
stbuf[0].itrl = itwc;
|
|
wostb();
|
|
loctr = ival;
|
|
dlabl(); /*define label*/
|
|
}
|
|
|
|
/* Assemble for mask2 (R9M), ignore... */
|
|
hmask2() /* [vlh] */
|
|
{
|
|
igrst();
|
|
}
|
|
|
|
/* Define register list */
|
|
hreg() /* [vlh] */
|
|
{
|
|
int mask;
|
|
if(lbt[0]==0) {
|
|
xerr(4); /*no label*/
|
|
return;
|
|
}
|
|
setname(); /*move label into main table*/
|
|
if((lblpt=lemt(sirt,FALSE))!=lmte) {
|
|
xerr(5); /*opcode redefined*/
|
|
return;
|
|
}
|
|
if (inoffset)
|
|
if (reloc != ABS) {
|
|
xerr(11);
|
|
return;
|
|
}
|
|
mmte(); /*make main table entry*/
|
|
if ((mask = mkmask()) == -1) {
|
|
xerr(6);
|
|
return;
|
|
}
|
|
lblpt->flags =| SYDF|SYEQ|SYRM; /* register mask, defined & equated */
|
|
lblpt->vl1 = mask;
|
|
igrst();
|
|
}
|
|
|
|
int regmsk[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
|
0100,040,020,010,4,2,1};
|
|
/* make a register mask for the reg routine */
|
|
mkmask() /* [vlh] */
|
|
{
|
|
register int *p, i, j, mask;
|
|
|
|
p = ®msk; mask = 0;
|
|
while ((i = chkreg()) != -1) {
|
|
if (fchr == '-') {
|
|
fchr = gchr();
|
|
if ((j = chkreg()) == -1) {
|
|
xerr(40);
|
|
return(-1);
|
|
}
|
|
while (i <= j)
|
|
mask =| p[i++];
|
|
}
|
|
else mask =| p[i];
|
|
if (fchr != '/' && fchr != ',') break; /*[vlh] Signetics fix*/
|
|
fchr = gchr();
|
|
}
|
|
return(mask);
|
|
}
|
|
|
|
/* get a register # from file, return -1 if none or illegal */
|
|
chkreg() /* [vlh] */
|
|
{
|
|
register int i, j;
|
|
|
|
i = j = 0;
|
|
if (fchr == 'a' || fchr == 'A')
|
|
i = 8;
|
|
else if (fchr != 'd' && fchr != 'r' && fchr != 'D' && fchr != 'R')
|
|
return(-1);
|
|
fchr = gchr();
|
|
do {
|
|
j = (j*10) + (fchr - '0');
|
|
fchr = gchr();
|
|
} while (isdigit(fchr));
|
|
if (j < 0 || j > AREGHI) return(-1);
|
|
i =+ j;
|
|
if (i >= 0 && i <= AREGHI) return(i);
|
|
else return(-1);
|
|
}
|
|
|
|
/* Define constant block */
|
|
hdcb() /* [vlh] */
|
|
{
|
|
chkeven(); /* on even boundary if not byte block. */
|
|
dlabl(); /* define label... */
|
|
opitb();
|
|
opito();
|
|
stbuf[0].itrl = itwc;
|
|
numops = stbuf[ITOP1].itop;
|
|
loctr =+ numops * modelen;
|
|
wostb(); /* write out statement buffer */
|
|
}
|
|
|
|
/* Command line, similar to ds.b */
|
|
hcomline() /* [vlh] */
|
|
{
|
|
dlabl(); /*define label maybe*/
|
|
modelen = 1; /* byte store... */
|
|
opitb(); /*output it for beginning of statement*/
|
|
refpc = 0;
|
|
expr(&p1gi);
|
|
if(itype!=ITCN) {
|
|
xerr(17); /*must be constant*/
|
|
return;
|
|
}
|
|
if(reloc != ABS) {
|
|
xerr(9); /*must be absolute*/
|
|
return;
|
|
}
|
|
opitoo(); /*output one operand*/
|
|
stbuf[0].itrl = itwc;
|
|
wostb(); /*write out statement buffer*/
|
|
loctr =+ ival;
|
|
igrst();
|
|
}
|
|
|
|
/* Relocateable id record, ignore */
|
|
hidnt() /* [vlh] */
|
|
{
|
|
igrst();
|
|
}
|
|
|
|
/* Define offsets */
|
|
hoffset() /* [vlh] */
|
|
{
|
|
inoffset = 1;
|
|
expr(&p1gi); /* get new location counter */
|
|
if (itype != ITCN) {
|
|
xerr(17); /* constant required */
|
|
return;
|
|
}
|
|
if (reloc != ABS) {
|
|
xerr(9); /* must be absolute */
|
|
return;
|
|
}
|
|
loctr = ival;
|
|
igrst();
|
|
}
|
|
|
|
/* define sections: map to bss, text and data */
|
|
hsection() /* [vlh] */
|
|
{
|
|
inoffset = 0; /* reseting section turns off offset mode */
|
|
dlabl(); /* define label on old base if there is one */
|
|
savelc[rlflg] = loctr; /* save old base relocation */
|
|
opitb(); /* intermediate table... */
|
|
expr(&p1gi); /* get section # */
|
|
if (itype != ITCN) {
|
|
xerr(17); /* must be a constant */
|
|
return;
|
|
}
|
|
if (ival > 15 || ival < 0) {
|
|
xerr(9); /* proper range 0..15 */
|
|
return;
|
|
}
|
|
if (ival==14) rlflg = DATA;
|
|
else if (ival==15) rlflg = BSS;
|
|
else rlflg = TEXT;
|
|
loctr = savelc[rlflg];
|
|
stbuf[3].itop = loctr; /* pass 1 location counter */
|
|
stbuf[3].itrl = rlflg; /* relocation base */
|
|
stbuf[0].itrl = itwc;
|
|
wostb();
|
|
igrst();
|
|
}
|
|
|
|
/* hopt -- ignore, set up assembler options */
|
|
hopt() /* vlh */
|
|
{
|
|
igrst();
|
|
}
|
|
|
|
/**** Second pass directive handling routines ****/
|
|
|
|
/* second pass end statement*/
|
|
send()
|
|
{
|
|
register int i;
|
|
|
|
savelc[rlflg] = loctr;
|
|
if(savelc[TEXT]&1) {
|
|
rlflg = TEXT;
|
|
outbyte(0,DABS);
|
|
savelc[TEXT]++;
|
|
}
|
|
if(savelc[DATA]&1) {
|
|
rlflg = DATA;
|
|
outbyte(0,DABS);
|
|
savelc[DATA]++;
|
|
}
|
|
if(savelc[BSS]&1) {
|
|
savelc[BSS]++;
|
|
}
|
|
|
|
ival = 0;
|
|
reloc = ABS;
|
|
ckeop(9);
|
|
print(0);
|
|
cpdata(); /*copy data to loader file*/
|
|
osymt(); /*output symbol table*/
|
|
myfflush(&tbuf); /*flush text relocation bits*/
|
|
cprlbits(); /*copy relocation bits*/
|
|
myfflush(&lbuf);
|
|
i = (sizeof couthd.ch_magic) + 3*(sizeof couthd.ch_tsize);
|
|
if((lseek(lfn,(long)i,0) == -1) || write(lfn,&stlen,4) != 4)
|
|
rpterr("I/O error on loader output file\n");
|
|
endit(); /*end*/
|
|
}
|
|
|
|
/*second pass define storage - ds*/
|
|
sds()
|
|
{
|
|
print(0);
|
|
if(rlflg == TEXT || rlflg==DATA) {
|
|
expr(&p2gi);
|
|
if(itype != ITCN) {
|
|
uerr(13);
|
|
return;
|
|
}
|
|
ival =* modelen;
|
|
while(ival) {
|
|
outbyte(0,DABS);
|
|
loctr++;
|
|
ival--;
|
|
}
|
|
}
|
|
else
|
|
loctr =+ stbuf[ITOP1].itop*modelen; /*reserve storage*/
|
|
}
|
|
|
|
/* second pass - define block storage, initialized */
|
|
sdcb() /* [vlh] */
|
|
{
|
|
register int pfg, i, hflg, len;
|
|
|
|
expr(&p2gi);
|
|
if (itype != ITCN || reloc != ABS) {
|
|
uerr(13); /* must be absolute constant */
|
|
return;
|
|
}
|
|
len = ival;
|
|
expr(&p2gi);
|
|
if (modelen==1 && (ival<-128 || ival>=256 || reloc != ABS)) {
|
|
uerr(20);
|
|
ival = 0;
|
|
reloc = ABS;
|
|
}
|
|
while (len--) {
|
|
if (modelen==1) {
|
|
if (!hflg) {
|
|
ins[i].hibyte = ival;
|
|
outbyte(ival.wd2,DABS);
|
|
hflg++;
|
|
}
|
|
else {
|
|
ins[i++].lobyte = ival;
|
|
outbyte(ival.wd2,DABS);
|
|
hflg=0;
|
|
}
|
|
goto sdbl2;
|
|
}
|
|
else if (modelen==2) {
|
|
sdbl1:
|
|
ins[i++] = ival.wd2;
|
|
outword(ival.wd2, reloc);
|
|
sdbl2:
|
|
if (i>3) {
|
|
instrlen = i*2;
|
|
print ((pfg++) ? 2 : 1);
|
|
loctr =+ instrlen;
|
|
i=0;
|
|
}
|
|
}
|
|
else { /* long word... */
|
|
ins[i++] = ival.wd1;
|
|
outword(ival.wd1,LUPPER);
|
|
goto sdbl1;
|
|
}
|
|
}
|
|
if (i) { /* more printing */
|
|
instrlen = i*2 - hflg;
|
|
print ((pfg) ? 2 : 1);
|
|
loctr =+ instrlen;
|
|
}
|
|
}
|
|
|
|
/*second pass data*/
|
|
sdsect()
|
|
{
|
|
savelc[rlflg] = loctr;
|
|
rlflg = DATA;
|
|
loctr = savelc[DATA];
|
|
print(0); /*print the new location counter*/
|
|
}
|
|
|
|
/*second pass text*/
|
|
spsect()
|
|
{
|
|
savelc[rlflg] = loctr;
|
|
rlflg = TEXT;
|
|
loctr = savelc[TEXT];
|
|
print(0); /*print the new location counter*/
|
|
}
|
|
|
|
sbss()
|
|
{
|
|
savelc[rlflg] = loctr;
|
|
rlflg = BSS;
|
|
loctr = savelc[BSS];
|
|
print(0); /*print the new location counter*/
|
|
}
|
|
|
|
/* make loctr even*/
|
|
seven()
|
|
{
|
|
if(loctr&1) {
|
|
if(rlflg==TEXT || rlflg==DATA)
|
|
outbyte(0,DABS);
|
|
loctr++;
|
|
}
|
|
print(0);
|
|
}
|
|
|
|
/* second pass org*/
|
|
sorg()
|
|
{
|
|
long l;
|
|
|
|
if(rlflg==TEXT || rlflg==DATA) { /*must put out zeros*/
|
|
l = stbuf[ITOP1].itop - loctr; /*# zeroes to output*/
|
|
ins[0] = 0;
|
|
print(1);
|
|
while(l > 0) {
|
|
outbyte(0,DABS);
|
|
loctr++;
|
|
l--;
|
|
}
|
|
}
|
|
else { /*BSS*/
|
|
loctr = stbuf[ITOP1].itop; /*new location counter*/
|
|
print(0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
*second pass define data (words or bytes)
|
|
* call with
|
|
* 2 => defining words
|
|
* 1 => defining bytes
|
|
* 4 => defining long words
|
|
*/
|
|
sdata(dtyp)
|
|
{
|
|
register pfg,i;
|
|
register hflg;
|
|
|
|
hflg = i = pfg = 0;
|
|
while(1) {
|
|
expr(&p2gi); /*evaluate expression*/
|
|
if(pitw < pnite)
|
|
pitw--; /*expr passed a token*/
|
|
if(itype!=ITCN && reloc != EXTRN) { /*must be constant*/
|
|
uerr(13);
|
|
ival=0;
|
|
reloc = ABS;
|
|
}
|
|
if(reloc == EXTRN)
|
|
reloc = (extref<<3)|EXTVAR; /*gen extern reference*/
|
|
if(dtyp==1) { /*defining a byte*/
|
|
if(ival<-128 || ival>=256 || reloc!=ABS) { /*not a byte*/
|
|
uerr(20);
|
|
ival=0;
|
|
reloc = ABS;
|
|
}
|
|
if(!hflg) {
|
|
ins[i].hibyte = ival;
|
|
outbyte(ival.wd2,DABS);
|
|
hflg++;
|
|
}
|
|
else {
|
|
ins[i++].lobyte = ival;
|
|
hflg = 0;
|
|
outbyte(ival.wd2,DABS);
|
|
}
|
|
goto sdal2;
|
|
}
|
|
else if(dtyp == 2) { /*defining a word*/
|
|
sdal1:
|
|
ins[i++] = ival.wd2;
|
|
outword(ival.wd2, reloc);
|
|
sdal2:
|
|
if(i>3) {
|
|
instrlen = i*2;
|
|
print ((pfg++) ? 2 : 1);
|
|
loctr =+ instrlen;
|
|
i=0;
|
|
}
|
|
}
|
|
else { /*long words*/
|
|
ins[i++] = ival.wd1;
|
|
outword(ival.wd1,LUPPER);
|
|
goto sdal1;
|
|
}
|
|
if(!ckeop(15)) /*should be end of operand*/
|
|
return;
|
|
pitw++;
|
|
if(ckein()) {
|
|
if(hflg) {
|
|
ins[i++].lobyte = 0;
|
|
}
|
|
if(i) { /*more printing*/
|
|
instrlen = i*2 - hflg;
|
|
print ((pfg) ? 2 : 1);
|
|
loctr =+ instrlen;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
sdc()
|
|
{
|
|
sdata(modelen);
|
|
}
|
|
|
|
ssection() /* [vlh] */
|
|
{
|
|
int sect;
|
|
|
|
sect = stbuf[3].itrl;
|
|
if (sect==DATA) sdsect();
|
|
else if (sect==BSS) sbss();
|
|
else spsect();
|
|
}
|
|
|
|
/*define word statement*/
|
|
sdw()
|
|
{
|
|
sdata(0); /*defining words*/
|
|
}
|
|
/**** Conditional assembly directives ****/
|
|
|
|
hifeq() /* [vlh] */
|
|
{
|
|
if (!acok()) return;
|
|
if (ival) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hifne() /* [vlh] */
|
|
{
|
|
if (!acok()) return;
|
|
if (!ival) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hiflt() /* [vlh] */
|
|
{
|
|
if (!acok()) return;
|
|
if (ival >= 0) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hifle() /* [vlh] */
|
|
{
|
|
if (!acok()) return;
|
|
if (ival > 0) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hifgt() /* [vlh] */
|
|
{
|
|
if (!acok()) return;
|
|
if (ival <= 0) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hifge() /* [vlh] */
|
|
{
|
|
if (!acok()) return;
|
|
if (ival < 0) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hifc() /* [vlh] */
|
|
{
|
|
if (!cmp_ops()) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hifnc() /* [vlh] */
|
|
{
|
|
if (cmp_ops()) {
|
|
if (ca_true) ca_level = ca;
|
|
ca_true = 0;
|
|
}
|
|
ca++;
|
|
}
|
|
|
|
hendc() /* [vlh] */
|
|
{
|
|
if (!ca) {
|
|
xerr(25); /* unexpected endc */
|
|
return;
|
|
}
|
|
ca--;
|
|
if (!ca_true)
|
|
if (ca_level == ca) ca_true = 1;
|
|
igrst();
|
|
}
|
|
hpage()
|
|
{
|
|
opitb(); /* Output beginning */
|
|
wostb(); /* Write out buffer */
|
|
igrst(); /* Ignore rest of line */
|
|
}
|
|
spage()
|
|
{
|
|
print(0); /* Print the directive */
|
|
xline = LPP; /* Force page on next print */
|
|
page();
|
|
}
|
|
acok()
|
|
{
|
|
expr(&p1gi);
|
|
if (itype != ITCN) {
|
|
xerr(7); /* must be a constant */
|
|
return(0);
|
|
}
|
|
if (reloc != ABS) {
|
|
xerr(11); /* must be absolute, no forward references */
|
|
return(0);
|
|
}
|
|
igrst();
|
|
return(1);
|
|
}
|
|
|
|
cmp_ops()
|
|
{
|
|
char str1[25], str2[25];
|
|
register int len1, len2;
|
|
|
|
if (fchr != '\'') { xerr(9); return(0); }
|
|
len1 = len2 = 0;
|
|
while (fchr = gchr()) {
|
|
if (fchr == '\'') break;
|
|
if (fchr == EOLC) return(0);
|
|
str1[len1++] = fchr;
|
|
}
|
|
if ((fchr=gchr()) != ',') { xerr(9); return; }
|
|
if ((fchr=gchr()) != '\'') { xerr(10); return;}
|
|
while (fchr = gchr()) {
|
|
if (fchr == '\'') break;
|
|
if (fchr == EOLC) return(0);
|
|
str2[len2++] = fchr;
|
|
}
|
|
igrst();
|
|
if (len1 != len2) return(0);
|
|
str1[len1] = str2[len2] = NULL;
|
|
if (strcmp(str1,str2) == 0) return(1);
|
|
return(0);
|
|
}
|
|
|
|
strcmp(s,t)
|
|
register char *s, *t;
|
|
{
|
|
for( ; *s == *t; s++, t++ )
|
|
if( *s == '\0' )
|
|
return(0);
|
|
return( *s - *t );
|
|
}
|