mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
110 lines
2.9 KiB
C
110 lines
2.9 KiB
C
/*
|
|
Copyright 1981
|
|
Alcyon Corporation
|
|
8716 Production Ave.
|
|
San Diego, Ca. 92121
|
|
*/
|
|
|
|
/* reduce long relative branches to short if possible*/
|
|
|
|
#include "as68.h"
|
|
int nitleft;
|
|
char tfilname[];
|
|
int p2gi();
|
|
long lseek();
|
|
pass1a()
|
|
{
|
|
register long reduced;
|
|
register int i, wsize;
|
|
register long oldpos,newpos; /* Old and new file seek pointers */
|
|
register j; /* temp */
|
|
|
|
pitix = itbuf;
|
|
nitleft = 0;
|
|
reduced = 0; itoffset = 0; stbuf[0].itrl = 0;
|
|
wsize = 3*sizeof stbuf[0]; /* [vlh] don't calculate many times */
|
|
close(itfn);
|
|
LASTCHTFN = itfnc;
|
|
itfn = openfi(tfilname,2,1); /*open it for update*/
|
|
while(ristb()) {
|
|
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
|
if(!(opcpt->flags&OPDR)) { /*not a directive*/
|
|
format = (opcpt->flags)&OPFF;
|
|
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
|
if(((format==6 && p1inlen==4) || opcpt==jsrptr) &&
|
|
(rlflg=stbuf[3].itrl)==TEXT) {
|
|
nite = stbuf[0].itrl & 0377;/* # of it entries */
|
|
pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
|
|
modelen = stbuf[2].itrl; /*instr mode length*/
|
|
opdix = ITOP1; /*first operand*/
|
|
pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
|
|
loctr = stbuf[3].itop - reduced;
|
|
expr(&p2gi);
|
|
ival =- loctr+2L;
|
|
if(itype==ITCN && !extflg && reloc!=ABS) {
|
|
if(format==9) { /*jsr*/
|
|
i = (ival>= -128 && ival<=127) ? p1inlen-2 :
|
|
(ival>= -32768 && ival<=32767) ? p1inlen-4 : 0;
|
|
if (!i)
|
|
continue;
|
|
stbuf[2].itop.ptrw2 = bsrptr; /*chng to bsr*/
|
|
}
|
|
else if(ival>= -128 && ival<=127) {
|
|
i = 2; /*[vlh]was 4 for ival=2*/
|
|
if (!ival) stbuf[2].itop.ptrw2 = nopptr;
|
|
}
|
|
else
|
|
continue;
|
|
fixsyadr(i);
|
|
reduced =+ i;
|
|
stbuf[1].itrl =- i; /*reduced somewhat*/
|
|
if(!stbuf[1].itrl)
|
|
stbuf[1].itrl = -1; /*ignore flag*/
|
|
oldpos=lseek(itfn,0L,1); /* Remember current position */
|
|
newpos= itoffset -
|
|
(stbuf[0].itrl*sizeof stbuf[0]);
|
|
if(lseek(itfn,newpos,0) < 0) {
|
|
rpterr("seek error on it file\n");
|
|
abort();
|
|
}
|
|
if(write(itfn,&stbuf[0],wsize) != wsize) {
|
|
rpterr("write error on it file\n");
|
|
abort();
|
|
}
|
|
lseek(itfn,oldpos,0);
|
|
}
|
|
}
|
|
}
|
|
else if(opcpt == endptr) {
|
|
savelc[TEXT] =- reduced;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* fix all symbol addresses that are text based and greater than loctr*/
|
|
/* fix means subtract 2 from them*/
|
|
fixsyadr(al)
|
|
{
|
|
register char **sx1, **sx2;
|
|
register l;
|
|
|
|
l = al;
|
|
/* 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 || sx2->flags&SYPC) && sx2->flags&SYRO &&
|
|
sx2->vl1 > loctr) /* [vlh] */
|
|
sx2->vl1 =- l;
|
|
if(sx2 == *sx1) /*end of chain*/
|
|
break;
|
|
sx2 = sx2->tlnk; /*next entry in chain*/
|
|
}
|
|
}
|
|
}
|