mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
Upload
Digital Research
This commit is contained in:
@@ -0,0 +1,988 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* pass 2 miscellaneous routines */
|
||||
|
||||
#include "as68.h"
|
||||
int p2gi();
|
||||
|
||||
long stlen;
|
||||
int stdofd 1;
|
||||
char tfilname[];
|
||||
int ins[], rlbits[], f2mode[];
|
||||
int udfct, ftudp, pline, prsp;
|
||||
|
||||
clrea(ap)
|
||||
struct op *ap;
|
||||
{
|
||||
register struct op *p;
|
||||
|
||||
p = ap;
|
||||
p->ea = p->len = p->xmod = p->drlc = 0; p->con = 0;
|
||||
p->ext = p->idx = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* get one operand effective adddress (operand until , or EOS)
|
||||
* returns:
|
||||
* opnd[opn].ea set to effective address mode bits
|
||||
* opnd[opn].len set to # bytes for operand
|
||||
* opnd[opn].con set to constant part of ea
|
||||
* opnd[opn].ext set to external symbol # if any
|
||||
* opnd[opn].idx set to index register if any
|
||||
* opnd[opn].drlc set to effective address relocation mode
|
||||
* opnd[opn].xmod set to index register addressing mode (word or long)
|
||||
*/
|
||||
getea(opn)
|
||||
{
|
||||
register i,disp;
|
||||
register struct op *p;
|
||||
register int t;
|
||||
|
||||
p = &opnd[opn];
|
||||
disp = 0;
|
||||
clrea(p);
|
||||
if(ckitc(pitw,'#')) {
|
||||
p->len = (modelen==1) ? 2 : modelen;
|
||||
p->ea = IMM;
|
||||
pitw++;
|
||||
goto dosimp;
|
||||
}
|
||||
if(ckitc(pitw,'(')) {
|
||||
geteal1:
|
||||
pitw++;
|
||||
if((i=getrgs()) == PC) { /*pc relative*/
|
||||
p->ea = 072; /*set mode & register bits*/
|
||||
p->len = 2;
|
||||
}
|
||||
else {
|
||||
if(i != -1) /*last was some type of register*/
|
||||
pitw--; /*havent used it yet*/
|
||||
if((i=getareg()) < 0) { /*not a reg # next*/
|
||||
if(disp || getreg()!=-1) {
|
||||
uerr(14); /*illegal index reg*/
|
||||
return;
|
||||
}
|
||||
pitw--;
|
||||
goto dosimp; /*must be expression in ()*/
|
||||
}
|
||||
p->ea = i&7; /*put in a reg #*/
|
||||
}
|
||||
if(ckitc(pitw,',')) { /*must be index reg #*/
|
||||
do_ireg(p,i);
|
||||
return;
|
||||
}
|
||||
ckrparen();
|
||||
if(i != PC) {
|
||||
if(!disp && ckitc(pitw,'+')) {
|
||||
pitw++;
|
||||
p->ea =| INDINC;
|
||||
}
|
||||
else if(disp) { /*indirect with displacement*/
|
||||
p->ea =| INDDISP;
|
||||
p->len = 2;
|
||||
}
|
||||
else
|
||||
p->ea =| INDIRECT;
|
||||
}
|
||||
ckeop(9+opn);
|
||||
return;
|
||||
}
|
||||
if(ckitc(pitw,'-')) { /*predecrement maybe*/
|
||||
pitw++;
|
||||
if(ckitc(pitw,'(')) { /*must be*/
|
||||
pitw++;
|
||||
if((i = getareg()) < 0) { /*not valid a reg*/
|
||||
pitw =- 2; /*must be negative expr*/
|
||||
goto dosimp;
|
||||
}
|
||||
p->ea = i|DECIND;
|
||||
ckrparen();
|
||||
ckeop(9+opn);
|
||||
return;
|
||||
}
|
||||
pitw--;
|
||||
}
|
||||
dosimp: /*simple addr or imm expr*/
|
||||
if(i=gspreg()) {
|
||||
t = ins[0];
|
||||
if(i==PC || (i==USP && t!=MOVE))
|
||||
uerr(20);
|
||||
if(i==SR || i==CCR) {
|
||||
if(t!=AND&&t!=OR&&t!=EOR&&t!=ANDI&&t!=ORI&&t!=EORI&&t!=MOVE)
|
||||
uerr(20);
|
||||
}
|
||||
p->idx = i;
|
||||
ckeop(9+opn);
|
||||
return;
|
||||
}
|
||||
if((i=getreg()) >= 0) { /*register direct*/
|
||||
p->ea = i;
|
||||
if(modelen==1 && i>=AREGLO && i<=AREGHI)
|
||||
uerr(20);
|
||||
ckeop(9+opn);
|
||||
return;
|
||||
}
|
||||
expr(&p2gi);
|
||||
if(pitw < pnite) /*expr passes one token*/
|
||||
pitw--;
|
||||
if(extflg) {
|
||||
p->ext = extref;
|
||||
extflg = 0;
|
||||
}
|
||||
p->con = ival;
|
||||
p->drlc = reloc; /*relocation factor*/
|
||||
if(ckitc(pitw,'(')) {
|
||||
disp++;
|
||||
goto geteal1;
|
||||
}
|
||||
if(!p->ea) { /*memory address*/
|
||||
if(shortadr && (!ival.wd1 || ival.wd1== -1)) { /*16-bit addrs*/
|
||||
p->ea = SADDR;
|
||||
p->len = 2;
|
||||
}
|
||||
else {
|
||||
p->ea = LADDR;
|
||||
p->len = 4;
|
||||
}
|
||||
}
|
||||
ckeop(9+opn);
|
||||
}
|
||||
|
||||
do_ireg(p,i,opn)
|
||||
struct op *p;
|
||||
int i, opn;
|
||||
{
|
||||
pitw++;
|
||||
p->idx = getreg();
|
||||
if(p->idx<0 || p->idx>AREGHI)
|
||||
uerr(14);
|
||||
p->len = 2;
|
||||
if(!ckitc(pitw,')')) {
|
||||
p->xmod = getrgs() - 20;
|
||||
if(p->xmod<0 || p->xmod>1) {
|
||||
uerr(34);
|
||||
p->xmod = 0;
|
||||
}
|
||||
}
|
||||
ckrparen();
|
||||
ckeop(9+opn);
|
||||
if(i==PC)
|
||||
p->ea =+ 1;
|
||||
else
|
||||
p->ea =| INDINX;
|
||||
}
|
||||
|
||||
/*
|
||||
* get an A register specification
|
||||
* call with:
|
||||
* pitw pointing to reg operand
|
||||
* returns:
|
||||
* -1 if not vaid A reg
|
||||
* A reg # if valid
|
||||
* also updates pitw if valid
|
||||
*/
|
||||
getareg()
|
||||
{
|
||||
register i;
|
||||
|
||||
i = getreg();
|
||||
if(i>=AREGLO && i<=AREGHI) {
|
||||
return(i&7);
|
||||
}
|
||||
else {
|
||||
if(i != -1)
|
||||
pitw--;
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get any register specification
|
||||
* call with :
|
||||
* pitw pointing at operand
|
||||
* returns:
|
||||
* register # with pitw updated
|
||||
* -1 if not valid register
|
||||
*/
|
||||
getreg()
|
||||
{
|
||||
register i;
|
||||
|
||||
i = getrgs();
|
||||
if(i>=0 && i<=AREGHI)
|
||||
return(i);
|
||||
else {
|
||||
if(i != -1)
|
||||
pitw--;
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*get any register specification*/
|
||||
getrgs()
|
||||
{
|
||||
register char *i;
|
||||
|
||||
if(pitw->itty == ITSY) {
|
||||
i = pitw->itop.ptrw2; /*symbol ptr*/
|
||||
if(i->flags&SYER) {
|
||||
pitw++;
|
||||
return(i->vl1.wd2); /*register #*/
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* check for a right paren as the next char*/
|
||||
/* output error msg if not found*/
|
||||
ckrparen()
|
||||
{
|
||||
if(ckitc(pitw,')')) /*found it*/
|
||||
pitw++;
|
||||
else
|
||||
uerr(32);
|
||||
}
|
||||
|
||||
/*
|
||||
* check intermedate text item for special character
|
||||
* call with:
|
||||
* pointer to desired item in stbuf
|
||||
* character to check for
|
||||
* returns:
|
||||
* 0 => no match
|
||||
* 1 => match
|
||||
*/
|
||||
ckitc(ckpt,cksc)
|
||||
char *ckpt;
|
||||
{
|
||||
if(ckpt >= pnite || ckpt->itty != ITSP || ckpt->itop.wd2 != cksc)
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* read intermediate text for one statement
|
||||
* returns:
|
||||
* intermediate text in stbuf
|
||||
*/
|
||||
ristb()
|
||||
{
|
||||
register riix;
|
||||
register int *pi;
|
||||
register int i;
|
||||
|
||||
do {
|
||||
riix = stbuf[0].itrl;
|
||||
itoffset =+ (riix&0377) * STBFSIZE;
|
||||
pi = &stbuf[0];
|
||||
for(i=0; i<(STBFSIZE)/(sizeof *pi); i++) {
|
||||
if(pitix > &itbuf[ITBSZ-1]) { /*need new buffer of it*/
|
||||
doitrd(); /*read it buffer*/
|
||||
}
|
||||
*pi++ = *pitix++; /*first word of it*/
|
||||
}
|
||||
if(stbuf[0].itty != ITBS) /*best be beginning of statement */
|
||||
abort();
|
||||
|
||||
/* get the rest of the statement it*/
|
||||
riix = stbuf[0].itrl & 0377; /*unsigned byte*/
|
||||
riix--; /*already got first entry*/
|
||||
while(riix--) {
|
||||
for(i=0; i<(STBFSIZE)/(sizeof *pi); i++) {
|
||||
if(pitix > &itbuf[ITBSZ-1]) { /*need new buffer of it*/
|
||||
doitrd();
|
||||
}
|
||||
*pi++ = *pitix++;
|
||||
}
|
||||
}
|
||||
} while(stbuf[1].itrl == -1); /* eliminated instr, read next one */
|
||||
}
|
||||
|
||||
int errno;
|
||||
|
||||
doitrd()
|
||||
{
|
||||
register int i;
|
||||
|
||||
pitix = itbuf;
|
||||
if((i=read(itfn,itbuf,ITBSZ*(sizeof i)))<=0) {
|
||||
putchar(0);
|
||||
stdofd = 2;
|
||||
printf("it read error i=%d errno=%o\n",
|
||||
i,errno);
|
||||
putchar(0);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check for end of operand
|
||||
* call with
|
||||
* error number if this is not end of operand
|
||||
*/
|
||||
ckeop(uen)
|
||||
{
|
||||
if(pitw>=pnite) /*end of all operands*/
|
||||
return(1);
|
||||
if(!ckitc(pitw,',')) { /*not end of stmt must be op,op*/
|
||||
uerr(uen);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* output symbol table to file*/
|
||||
osymt()
|
||||
{
|
||||
register char **sx1;
|
||||
register char *p;
|
||||
register i;
|
||||
|
||||
stlen = 0;
|
||||
if(extindx) { /*output external symbols first*/
|
||||
if(prtflg)
|
||||
printf("\n\n-EXTERNAL SYMBOLS-\n");
|
||||
sx1 = extbl;
|
||||
for(i=0;i<extindx;i++) /*go through external table*/
|
||||
osyme(*sx1++); /*output symbol*/
|
||||
}
|
||||
if(prtflg)
|
||||
printf("\n\n");
|
||||
|
||||
for(p=bmte; p<lmte; p=+ STESIZE) { /*want them in order defined*/
|
||||
if(p->flags&(SYXR|SYIN))
|
||||
continue;
|
||||
osyme(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* make all undefined symbols external*/
|
||||
fixunds()
|
||||
{
|
||||
register char **sx1, **sx2;
|
||||
|
||||
/* loop thru symbol initial reference table*/
|
||||
for(sx1= sirt; sx1<&sirt[SZIRT-1]; sx1 =+ 2) {
|
||||
if(*(sx2 = sx1+1)==0) /* this chain is empty*/
|
||||
continue;
|
||||
|
||||
/* symbols on one chain*/
|
||||
sx2 = *sx2; /*first entry on this chain*/
|
||||
while(1) {
|
||||
if(!(sx2->flags&SYDF)) { /*not defined*/
|
||||
if(undflg || sx2->flags&SYGL) { /*all or globals*/
|
||||
sx2->flags = sx2->flags|SYDF|SYXR;
|
||||
mkextidx(sx2);
|
||||
}
|
||||
}
|
||||
if(sx2 == *sx1) /*end of chain*/
|
||||
break;
|
||||
sx2 = sx2->tlnk; /*next entry in chain*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* output symbols in a form to be read by a debugger
|
||||
* call with pointer to symbol table entry
|
||||
* prints all undefined symbols
|
||||
*/
|
||||
osyme(aosypt)
|
||||
struct symtab *aosypt;
|
||||
{
|
||||
register struct symtab *osypt;
|
||||
register char *p1;
|
||||
register int i;
|
||||
#ifdef VAX11
|
||||
register short *ps1;
|
||||
#else
|
||||
register int *ps1;
|
||||
#endif
|
||||
|
||||
osypt = aosypt; /*pointer to symbol table entry*/
|
||||
if(!prtflg && !(osypt->flags&SYDF)) { /*undefined symbol*/
|
||||
pudfs(osypt); /*print undefined*/
|
||||
return;
|
||||
}
|
||||
|
||||
p1 = &(osypt->name[0]);
|
||||
if(prtflg && !((osypt->flags)&SYER)) { /*put symbol on listing*/
|
||||
if(osypt->flags&SYXR) /*external symbol*/
|
||||
printf("%s\n",p1); /*just print name*/
|
||||
else if (osypt->flags&SYDF) {
|
||||
printf("%s\t",p1);
|
||||
puthex(osypt->vl1.wd1,4);
|
||||
puthex(osypt->vl1.wd2,4);
|
||||
if(osypt->flags&SYRA) /*print relocation factor*/
|
||||
printf("\tDATA\n");
|
||||
else if(osypt->flags&SYRO)
|
||||
printf("\tTEXT\n");
|
||||
else if(osypt->flags&SYBS)
|
||||
printf("\tBSS\n");
|
||||
else printf("\tABS\n");
|
||||
}
|
||||
else { /*undefined*/
|
||||
nerror++;
|
||||
printf("%s\t*UNDEFINED*\n",p1);
|
||||
}
|
||||
}
|
||||
|
||||
stlen =+ 14; /*one more symbol out*/
|
||||
|
||||
/*output symbol to loader file*/
|
||||
ps1 = &(osypt->name[0]);
|
||||
for(i=0; i<NAMELEN/2; i++) { /*output symbol name*/
|
||||
putw(*ps1++,&lbuf);
|
||||
}
|
||||
|
||||
putw(osypt->flags,&lbuf); /* output symbol flags */
|
||||
if(osypt->flags&SYXR) { /*external symbol*/
|
||||
putw(0,&lbuf);
|
||||
putw(osypt->vl1.wd1,&lbuf);
|
||||
}
|
||||
else {
|
||||
putw(osypt->vl1.wd1,&lbuf); /*upper half symbol value*/
|
||||
putw(osypt->vl1.wd2,&lbuf); /*lower symbol value*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print undefined symbols
|
||||
* call with
|
||||
* pointer to undefined symbol
|
||||
*/
|
||||
pudfs(udspt)
|
||||
struct symtab *udspt;
|
||||
{
|
||||
nerror++;
|
||||
if(!ftudp) { /*first time thru*/
|
||||
printf("\n&& UNDEFINED SYMBOLS &&\n");
|
||||
ftudp++;
|
||||
udfct=0; /*no symbols on this line*/
|
||||
}
|
||||
|
||||
printf("%8s ",&(udspt->name[0]));
|
||||
if(udfct++ > 6) {
|
||||
printf("\n");
|
||||
udfct=0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* output source and object listing
|
||||
* call with
|
||||
* 2 => print address and binary code only
|
||||
* 1 => object in ins[] and instr type in format
|
||||
* 0 => print address only
|
||||
*/
|
||||
print(pflag)
|
||||
{
|
||||
register i,j;
|
||||
register int *pi;
|
||||
|
||||
if( !prtflg ) return; /*no printing desired*/
|
||||
if(fchr==EOF) return; /*end of source file*/
|
||||
|
||||
i = instrlen; instrlen = 1; /*to print preceeding lines*/
|
||||
while(pline<p2absln) { /*need to print some lines*/
|
||||
printf("%4d ",pline); /*put source line num on listing*/
|
||||
printf(" "); /*align the source*/
|
||||
prtline(1);
|
||||
putchar('\n');
|
||||
fchr=gchr();
|
||||
if(fchr==EOF) return;
|
||||
pline++;
|
||||
}
|
||||
instrlen = i;
|
||||
|
||||
/* output current address, binary, and source*/
|
||||
printf("%4d ",p2absln); /*put source line num on listing*/
|
||||
puthex(loctr.wd1,4);
|
||||
puthex(loctr.wd2,4);
|
||||
putchar(' ');
|
||||
if(!pflag) { /*no binary*/
|
||||
printf(" "); /*blanks instead*/
|
||||
}
|
||||
else {
|
||||
pi = ins;
|
||||
for(i=0; i<instrlen/2; i++) { /* binary*/
|
||||
puthex(*pi++,4);
|
||||
}
|
||||
if(instrlen&1)
|
||||
puthex(*pi,2);
|
||||
putchar(' ');
|
||||
for(;i<4;i++) { /*four bytes max per line*/
|
||||
printf(" "); /*align the source*/
|
||||
}
|
||||
}
|
||||
if(pline>p2absln || pflag==2) {
|
||||
putchar('\n'); /*end of line*/
|
||||
}
|
||||
else {
|
||||
prtline(0);
|
||||
if(fchr==EOF) return;
|
||||
putchar('\n');
|
||||
fchr=gchr();
|
||||
pline++;
|
||||
}
|
||||
}
|
||||
|
||||
/*print one line aligning source output*/
|
||||
prtline(flg)
|
||||
{
|
||||
register i;
|
||||
register col, blcnt;
|
||||
|
||||
if(fchr=='*' || flg) { /*comment*/
|
||||
while(fchr!=EOLC && fchr!=EOF) {
|
||||
putchar(fchr);
|
||||
fchr = gchr();
|
||||
}
|
||||
return;
|
||||
}
|
||||
col = 1;
|
||||
blcnt = 0;
|
||||
while(1) {
|
||||
if(fchr==EOLC || fchr==EOF)
|
||||
return;
|
||||
if(fchr==' '&& blcnt<3) {
|
||||
i= (++blcnt == 3) ? 017 : 7;
|
||||
while(col&i) {
|
||||
putchar(' ');
|
||||
col++;
|
||||
}
|
||||
while(fchr==' ')
|
||||
fchr=gchr();
|
||||
if(fchr==EOLC || fchr==EOF)
|
||||
return;
|
||||
}
|
||||
putchar(fchr);
|
||||
fchr=gchr();
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
/* buffered putchar routine*/
|
||||
putchar(c)
|
||||
char c;
|
||||
{
|
||||
register int i;
|
||||
|
||||
*prtchidx++ = c;
|
||||
if(!c || prtchidx>=&prtchars[PRTCHLEN]) {
|
||||
i = prtchidx - prtchars;
|
||||
write(stdofd,prtchars,i);
|
||||
prtchidx = prtchars;
|
||||
}
|
||||
}
|
||||
|
||||
int hibytflg[4], hibytw[4];
|
||||
|
||||
outbyte(bv,br)
|
||||
{
|
||||
if (rlflg == BSS) { /* [vlh] */
|
||||
uerr(39);
|
||||
return;
|
||||
}
|
||||
if(hibytflg[rlflg]) {
|
||||
outword(hibytw[rlflg]|(bv&0xff),br);
|
||||
hibytflg[rlflg] = 0;
|
||||
}
|
||||
else {
|
||||
hibytw[rlflg] = bv<<8;
|
||||
hibytflg[rlflg]++;
|
||||
}
|
||||
}
|
||||
|
||||
outword(val,rb)
|
||||
{
|
||||
switch(rlflg) {
|
||||
|
||||
case TEXT:
|
||||
putw(val,&lbuf);
|
||||
putw(rb,&tbuf);
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
putw(val,&dabuf);
|
||||
putw(rb,&drbuf);
|
||||
break;
|
||||
|
||||
case BSS:
|
||||
uerr(39);
|
||||
break;
|
||||
|
||||
default:
|
||||
rpterr("& outword: bad rlflg\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
outinstr()
|
||||
{
|
||||
register i;
|
||||
register int *p1, *p2;
|
||||
|
||||
i = instrlen>>1;
|
||||
p1 = ins;
|
||||
p2 = rlbits;
|
||||
while(i--) {
|
||||
outword(*p1++, *p2++);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy data bits from temporary file to loader file*/
|
||||
cpdata()
|
||||
{
|
||||
myfflush(&lbuf);
|
||||
myfflush(&dabuf);
|
||||
docp(dafn,dafnc);
|
||||
}
|
||||
|
||||
/* copy text then data relocation bits from temporary file to loader file*/
|
||||
cprlbits()
|
||||
{
|
||||
myfflush(&lbuf);
|
||||
myfflush(&drbuf);
|
||||
docp(trbfn, trbfnc);
|
||||
docp(drbfn, drbfnc);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy one of the temporary files to the loader file
|
||||
* call with:
|
||||
* file descriptor of the temporary file
|
||||
* last char of the temporary file name
|
||||
*/
|
||||
docp(cfn,cfnc)
|
||||
{
|
||||
register i;
|
||||
|
||||
close(cfn);
|
||||
LASTCHTFN = cfnc;
|
||||
cfn = openfi(tfilname,0);
|
||||
while((i=read(cfn,itbuf,512)) > 0) {
|
||||
if(write(lfn,itbuf,i) != i) {
|
||||
rpterr("& file write error\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print one word in hex*/
|
||||
puthex(v,l)
|
||||
{
|
||||
register i,j,k;
|
||||
|
||||
j = 12;
|
||||
for(i=0; i<l; i++) {
|
||||
k = (v>>j)&017;
|
||||
k =+ (k >= 10) ? ('A'-10) : '0';
|
||||
putchar(k);
|
||||
j =- 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for a control operand*/
|
||||
controlea(ap)
|
||||
struct op *ap;
|
||||
{
|
||||
register i;
|
||||
|
||||
i = ap->ea&070;
|
||||
if(i==INDIRECT || i==INDDISP || i==INDINX)
|
||||
return(1);
|
||||
if(i==070) {
|
||||
if((ap->ea&7) <= 3)
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
ckcomma()
|
||||
{
|
||||
if(ckitc(pitw,',')) { /*next token a comma*/
|
||||
pitw++;
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* generate any necessary additional words for the effective address
|
||||
* call with:
|
||||
* pins pointing to next available word in ins[]
|
||||
* prlb pointing to next available word in rlbits[]
|
||||
* argument is ptr to op structure
|
||||
*
|
||||
* returns:
|
||||
* appropriate words in ins[] and rlbits[] for operand
|
||||
* pins and prlb updated.
|
||||
*/
|
||||
doea(apea)
|
||||
struct op *apea;
|
||||
{
|
||||
register i,j;
|
||||
register struct op *p;
|
||||
|
||||
p = apea;
|
||||
switch((p->ea>>3)&7) { /* ea mode bits*/
|
||||
|
||||
default: /*no more words*/
|
||||
return;
|
||||
|
||||
case 5: /* d(An)*/
|
||||
dodisp(p);
|
||||
return;
|
||||
|
||||
case 6: /* d(An,Ri)*/
|
||||
dindx:
|
||||
if (p->con > 127L || p->con < -128L) {
|
||||
uerr(35);
|
||||
}
|
||||
i = (p->con.wd2&0377) | (p->idx<<12) | (p->xmod<<11);
|
||||
if(p->drlc != ABS)
|
||||
uerr(27);
|
||||
*pins++ = i;
|
||||
*prlb++ = DABS;
|
||||
instrlen =+ 2;
|
||||
return;
|
||||
|
||||
case 7: /*xxx.W, xxx.L, or #xxx*/
|
||||
switch(p->ea&7) {
|
||||
|
||||
case 1: /* xxx.L*/
|
||||
doupper(p);
|
||||
p->con.wd1 = 0; /*clear for dodisp check*/
|
||||
|
||||
case 0: /* xxx.W*/
|
||||
dodisp(p);
|
||||
return;
|
||||
|
||||
case 2: /*d(PC)*/
|
||||
case 3: /*d(PC,Ri.X)*/
|
||||
if(p->drlc != ABS) {
|
||||
if(p->drlc != rlflg) /*not same reloc base*/
|
||||
uerr(27);
|
||||
p->con =- (loctr+instrlen);
|
||||
p->drlc = ABS;
|
||||
}
|
||||
if((p->ea&7) == 3) /*d(PC,Ri.X)*/
|
||||
goto dindx;
|
||||
dodisp(p);
|
||||
return;
|
||||
|
||||
case 4: /* #xxx*/
|
||||
chkimm(p); /*check for valid length*/
|
||||
if(modelen == 4) { /*instr mode is long*/
|
||||
doupper(p);
|
||||
p->con.wd1 = 0; /*clear for dodisp check*/
|
||||
}
|
||||
dodisp(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dodisp(ap)
|
||||
struct op *ap;
|
||||
{
|
||||
register struct op *p;
|
||||
|
||||
p = ap;
|
||||
*pins++ = p->con.wd2; /*displacement*/
|
||||
if(p->con.wd1 && p->con.wd1 != -1)
|
||||
uerr(41); /*invalid 16-bit disp*/
|
||||
*prlb++ = (p->ext != -1) ? (p->ext<<3)|EXTVAR : p->drlc;
|
||||
instrlen =+ 2;
|
||||
}
|
||||
|
||||
doupper(p)
|
||||
struct op *p;
|
||||
{
|
||||
*pins++ = p->con.wd1; /*upper half of long addr or constant*/
|
||||
*prlb++ = LUPPER;
|
||||
instrlen =+ 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* build a format 1 (add, sub, and, etc) instr
|
||||
* call with:
|
||||
* register #
|
||||
* mode bits
|
||||
* ptr to operand structure for effective address
|
||||
*/
|
||||
makef1(arreg, armode, apea)
|
||||
struct op *apea;
|
||||
{
|
||||
register i,j;
|
||||
register struct op *p;
|
||||
|
||||
p = apea;
|
||||
ins[0] =| (arreg<<9); /*put in reg #*/
|
||||
ins[0] =| armode; /*instr mode bits*/
|
||||
ins[0] =| p->ea; /*put in effective addr bits*/
|
||||
doea(p); /*may be more words in ea*/
|
||||
}
|
||||
|
||||
/* generate an immediate instr*/
|
||||
genimm()
|
||||
{
|
||||
ins[0] =| (f2mode[modelen] | opnd[1].ea);
|
||||
if(modelen == 4) {
|
||||
doupper(&opnd[0]);
|
||||
opnd[0].con.wd1 = 0; /*clear for dodisp check*/
|
||||
}
|
||||
chkimm(&opnd[0]); /*check for valid immed length*/
|
||||
dodisp(&opnd[0]);
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
chkimm(ap)
|
||||
struct op *ap;
|
||||
{
|
||||
register struct op *p;
|
||||
|
||||
p=ap;
|
||||
if(modelen == 2) { /*word*/
|
||||
if(p->con.wd1 && p->con.wd1!=-1)
|
||||
uerr(42);
|
||||
}
|
||||
else if(modelen == 1) { /*byte*/
|
||||
if(p->con.wd1 && p->con.wd1!=-1)
|
||||
uerr(43);
|
||||
if(p->con.wd2>255 || p->con.wd2<=-256)
|
||||
uerr(43);
|
||||
}
|
||||
}
|
||||
|
||||
/* try to make a normal instr into an immediate instr*/
|
||||
makeimm()
|
||||
{
|
||||
if(opnd[0].ea != IMM)
|
||||
return(0);
|
||||
if(!dataalt(&opnd[1]))
|
||||
return(0);
|
||||
if(opcpt == addptr)
|
||||
opcpt = addiptr;
|
||||
else if(opcpt == andptr)
|
||||
opcpt = andiptr;
|
||||
else if(opcpt == orptr)
|
||||
opcpt = oriptr;
|
||||
else if(opcpt == subptr)
|
||||
opcpt = subiptr;
|
||||
else if(opcpt == cmpptr)
|
||||
opcpt = cmpiptr;
|
||||
else if(opcpt == eorptr)
|
||||
opcpt = eoriptr;
|
||||
else
|
||||
return(0);
|
||||
ins[0] = opcpt->vl1.wd2;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
genimm();
|
||||
return(1);
|
||||
}
|
||||
|
||||
ckbytea()
|
||||
{
|
||||
if(modelen==1 && !dataea(&opnd[0]))
|
||||
uerr(20); /*byte mod not allowed*/
|
||||
}
|
||||
|
||||
/* get a special register token (CCR, SR, or USP)*/
|
||||
gspreg()
|
||||
{
|
||||
register i;
|
||||
|
||||
i = getrgs();
|
||||
if(i>AREGHI)
|
||||
return(i);
|
||||
if(i != -1)
|
||||
pitw--;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* check an operand for a special register
|
||||
* call with:
|
||||
* ptr to operand struct
|
||||
* special register value
|
||||
*/
|
||||
cksprg(ap,v1)
|
||||
struct op *ap;
|
||||
{
|
||||
if(ap->ea)
|
||||
return(0);
|
||||
if(ap->idx == v1)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check for operand as any special register*/
|
||||
anysprg(ap)
|
||||
struct op *ap;
|
||||
{
|
||||
if(ap->ea)
|
||||
return(0);
|
||||
if(ap->idx>=CCR && ap->idx<=USP)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* copy opnd 0 to opnd 1*/
|
||||
cpop01()
|
||||
{
|
||||
opnd[1].ea = opnd[0].ea;
|
||||
opnd[1].len = opnd[0].len;
|
||||
opnd[1].con = opnd[0].con;
|
||||
opnd[1].drlc = opnd[0].drlc;
|
||||
opnd[1].ext = opnd[0].ext;
|
||||
opnd[1].idx = opnd[0].idx;
|
||||
opnd[1].xmod = opnd[0].xmod;
|
||||
}
|
||||
|
||||
cksize(ap) /* [vlh] try to check displacement range */
|
||||
struct op *ap;
|
||||
{
|
||||
long value;
|
||||
|
||||
if ((ap->ea&070) != 070) return;
|
||||
value = (ap->con>0 && ap->con&0100000) ? -(ap->con&~0100000) : ap->con;
|
||||
if (modelen == 1) {
|
||||
if (value < -128L || value > 127L) /* 8 bits */
|
||||
uerr(35);
|
||||
}
|
||||
else if (modelen == 2)
|
||||
if (value > 32767L || value < -32768L) /* 16 bits */
|
||||
uerr(41);
|
||||
}
|
||||
|
||||
ccr_or_sr() /* [vlh] */
|
||||
{
|
||||
if(opnd[1].idx==CCR)
|
||||
modelen = 1; /*byte mode only*/
|
||||
else /* [vlh] SR */
|
||||
if (modelen != 2) {
|
||||
modelen = 2;
|
||||
uerr(34);
|
||||
}
|
||||
cksize(&opnd[0]);
|
||||
ins[0] =| IMM | f2mode[modelen];
|
||||
dodisp(&opnd[0]);
|
||||
}
|
||||
|
||||
get2ops()
|
||||
{
|
||||
getea(0); /*get first effective address*/
|
||||
if(!ckcomma()) {
|
||||
uerr(10);
|
||||
return(1); /*no second op*/
|
||||
}
|
||||
getea(1); /*get second effective address*/
|
||||
return(0);
|
||||
}
|
||||
Reference in New Issue
Block a user