mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
857 lines
26 KiB
Plaintext
857 lines
26 KiB
Plaintext
1File: PASS2.C Page 1
|
|
1 /*
|
|
2 Copyright 1981
|
|
3 Alcyon Corporation
|
|
4 8716 Production Ave.
|
|
5 San Diego, Ca. 92121
|
|
6 */
|
|
7
|
|
8 /*
|
|
9 * pass two for the 68000 assembler
|
|
10 * Bill Allen
|
|
11 * March 1980
|
|
12 */
|
|
13
|
|
14 #include "as68.h"
|
|
15 #include "cout.h" /*c.out header definition & MAGIC*/
|
|
16
|
|
17 #define MOVEA 0100
|
|
18
|
|
19 int p2gi();
|
|
20
|
|
21 extern char tfilname[]; /*name of it file*/
|
|
22 extern char initfnam[]; /*name of the initilization file*/
|
|
23 int (*p2direct[])();
|
|
24
|
|
25 int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
|
|
26 int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
|
|
27 int opf21(), opf22(), opf23();
|
|
28
|
|
29 int (*opfary[])() {
|
|
30 0, /*0*/
|
|
31 opf1, /*1*/
|
|
32 opf2, /*2*/
|
|
33 opf3, /*3*/
|
|
34 opf4, /*4*/
|
|
35 opf5, /*5*/
|
|
36 relbr, /*6*/
|
|
37 opf7, /*7*/
|
|
38 opf8, /*8*/
|
|
39 opf9, /*9*/
|
|
40 opf4, /*10*/
|
|
41 opf11, /*11*/
|
|
42 opf12, /*12*/
|
|
43 opf13, /*13*/
|
|
44 opf9, /*14*/
|
|
45 opf15, /*15*/
|
|
46 opf17, /*16*/
|
|
47 opf17, /*17*/
|
|
48 opf13, /*18*/
|
|
49 opf11, /*19*/
|
|
50 opf20, /*20*/
|
|
51 opf21, /*21*/
|
|
52 opf22, /*22*/
|
|
53 opf23, /*23*/
|
|
54 opf9, /*24*/
|
|
55 opf9, /*25*/
|
|
56 opf5, /*26*/ /* [vlh] cmp, chk, extention verification */
|
|
57 opf4, /*27*/ /* [vlh] addx, subx, extension verification */
|
|
58 opf13, /*28*/ /* [vlh] swap, extension verification */
|
|
59 opf9, /*29*/ /* [vlh] pea, extention verification */
|
|
1File: PASS2.C Page 2
|
|
60 opf15 /*30*/ /* [vlh] lea, extension verification */
|
|
61 };
|
|
62
|
|
63 #define LSTFRMT 30
|
|
64
|
|
65 int f1mode[] {0,0,0100,0,0200};
|
|
66 int f2mode[] {0,0,0100,0,0200};
|
|
67 int f3mode[] {0,010000,030000,0,020000};
|
|
68 int f15mode[] {0,0,0300,0,0700};
|
|
69 int f5mode[] {0,0,0100,0,0200};
|
|
70 int f5amode[] {0,0,0300,0,0700};
|
|
71 int f13mode[] {0,0,0200,0,0300};
|
|
72 int f23mode[] {0,0400,0500,0,0600};
|
|
73 int rlbits[5]; /*holds relocation bits for instr*/
|
|
74 int pline; /*number of last printed line*/
|
|
75 int brkln2 077777; /*pass 2 break line number for debugging*/
|
|
76 int prsp; /*special print alignment flag*/
|
|
77 int amode; /*addressing mode*/
|
|
78 int nitleft;
|
|
79 /*pass two driver*/
|
|
80 pass2()
|
|
81 {
|
|
82 register short *p;
|
|
83 register i;
|
|
84 register (*dirop)();
|
|
85
|
|
86 pitix = itbuf; /* This is init for doitrd*/
|
|
87 xline = LPP;
|
|
88 nitleft = 0;
|
|
89 lbuf.nunused = tbuf.nunused = dabuf.nunused = drbuf.nunused = 512;
|
|
90 lbuf.fildes = lfn; /*set buffered io for binary file*/
|
|
91 lbuf.xfree = &lbuf.buff[0];
|
|
92 tbuf.fildes = trbfn; /*set buffered io for text reloc bits file*/
|
|
93 tbuf.xfree = &tbuf.buff[0];
|
|
94 dabuf.fildes = dafn; /*set buffered io for data bytes*/
|
|
95 dabuf.xfree = &dabuf.buff[0];
|
|
96 drbuf.fildes = drbfn; /*set buffered io for data reloc bits*/
|
|
97 drbuf.xfree = &drbuf.buff[0];
|
|
98 couthd.ch_magic = MAGIC;/*c.out magic number*/
|
|
99 if(savelc[TEXT]&1)
|
|
100 savelc[TEXT]++; /*make it even*/
|
|
101 couthd.ch_tsize = savelc[TEXT]; /*text size*/
|
|
102 if(savelc[DATA]&1)
|
|
103 savelc[DATA]++; /*make it even*/
|
|
104 couthd.ch_dsize = savelc[DATA]; /*data size*/
|
|
105 couthd.ch_bsize = savelc[BSS]; /*bss size*/
|
|
106 /*symbol table size is not known now -- it is set at end of pass 2*/
|
|
107 /* entry point and stack size are zero for now*/
|
|
108 p = &couthd;
|
|
109 for(i=0; i<HDSIZE/2; i++) {
|
|
110 putw(*p++,&lbuf); /*write the file header words*/
|
|
111 }
|
|
112 savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
|
|
113 loctr = 0; /*location counter*/
|
|
114 rlflg = TEXT; /*TEXT relocatable*/
|
|
115 p2flg = 1; /*pass two*/
|
|
116 #ifdef UNIX
|
|
117 if (lseek(ifn,0L,0) == -1) { /*beginning of source*/
|
|
118 rpterr("seek error on source file\n");
|
|
1File: PASS2.C Page 3
|
|
119 abort();
|
|
120 }
|
|
121 #else
|
|
122 close(ifn); /* This way for goddamn Whitesmith's */
|
|
123 ifn=open(sfname,0,0); /* Re-open the fucking source file */
|
|
124 if(ifn < 0) /* Couldn't */
|
|
125 {
|
|
126 printf("Unable to open file %s\n",sfname);
|
|
127 abort();
|
|
128 }
|
|
129 #endif
|
|
130 close(itfn);
|
|
131 LASTCHTFN = itfnc;
|
|
132 itfn = openfi(tfilname,0); /*open it for reading*/
|
|
133 pline = 1; /*no lines printed*/
|
|
134 fchr=gchr(); /*get first char*/
|
|
135 while(ristb()) { /*pass 2 main loop*/
|
|
136 p2absln = stbuf[0].itop; /*line number*/
|
|
137 if(p2absln>=brkln2) /*for debugging the assembler*/
|
|
138 i=0;
|
|
139 opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
|
140 nite = stbuf[0].itrl & 0377; /*number of it entries*/
|
|
141 pnite = &stbuf[nite]; /*ptr to end of stmt*/
|
|
142 modelen = stbuf[2].itrl; /*instr mode length*/
|
|
143 p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
|
144 opdix = ITOP1; /*first operand*/
|
|
145 pitw = &stbuf[ITOP1]; /*ptr to first operand*/
|
|
146 prsp = 0; /*special print flag off*/
|
|
147 instrlen = 2; /*default for print*/
|
|
148 if(opcpt->flags&OPDR) { /*opcode is a directive*/
|
|
149 i = opcpt->vl1; /*directive number*/
|
|
150 dirop = p2direct[i];
|
|
151 (*dirop)(); /*handle directive*/
|
|
152 }
|
|
153 else {
|
|
154 gcist(); /*generate code for one statement*/
|
|
155 }
|
|
156 }
|
|
157 }
|
|
158
|
|
159 /* generate code for an instruction*/
|
|
160 /* call with*/
|
|
161 /* intermediate text for instruction in stbuf*/
|
|
162 gcist()
|
|
163 {
|
|
164 register i,j;
|
|
165
|
|
166 if(stbuf[0].itty != ITBS) /*beginning of statement*/
|
|
167 abort();
|
|
168 format = (opcpt->flags)&OPFF;
|
|
169 in_err = 0; /*[vlh] no error this instruction, yet*/
|
|
170 ival = 0; /*initial value for possible operand*/
|
|
171 reloc = ABS;
|
|
172 instrlen = 2; /*at least 2 bytes*/
|
|
173 ins[0] = opcpt->vl1; /*opcode value*/
|
|
174 rlbits[0] = INSABS; /*instruction absolute*/
|
|
175 pins = &ins[1];
|
|
176 prlb = &rlbits[1];
|
|
177 if(nite>ITOP1) { /*operands*/
|
|
1File: PASS2.C Page 4
|
|
178 if(!format) {
|
|
179 uerr(9);
|
|
180 }
|
|
181 else if(format>LSTFRMT) /* [vlh] was a magic number... */
|
|
182 abort();
|
|
183 else {
|
|
184 (*opfary[format])();
|
|
185 }
|
|
186 }
|
|
187 if (!ckein() && !in_err) /* at end of statement ?? */
|
|
188 uerr(6);
|
|
189 print(1); /*print source*/
|
|
190
|
|
191 loctr =+ p1inlen;
|
|
192 if (!in_err && p1inlen != instrlen) /* [vlh] 2nd pass error recovery */
|
|
193 uerr(38);
|
|
194 outinstr(); /*write out instr binary*/
|
|
195 }
|
|
196
|
|
197 /* relative branches*/
|
|
198 relbr()
|
|
199 {
|
|
200 expr(&p2gi);
|
|
201 if(extflg) { /*external reference*/
|
|
202 instrlen =+ 2; /*long relative*/
|
|
203 *pins++ = ival; /*pass constant part*/
|
|
204 *prlb++ = (extref<<3)|EXTREL; /*ext ref*/
|
|
205 return;
|
|
206 }
|
|
207 ival =- (loctr+2); /*calc relative offset*/
|
|
208 if(itype!=ITCN || reloc != rlflg) {
|
|
209 uerr(22); /*invalid relative branch*/
|
|
210 ival = 0;
|
|
211 }
|
|
212 reloc = ABS;
|
|
213 if(p1inlen==4) { /*long displacement*/
|
|
214 if(ival< (-32768L) || ival > (32767L))
|
|
215 uerr(22);
|
|
216 instrlen =+ 2;
|
|
217 *pins++ = ival;
|
|
218 *prlb++ = DABS; /*data absolute*/
|
|
219 }
|
|
220 else { /*short displacement*/
|
|
221 if (ival>127 || ival<-128)
|
|
222 uerr(22);
|
|
223 ins[0] =| (ival.wd2&0377);
|
|
224 }
|
|
225 if (!ival) { /* make it a nop */
|
|
226 opcpt = nopptr;
|
|
227 ins[0] = opcpt->vl1.wd2;
|
|
228 pins = &ins[1];
|
|
229 if (modelen==4) {
|
|
230 *pins++ = opcpt->vl1.wd2;
|
|
231 rlbits[1] = INSABS;
|
|
232 }
|
|
233 }
|
|
234 in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
|
|
235 }
|
|
236
|
|
1File: PASS2.C Page 5
|
|
237 /* format one -- add, sub, and, or, cmp, etc.*/
|
|
238 /* one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
|
|
239 opf1()
|
|
240 {
|
|
241 register int *p;
|
|
242
|
|
243 if(get2ops())
|
|
244 return;
|
|
245 if (ins[0]==AND || ins[0]==OR)
|
|
246 if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
|
247 if (ins[0]==AND) opcpt = andiptr;
|
|
248 else opcpt = oriptr;
|
|
249 ins[0] = opcpt->vl1.wd2;
|
|
250 format = (opcpt->flags)&OPFF;
|
|
251 ccr_or_sr();
|
|
252 return;
|
|
253 }
|
|
254 p = f1mode;
|
|
255 if(ckdreg(&opnd[1])) { /*destn is D reg*/
|
|
256 if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0])) /*A source*/
|
|
257 uerr(20);
|
|
258 makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
|
259 return;
|
|
260 }
|
|
261 else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) { /*source is D reg*/
|
|
262 if (pcea(&opnd[1])) uerr(10);
|
|
263 makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
|
|
264 return;
|
|
265 }
|
|
266 else if(ckareg(&opnd[1])) { /*A reg is dstn*/
|
|
267 if(opcpt==addptr)
|
|
268 opcpt = addaptr;
|
|
269 else if(opcpt==cmpptr)
|
|
270 opcpt = cmpaptr;
|
|
271 else if(opcpt==subptr)
|
|
272 opcpt = subaptr;
|
|
273 else {
|
|
274 uerr(20);
|
|
275 return;
|
|
276 }
|
|
277 format = (opcpt->flags)&OPFF;
|
|
278 opnd[1].ea =& 07;
|
|
279 p = f15mode;
|
|
280 makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
|
281 return;
|
|
282 }
|
|
283 else if(!makeimm()) /*make an immediate instr*/
|
|
284 uerr(20);
|
|
285 }
|
|
286
|
|
287 /* format 2 -- addi, andi, subi, etc*/
|
|
288 opf2()
|
|
289 {
|
|
290 if(get2ops())
|
|
291 return;
|
|
292 if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
|
|
293 if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
|
294 ccr_or_sr();
|
|
295 return;
|
|
1File: PASS2.C Page 6
|
|
296 }
|
|
297 }
|
|
298 if(opnd[0].ea != IMM) {
|
|
299 uerr(9);
|
|
300 return;
|
|
301 }
|
|
302 if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
|
|
303 uerr(20);
|
|
304 return;
|
|
305 }
|
|
306 genimm();
|
|
307 }
|
|
308
|
|
309 /*format #3 -- move and movea*/
|
|
310 opf3()
|
|
311 {
|
|
312 register i,j,k;
|
|
313
|
|
314 if(get2ops())
|
|
315 return;
|
|
316 if(cksprg(&opnd[1],CCR)) {
|
|
317 ins[0] = MOVECCR;
|
|
318 opf3l1:
|
|
319 if (modelen==1 || modelen==4) uerr(34);
|
|
320 if(anysprg(&opnd[0]))
|
|
321 uerr(20);
|
|
322 ins[0] =| opnd[0].ea;
|
|
323 if(!dataea(&opnd[0]))
|
|
324 uerr(9);
|
|
325 doea(&opnd[0]);
|
|
326 return;
|
|
327 }
|
|
328 if(cksprg(&opnd[1],SR)) {
|
|
329 ins[0] = MOVESR;
|
|
330 goto opf3l1;
|
|
331 }
|
|
332 if(cksprg(&opnd[0],SR)) {
|
|
333 if (modelen==1 || modelen==4)
|
|
334 uerr(34);
|
|
335 if(anysprg(&opnd[1]))
|
|
336 uerr(20);
|
|
337 ins[0] = SRMOVE | opnd[1].ea;
|
|
338 if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
|
339 uerr(10);
|
|
340 doea(&opnd[1]);
|
|
341 return;
|
|
342 }
|
|
343 if(cksprg(&opnd[0],USP)) {
|
|
344 if (modelen == 1)
|
|
345 uerr(34); /* default is word, can't test */
|
|
346 if (!ckareg(&opnd[1]))
|
|
347 uerr(33);
|
|
348 ins[0] = MOVEUSP|8|(opnd[1].ea&7);
|
|
349 return;
|
|
350 }
|
|
351 if(cksprg(&opnd[1],USP)) {
|
|
352 if (modelen == 1)
|
|
353 uerr(34); /* default is word, can't test */
|
|
354 if (!ckareg(&opnd[0]))
|
|
1File: PASS2.C Page 7
|
|
355 uerr(33);
|
|
356 ins[0] = MOVEUSP|(opnd[0].ea&7);
|
|
357 return;
|
|
358 }
|
|
359 k = ins[0];
|
|
360 ins[0] =| f3mode[modelen];
|
|
361 ckbytea();
|
|
362 ins[0] =| opnd[0].ea; /*source ea*/
|
|
363 doea(&opnd[0]);
|
|
364 ins[0] =| (opnd[1].ea&7)<<9; /*dest register*/
|
|
365 ins[0] =| (opnd[1].ea&070)<<3; /*dest mode*/
|
|
366 doea(&opnd[1]);
|
|
367 if(k==MOVEA) {
|
|
368 if(dataea(&opnd[1]))
|
|
369 uerr(20);
|
|
370 }
|
|
371 else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
|
|
372 uerr(20);
|
|
373 }
|
|
374
|
|
375 /* format 4 -- abcd, sbcd */
|
|
376 /* format 10 -- cmpm*/
|
|
377 /* format 27 -- addx, subx */
|
|
378 opf4()
|
|
379 {
|
|
380 if(get2ops())
|
|
381 return;
|
|
382 if (format==27) { /*addx,subx add in size bits*/
|
|
383 ins[0] =| f1mode[modelen];
|
|
384 }
|
|
385 else if(format==10) { /*cmpm*/
|
|
386 if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
|
|
387 uerr(20);
|
|
388 ins[0] =| f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
|
389 return;
|
|
390 }
|
|
391 if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
|
|
392 ins[0] =| ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
|
393 return;
|
|
394 }
|
|
395 if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
|
|
396 ins[0] =| 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
|
397 return;
|
|
398 }
|
|
399 uerr(20);
|
|
400 }
|
|
401
|
|
402 /*format 5 -- div, mul*/
|
|
403 /*format 26 -- cmp, chk */
|
|
404 opf5()
|
|
405 {
|
|
406 if(get2ops())
|
|
407 return;
|
|
408 if(!ckdreg(&opnd[1])) {
|
|
409 if(opcpt==cmpptr) {
|
|
410 if(!dataea(&opnd[1])) /* [vlh] made define */
|
|
411 ins[0] =| f5amode[modelen]; /* was pumode */
|
|
412 else if(makeimm())
|
|
413 return;
|
|
1File: PASS2.C Page 8
|
|
414 else
|
|
415 uerr(20);
|
|
416 }
|
|
417 else
|
|
418 uerr(20);
|
|
419 }
|
|
420 if(opcpt==cmpptr) {
|
|
421 ins[0] =| f5mode[modelen]; /* was pumode */
|
|
422 ckbytea();
|
|
423 }
|
|
424 else if(!dataea(&opnd[0]))
|
|
425 uerr(20);
|
|
426 ins[0] =| (opnd[1].ea&7)<<9 | opnd[0].ea;
|
|
427 doea(&opnd[0]);
|
|
428 }
|
|
429
|
|
430 #define BTST 0000
|
|
431 /* format 7 -- bit instrs -- btst, bclr, bset, etc*/
|
|
432 opf7()
|
|
433 {
|
|
434 if(get2ops())
|
|
435 return;
|
|
436 if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
|
|
437 uerr(20);
|
|
438 if(ckdreg(&opnd[0])) {
|
|
439 ins[0] =| (opnd[0].ea<<9)|0400;
|
|
440 }
|
|
441 else { /*static bit #*/
|
|
442 if(opnd[0].con<0L || opnd[0].con>31 ||
|
|
443 (opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
|
|
444 uerr(23);
|
|
445 if(opnd[0].ea != IMM)
|
|
446 uerr(17);
|
|
447 ins[0] =| 04000;
|
|
448 dodisp(&opnd[0]);
|
|
449 }
|
|
450 if (modelen==1 && !(memea(&opnd[1]))) /*[vlh]*/
|
|
451 uerr(20);
|
|
452 else if (!(ckdreg(&opnd[1])) && modelen==4)
|
|
453 uerr(20);
|
|
454 ins[0] =| opnd[1].ea;
|
|
455 doea(&opnd[1]);
|
|
456 }
|
|
457
|
|
458 /* format 8 -- shifts and rotates*/
|
|
459 opf8()
|
|
460 {
|
|
461 register i;
|
|
462
|
|
463 getea(0); /*get first operand*/
|
|
464 if(pitw >= pnite) { /*end of all ops*/
|
|
465 if(ckdreg(&opnd[0])) { /*shift dreg one bit*/
|
|
466 cpop01(); /*copy opnd 0 to 1*/
|
|
467 opnd[0].ea = IMM;
|
|
468 opnd[0].con = 1L;
|
|
469 if (!ckdreg(&opnd[1])) uerr(20);
|
|
470 opf8l1:
|
|
471 if(opnd[0].con<1 || opnd[0].con>8) /*[vlh legal range 1..8*/
|
|
472 uerr(37);
|
|
1File: PASS2.C Page 9
|
|
473 ins[0] =| ((opnd[0].con.wd2&7)<<9)|f1mode[modelen]|opnd[1].ea;
|
|
474 return;
|
|
475 }
|
|
476 i = (ins[0]&077)<<6;
|
|
477 ins[0] =& 0177700;
|
|
478 ins[0] =| 0300|i|opnd[0].ea;
|
|
479 if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
|
|
480 uerr(20);
|
|
481 doea(&opnd[0]);
|
|
482 return;
|
|
483 }
|
|
484 if(!ckcomma()) {
|
|
485 uerr(10);
|
|
486 return;
|
|
487 }
|
|
488 getea(1); /*get second operand*/
|
|
489 if(!ckdreg(&opnd[1])) /* [vlh] second operand must be dreg */
|
|
490 uerr(20);
|
|
491 if(ckdreg(&opnd[0])) { /*first op is D reg*/
|
|
492 ins[0] =| (opnd[0].ea<<9)|040; /*reg # and reg bit*/
|
|
493 }
|
|
494 else {
|
|
495 if(opnd[0].ea != IMM)
|
|
496 uerr(20);
|
|
497 goto opf8l1;
|
|
498 }
|
|
499 ins[0] =| f1mode[modelen] | opnd[1].ea; /*put in size and reg #*/
|
|
500 }
|
|
501
|
|
502 /* format 9 -- jmp, jsr */
|
|
503 /* format 14 -- stop */
|
|
504 /* format 24 -- clr, neg, negx, not */
|
|
505 /* format 25 -- s?? */
|
|
506 /* format 29 -- pea */
|
|
507 /* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
|
|
508 opf9()
|
|
509 {
|
|
510 getea(0);
|
|
511 if(format==24) { /*clr, not, etc*/
|
|
512 ins[0] =| f1mode[modelen]; /*add size bits*/
|
|
513 if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
|
|
514 uerr(20);
|
|
515 }
|
|
516 else if(format==25) { /*tas,scc, etc*/
|
|
517 if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
|
|
518 uerr(20);
|
|
519 }
|
|
520 else if(format==14) { /*stop*/
|
|
521 if(modelen!=2 || opnd[0].ea!=IMM)
|
|
522 uerr(20);
|
|
523 doea(&opnd[0]);
|
|
524 return;
|
|
525 }
|
|
526 else if(!controlea(&opnd[0])) /*jmp, jsr, etc*/
|
|
527 uerr(20);
|
|
528 ins[0] =| opnd[0].ea;
|
|
529 doea(&opnd[0]);
|
|
530 }
|
|
531
|
|
1File: PASS2.C Page 10
|
|
532 /* format 11 -- dbcc*/
|
|
533 /* format 19 -- link*/
|
|
534 opf11()
|
|
535 {
|
|
536 if(get2ops())
|
|
537 return;
|
|
538 if(format==19) { /*link*/
|
|
539 if(!ckareg(&opnd[0]))
|
|
540 uerr(33);
|
|
541 if(opnd[1].ea != IMM)
|
|
542 uerr(17);
|
|
543 }
|
|
544 else {
|
|
545 if(!ckdreg(&opnd[0]))
|
|
546 uerr(33);
|
|
547 if(opnd[1].drlc!=rlflg) /*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
|
|
548 uerr(22);
|
|
549 opnd[1].con =- (loctr+2L);
|
|
550 cksize(&opnd[1]);
|
|
551 opnd[1].drlc = ABS; /*not relocatable*/
|
|
552 }
|
|
553 ins[0] =| opnd[0].ea&7; /*put in reg #*/
|
|
554 dodisp(&opnd[1]);
|
|
555 }
|
|
556
|
|
557 /* format 12 -- exg*/
|
|
558 opf12()
|
|
559 {
|
|
560 register i;
|
|
561
|
|
562 if(get2ops())
|
|
563 return;
|
|
564 if(ckdreg(&opnd[0])) {
|
|
565 if(ckdreg(&opnd[1])) { /*exchange D regs*/
|
|
566 ins[0] =| 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
|
567 return;
|
|
568 }
|
|
569 if(ckareg(&opnd[1])) { /*ins[0] <- A and D flag*/
|
|
570 ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
|
571 return;
|
|
572 }
|
|
573 }
|
|
574 if(ckareg(&opnd[0])) {
|
|
575 if(ckareg(&opnd[1])) { /*both a regs*/
|
|
576 ins[0] =| 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
|
577 return;
|
|
578 }
|
|
579 if(ckdreg(&opnd[1])) { /*A and D regs*/
|
|
580 i = opnd[0].ea; /*exchg ea's*/
|
|
581 opnd[0].ea = opnd[1].ea;
|
|
582 opnd[1].ea = i;
|
|
583 ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
|
584 return;
|
|
585 }
|
|
586 }
|
|
587 uerr(20);
|
|
588 }
|
|
589
|
|
590 /* format 13 -- ext, unlk*/
|
|
1File: PASS2.C Page 11
|
|
591 /* format 18 -- trap*/
|
|
592 /* format 28 -- swap */
|
|
593 #define UNLK 047130
|
|
594
|
|
595 opf13()
|
|
596 {
|
|
597 getea(0);
|
|
598 if(format==18) { /*trap*/
|
|
599 if(opnd[0].con<0 || opnd[0].con>15)
|
|
600 uerr(15);
|
|
601 ins[0] =| opnd[0].con.wd2;
|
|
602 return;
|
|
603 }
|
|
604 if(ins[0]==UNLK) { /*unlk instr*/
|
|
605 if(!ckareg(&opnd[0]))
|
|
606 uerr(20);
|
|
607 }
|
|
608 else {
|
|
609 if(!ckdreg(&opnd[0]))
|
|
610 uerr(20);
|
|
611 if (format==13) /* ext */
|
|
612 ins[0] =| f13mode[modelen];
|
|
613 }
|
|
614 ins[0] =| opnd[0].ea&7;
|
|
615 }
|
|
616
|
|
617 /* format 15 -- adda, cmpa, suba*/
|
|
618 /* format 30 -- lea */
|
|
619 opf15()
|
|
620 {
|
|
621 register i;
|
|
622
|
|
623 if(get2ops())
|
|
624 return;
|
|
625 if(!ckareg(&opnd[1]))
|
|
626 uerr(33);
|
|
627 if(format==30) {
|
|
628 i = 0700;
|
|
629 if(!controlea(&opnd[0]))
|
|
630 uerr(20);
|
|
631 }
|
|
632 else
|
|
633 i = f15mode[modelen];
|
|
634 makef1(opnd[1].ea&7,i,&opnd[0]);
|
|
635 if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
|
|
636 }
|
|
637
|
|
638 /*formats 16 and 17 -- addq, inc, subq, dec*/
|
|
639 opf17()
|
|
640 {
|
|
641 if(format==16) { /*inc or dec*/
|
|
642 clrea(&opnd[0]);
|
|
643 opnd[0].ea = IMM;
|
|
644 opnd[0].con = 1L;
|
|
645 opnd[0].drlc = ABS;
|
|
646 getea(1);
|
|
647 }
|
|
648 else {
|
|
649 if(get2ops())
|
|
1File: PASS2.C Page 12
|
|
650 return;
|
|
651 }
|
|
652 if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
|
|
653 uerr(20);
|
|
654 if(opnd[0].con<=0 || opnd[0].con>8)
|
|
655 uerr(15);
|
|
656 if(modelen==1 && !dataea(&opnd[1]))
|
|
657 uerr(34);
|
|
658 ins[0] =| f1mode[modelen]|((opnd[0].con.wd2&7)<<9)|opnd[1].ea;
|
|
659 doea(&opnd[1]);
|
|
660 }
|
|
661
|
|
662 /* format 20 -- movem */
|
|
663 int regmsk0[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
|
664 0100,040,020,010,4,2,1};
|
|
665 int regmsk1[] {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
|
|
666 020000,040000,0100000};
|
|
667 opf20()
|
|
668 {
|
|
669 register dr;
|
|
670 register i,j;
|
|
671
|
|
672 dr = 0;
|
|
673 if(getreg() != -1 || pitw->itty == ITRM) { /*regs to memory*/
|
|
674 if (pitw->itty != ITRM) { /* [vlh] */
|
|
675 pitw--;
|
|
676 j = getrlist(regmsk0);
|
|
677 }
|
|
678 else {
|
|
679 j = pitw->itop;
|
|
680 pitw++;
|
|
681 }
|
|
682 if(!ckcomma())
|
|
683 uerr(10);
|
|
684 }
|
|
685 else
|
|
686 dr = 02000;
|
|
687 getea(0);
|
|
688 if(dr) {
|
|
689 if(!ckcomma())
|
|
690 uerr(10);
|
|
691 if (pitw->itty != ITRM) /* [vlh] */
|
|
692 j = getrlist(regmsk1); /*mem to regs*/
|
|
693 else {
|
|
694 j = pitw->itop;
|
|
695 j = fixmask(j);
|
|
696 pitw++;
|
|
697 }
|
|
698 }
|
|
699 else {
|
|
700 if(controlea(&opnd[0]))
|
|
701 j = fixmask(j);
|
|
702 }
|
|
703 i = opnd[0].ea&070;
|
|
704 if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
|
|
705 uerr(20);
|
|
706 if(modelen==4) /*long*/
|
|
707 ins[0] =| 0100;
|
|
708 ins[0] =| opnd[0].ea|dr;
|
|
1File: PASS2.C Page 13
|
|
709 *pins++ = j; /*reg mask*/
|
|
710 *prlb++ = DABS;
|
|
711 instrlen =+ 2;
|
|
712 doea(&opnd[0]);
|
|
713 if (!dr) { /* 1st argument (2nd is reg list) */
|
|
714 if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
|
|
715 uerr(20); /* xx(pc), xx(pc,dx), -(ax) */
|
|
716 }
|
|
717 else /* 2nd argument (1st is reg list) */
|
|
718 if ((opnd[0].ea&070)==DECIND)
|
|
719 uerr(20); /* (ax)+ */
|
|
720 }
|
|
721
|
|
722 /*
|
|
723 * get a list of registers for the movem instr
|
|
724 * call with:
|
|
725 * ptr to reg-to-mem or mem-to-reg array of bits
|
|
726 */
|
|
727 getrlist(ap)
|
|
728 int *ap;
|
|
729 {
|
|
730 register int *p,i,j;
|
|
731 register int mask;
|
|
732
|
|
733 p = ap;
|
|
734 mask = 0;
|
|
735 while((i=getreg()) != -1) {
|
|
736 if(ckitc(pitw,'-')) {
|
|
737 pitw++;
|
|
738 if((j=getreg()) == -1) {
|
|
739 uerr(40);
|
|
740 break;
|
|
741 }
|
|
742 while(i<=j)
|
|
743 mask =| p[i++];
|
|
744 }
|
|
745 else
|
|
746 mask =| p[i];
|
|
747 if(ckitc(pitw,'/'))
|
|
748 pitw++;
|
|
749 else
|
|
750 break;
|
|
751 }
|
|
752 if(!mask)
|
|
753 uerr(40);
|
|
754 return(mask);
|
|
755 }
|
|
756
|
|
757 /*reverse a movem register mask for control ea to memory*/
|
|
758 fixmask(msk)
|
|
759 {
|
|
760 register i,j,k;
|
|
761
|
|
762 k = (msk&1) ? 0100000 : 0;
|
|
763 i = 2;
|
|
764 j = 040000;
|
|
765 while(i) {
|
|
766 if(msk&i)
|
|
767 k =| j;
|
|
1File: PASS2.C Page 14
|
|
768 i =<< 1;
|
|
769 j =>> 1;
|
|
770 }
|
|
771 return(k);
|
|
772 }
|
|
773
|
|
774 /* format 21 -- movep*/
|
|
775 opf21()
|
|
776 {
|
|
777 register m,d;
|
|
778 register char *p;
|
|
779
|
|
780 if(get2ops())
|
|
781 return;
|
|
782 if(ckdreg(&opnd[0])) { /*d reg source*/
|
|
783 m = 0600;
|
|
784 d = opnd[0].ea;
|
|
785 p = &opnd[1];
|
|
786 }
|
|
787 else if(ckdreg(&opnd[1])) { /*d reg dest*/
|
|
788 m = 0400;
|
|
789 d = opnd[1].ea;
|
|
790 p = &opnd[0];
|
|
791 }
|
|
792 else {
|
|
793 uerr(20);
|
|
794 }
|
|
795 if((p->ea&070) != INDDISP)
|
|
796 uerr(20);
|
|
797 if(modelen == 4)
|
|
798 m =| 0100;
|
|
799 ins[0] =| (d<<9)|m|(p->ea&7);
|
|
800 *pins++ = p->con.wd2;
|
|
801 *prlb++ = p->drlc;
|
|
802 instrlen =+ 2;
|
|
803 }
|
|
804
|
|
805 /* format 22 -- moveq*/
|
|
806 opf22()
|
|
807 {
|
|
808 if(get2ops())
|
|
809 return;
|
|
810 if(opnd[0].ea != IMM)
|
|
811 uerr(17);
|
|
812 if(opnd[0].con>255L || opnd[0].con<-256L)
|
|
813 uerr(15);
|
|
814 if(!ckdreg(&opnd[1]))
|
|
815 uerr(33);
|
|
816 ins[0] =| (opnd[1].ea<<9) | (opnd[0].con.wd2&0377);
|
|
817 }
|
|
818
|
|
819 /* format 23 -- eor*/
|
|
820 opf23()
|
|
821 {
|
|
822 if(get2ops())
|
|
823 return;
|
|
824 if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
|
825 opcpt = eoriptr;
|
|
826 ins[0] = opcpt->vl1.wd2;
|
|
1File: PASS2.C Page 15
|
|
827 format = (opcpt->flags)&OPFF;
|
|
828 ccr_or_sr();
|
|
829 return;
|
|
830 }
|
|
831 if(!ckdreg(&opnd[0])) {
|
|
832 if(makeimm()) /*must be immediate*/
|
|
833 return;
|
|
834 uerr(20); /*or error*/
|
|
835 }
|
|
836 if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
|
837 uerr(20);
|
|
838 ins[0] =| (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
|
|
839 doea(&opnd[1]);
|
|
840 }
|
|
841
|