|
|
1.1 root 1: /* a6 -- pdp-11 assembler pass 2 */
2: #include "as2.h"
3: #define BR 0400
4: #define JMP 0100
5:
6: struct adr {
7: int xval; /* index value */
8: int xrel; /* index reloc. */
9: struct expr *xsym; /* index global */
10: } adrbuf[2];
11: struct adr *adrp;
12:
13: opline(op)
14: OP op;
15: {
16: struct expr x;
17: register int w,src,dst,rlimit,swapf,t;
18:
19: if (ISCHAR(op)) {
20: if (op.v==5) {/* file name of source */
21: register char *cp=argb;
22: line=1;
23: while ((unsigned)(t=getw())<0200) if (cp<(argb+sizeof(argb))) *cp++=t;
24: *cp++='\n'; *cp++='\0'; return;
25: }
26: if (op.v=='<') goto opl17;
27: xpr:
28: x=expres(op); outw(x.typ,x.val); return;
29: }
30: t=op.xp->typ;
31: if (t==T_REG || t==T_ESTTXT || t==T_ESTDAT || t<T_FLOPD || t>T_JXX) goto xpr;
32: w=op.xp->val;
33: op=readop(); adrp=adrbuf; swapf=0; rlimit= 07777;
34: switch (t) {
35: case T_REG:
36: case T_ESTTXT:
37: case T_ESTDAT:
38: goto xpr;
39:
40: case T_MUL: swapf++; rlimit=01000; goto opl13;
41: case T_FLOPF: swapf++;
42: case T_FLOPD: rlimit=0400;
43: case T_DOUBLE:
44: opl13: src=addres();
45: op2a: readop(); /* prime the pump */
46: op2b: dst=addres();
47: if (swapf) {t=src; src=dst; dst=t;}
48: if ((src<<=6)>=rlimit) error('x');
49: outw(0,w|src|dst);
50: {
51: register struct adr *p;
52: for (p=adrbuf; p<adrp; p++) {
53: xsymbol=p->xsym; outw(p->xrel,p->xval);
54: }
55: }
56: return;
57: case T_SINGLE: src=0; goto op2b;
58:
59: case T_MOVF:
60: rlimit=0400;
61: if ((src=addres())>=4) swapf++; /* src is freg */
62: else w=0174000;
63: goto op2a;
64: case T_JBR:
65: case T_JXX:
66: x=expres(op);
67: if (passno==0) {
68: if (0!=(t=setbr(x.val)) && w!=BR) t+=2;
69: *dot+=t+2; return;
70: } else {
71: if (getbr()==0) goto dobranch;
72: if (w!=BR) outw(T_ABS,w^0402); /* flip jump to .+6 */
73: outw(T_ABS,JMP+037); outw(x.typ,x.val); return;
74: }
75: case T_SOB:
76: x=expres(op); chkreg(&x); w |= x.val<<6; x=expres(readop());
77: if (passno==0) {outw(0,w|x.val); return;}
78: if ((x.val= *dot-x.val)<-2 || x.val>0175) {error('b'); outw(0,w); return;}
79: x.val+=4; goto f1;
80: case T_BRANCH:
81: x=expres(op);
82: if (passno!=0) {
83: dobranch:
84: if ((x.val-= *dot)<-254 || x.val>256) {error('b'); outw(0,w); return;}
85: f1:
86: if (x.val&1 || x.typ!= *dotrel) {error('b'); outw(0,w); return;}
87: outw(0,w|(((x.val>>1)-1)&0377)); return;
88: }
89: outw(0,w|x.val); return;
90: case T_JSR: x=expres(op); chkreg(&x); src=x.val; goto op2a;
91: case T_RTS: x=expres(op); chkreg(&x); outw(0,w|x.val); return;
92: case T_SYS:
93: x=expres(op); if ((unsigned)x.val>=256 || x.typ>T_ABS) errora();
94: outw(x.typ,w|x.val); return;
95: case T_BYTE:
96: for (;;) {
97: x=expres(op); outb(x.typ,x.val); if (!LAST(',')) return;
98: op=readop();
99: }
100: case T_STRING:
101: opl17:
102: for (;;) {
103: if ((unsigned)(t=getw())>=0600) {getw(); return;}
104: outb(T_ABS,t&0377);
105: }
106: case T_EVEN:
107: if (*dot&1) {
108: if (*dotrel!=T_BSS) outb(0,0);
109: else (*dot)++;
110: }
111: return;
112:
113: case T_IF: x=expres(op);
114: case T_ENDIF: return;
115:
116: case T_GLOBL:
117: for (;;) if (!ISCHAR(op)) {
118: op.xp->typ |= T_EXTERN;
119: op=readop(); if (!LAST(',')) break;
120: op=readop();
121: } else break;
122: return;
123:
124: case T__TEXT:
125: case T__DATA:
126: case T__BSS:
127: *dot=(*dot+1)&~1;
128: savdot[*dotrel-T_TEXT] = *dot;
129: if (passno!=0 && t!=T__BSS) {
130: fseek(txtf,tseek[t-T__TEXT],0);
131: fseek(relf,rseek[t-T__TEXT],0);
132: }
133: *dot = savdot[t-T__TEXT];
134: *dotrel = t-T__TEXT+T_TEXT;
135: return;
136:
137: case T_COMM:
138: if (!ISCHAR(op)) {
139: readop(); x=expres(readop());
140: if ((op.xp->typ&037)==T_UNDEF) {
141: op.xp->typ |= T_EXTERN; op.xp->val=x.val;
142: }
143: }
144: return;
145: }
146: }
147:
148: addres() /* returns 6-bit pdp-11 addressing mode */
149: {
150: register int indir=0;
151: struct expr x;
152:
153: again:
154: if (LAST('(')) {
155: x=expres(readop()); chkreg(&x); chkrp();
156: if (!LAST('+')) {
157: if (indir!=0) {/* concession for "*(r)" meaning "*0(r)" */
158: adrp->xval=0; adrp->xrel=0; adrp->xsym=xsymbol; adrp++;
159: return(x.val|070);
160: } else return(010|x.val);
161: }
162: readop(); return(indir|020|x.val);
163: } else if (LAST('-')) {
164: readop();
165: if (!LAST('(')) {
166: savop=lastop; lastop.v='-'; /* fall through to end of else-if */
167: } else {
168: x=expres(readop()); chkreg(&x); chkrp();
169: return(indir|040|x.val);
170: }
171: } else if (LAST('$')) {
172: x=expres(readop());
173: adrp->xval=x.val; adrp->xrel=x.typ; adrp->xsym=xsymbol; adrp++;
174: return(indir|027);
175: } else if (LAST('*')) {
176: if (indir) error('*');
177: indir=010; readop(); goto again;
178: }
179: x=expres(lastop);
180: if (LAST('(')) {
181: adrp->xval=x.val; adrp->xrel=x.typ; adrp->xsym=xsymbol; adrp++;
182: x=expres(readop()); chkreg(&x); chkrp();
183: return(indir|060|x.val);
184: }
185: if (x.typ==T_REG) {
186: chkreg(&x); return(indir|x.val);
187: } else {
188: x.typ|=PCREL; x.val=x.val-*dot-4; if (adrp!=adrbuf) x.val-=2;
189: adrp->xval=x.val; adrp->xrel=(unsigned short)x.typ; adrp->xsym=xsymbol; adrp++;
190: return(indir|067);
191: }
192: }
193:
194: errora()
195: {
196: error('a');
197: }
198:
199: chkreg(p)
200: register struct expr *p;
201: {
202: if (((unsigned)p->val)>7 || (p->typ!=T_ABS && ((unsigned)p->typ)<=T_BSS)) {
203: errora(); p->typ=0; p->val=0;
204: }
205: }
206:
207: errore()
208: {
209: error('e');
210: }
211:
212: chkrp()
213: {
214: if (!LAST(')')) {error(')'); return;}
215: readop();
216: }
217:
218: #define BRLEN 1024
219: char brtab[BRLEN/8];
220: char bit[8] = {1,2,4,8,16,32,64,128};
221: int brtabp;
222:
223: setbr(d)
224: register int d;
225: {
226: register int t;
227:
228: if (brtabp>=BRLEN) return(2);
229: t=brtabp++;
230: if ((d-= *dot)>0) d-=brdelt;
231: if (d>=-254 && d<=256) return(0);
232: brtab[t>>3] |= bit[t&7];
233: return(2);
234: }
235:
236: getbr()
237: {
238: register int t;
239:
240: if (brtabp>=BRLEN) return(1);
241: t=brtabp++;
242: return(brtab[t>>3]&bit[t&7]);
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.